diff options
| author | Brian Waldon <brian.waldon@rackspace.com> | 2011-07-28 16:35:56 -0400 |
|---|---|---|
| committer | Brian Waldon <brian.waldon@rackspace.com> | 2011-07-28 16:35:56 -0400 |
| commit | 1b4d0f8f72ec443027f8f83bffec9e02a76ce32f (patch) | |
| tree | 62b1c3387ab0e1e1c4fe8cb3079c5e2693f0a411 | |
| parent | 0a7e19481849f451f04063d3d2fc45b8f3328119 (diff) | |
| parent | 3c58da1a739c34d82f744692f0f9447453f3ff0a (diff) | |
merging trunk
29 files changed, 343 insertions, 331 deletions
diff --git a/bin/nova-manage b/bin/nova-manage index b63bd326f..75d74903c 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -631,40 +631,75 @@ class NetworkCommands(object): """Class for managing networks.""" @args('--label', dest="label", metavar='<label>', - help='Label(ex: public)') - @args('--network', dest="fixed_range", metavar='<x.x.x.x/yy>', - help='Network') + help='Label for network (ex: public)') + @args('--fixed_range_v4', dest="fixed_range_v4", metavar='<x.x.x.x/yy>', + help='IPv4 subnet (ex: 10.0.0.0/8)') @args('--num_networks', dest="num_networks", metavar='<number>', - help='How many networks create') + help='Number of networks to create') @args('--network_size', dest="network_size", metavar='<number>', - help='How many hosts in network') + help='Number of IPs per network') @args('--vlan', dest="vlan_start", metavar='<vlan id>', help='vlan id') @args('--vpn', dest="vpn_start", help='vpn start') - @args('--fixed_range_v6', dest="fixed_range_v6", help='fixed ipv6 range') + @args('--fixed_range_v6', dest="fixed_range_v6", + help='IPv6 subnet (ex: fe80::/64') @args('--gateway_v6', dest="gateway_v6", help='ipv6 gateway') - @args('--flat_network_bridge', dest="flat_network_bridge", - metavar='<flat network bridge>', help='Flat_network_bridge') + @args('--bridge', dest="bridge", + metavar='<bridge>', + help='VIFs on this network are connected to this bridge') @args('--bridge_interface', dest="bridge_interface", - metavar='<bridge interface>', help='Bridge_interface') + metavar='<bridge interface>', + help='the bridge is connected to this interface') @args('--multi_host', dest="multi_host", metavar="<'T'|'F'>", help='Multi host') @args('--dns1', dest="dns1", metavar="<DNS Address>", help='First DNS') @args('--dns2', dest="dns2", metavar="<DNS Address>", help='Second DNS') - def create(self, label=None, fixed_range=None, num_networks=None, + def create(self, label=None, fixed_range_v4=None, num_networks=None, network_size=None, multi_host=None, vlan_start=None, vpn_start=None, fixed_range_v6=None, gateway_v6=None, - flat_network_bridge=None, bridge_interface=None, - dns1=None, dns2=None): + bridge=None, bridge_interface=None, dns1=None, dns2=None): """Creates fixed ips for host by range""" + + # check for certain required inputs if not label: - msg = _('a label (ex: public) is required to create networks.') - print msg - raise TypeError(msg) - if not fixed_range: - msg = _('Fixed range in the form of 10.0.0.0/8 is ' - 'required to create networks.') - print msg - raise TypeError(msg) + raise exception.NetworkNotCreated(req='--label') + if not fixed_range_v4: + raise exception.NetworkNotCreated(req='--fixed_range_v4') + + bridge = bridge or FLAGS.flat_network_bridge + if not bridge: + bridge_required = ['nova.network.manager.FlatManager', + 'nova.network.manager.FlatDHCPManager'] + if FLAGS.network_manager in bridge_required: + # TODO(tr3buchet) - swap print statement and following line for + # raise statement in diablo 4 + print _('--bridge parameter required or FLAG ' + 'flat_network_bridge must be set to create networks\n' + 'WARNING! ACHTUNG! Setting the bridge to br100 ' + 'automatically is deprecated and will be removed in ' + 'Diablo milestone 4. Prepare yourself accordingly.') + time.sleep(10) + bridge = 'br100' + #raise exception.NetworkNotCreated(req='--bridge') + + bridge_interface = bridge_interface or FLAGS.flat_interface or \ + FLAGS.vlan_interface + if not bridge_interface: + interface_required = ['nova.network.manager.FlatDHCPManager', + 'nova.network.manager.VlanManager'] + if FLAGS.network_manager in interface_required: + raise exception.NetworkNotCreated(req='--bridge_interface') + + if FLAGS.use_ipv6: + fixed_range_v6 = fixed_range_v6 or FLAGS.fixed_range_v6 + if not fixed_range_v6: + raise exception.NetworkNotCreated(req='with use_ipv6, ' + '--fixed_range_v6') + gateway_v6 = gateway_v6 or FLAGS.gateway_v6 + if not gateway_v6: + raise exception.NetworkNotCreated(req='with use_ipv6, ' + '--gateway_v6') + + # sanitize other input using FLAGS if necessary if not num_networks: num_networks = FLAGS.num_networks if not network_size: @@ -677,36 +712,25 @@ class NetworkCommands(object): vlan_start = FLAGS.vlan_start if not vpn_start: vpn_start = FLAGS.vpn_start - if not fixed_range_v6: - fixed_range_v6 = FLAGS.fixed_range_v6 - if not flat_network_bridge: - flat_network_bridge = FLAGS.flat_network_bridge - if not bridge_interface: - bridge_interface = FLAGS.flat_interface or FLAGS.vlan_interface - if not gateway_v6: - gateway_v6 = FLAGS.gateway_v6 if not dns1 and FLAGS.flat_network_dns: dns1 = FLAGS.flat_network_dns - net_manager = utils.import_object(FLAGS.network_manager) - try: - net_manager.create_networks(context.get_admin_context(), - label=label, - cidr=fixed_range, - multi_host=multi_host, - num_networks=int(num_networks), - network_size=int(network_size), - vlan_start=int(vlan_start), - vpn_start=int(vpn_start), - cidr_v6=fixed_range_v6, - gateway_v6=gateway_v6, - bridge=flat_network_bridge, - bridge_interface=bridge_interface, - dns1=dns1, - dns2=dns2) - except ValueError, e: - print e - raise e + # create the network + net_manager = utils.import_object(FLAGS.network_manager) + net_manager.create_networks(context.get_admin_context(), + label=label, + cidr=fixed_range_v4, + multi_host=multi_host, + num_networks=int(num_networks), + network_size=int(network_size), + vlan_start=int(vlan_start), + vpn_start=int(vpn_start), + cidr_v6=fixed_range_v6, + gateway_v6=gateway_v6, + bridge=bridge, + bridge_interface=bridge_interface, + dns1=dns1, + dns2=dns2) def list(self): """List all created networks""" diff --git a/nova/api/ec2/cloud.py b/nova/api/ec2/cloud.py index 10720a804..0294c09c5 100644 --- a/nova/api/ec2/cloud.py +++ b/nova/api/ec2/cloud.py @@ -539,15 +539,18 @@ class CloudController(object): return rules if 'ip_ranges' in kwargs: rules = self._cidr_args_split(kwargs) + else: + rules = [kwargs] finalset = [] for rule in rules: if 'groups' in rule: groups_values = self._groups_args_split(rule) for groups_value in groups_values: - finalset.append(groups_value) + final = self._rule_dict_last_step(context, **groups_value) + finalset.append(final) else: - if rule: - finalset.append(rule) + final = self._rule_dict_last_step(context, **rule) + finalset.append(final) return finalset def _cidr_args_split(self, kwargs): @@ -590,6 +593,9 @@ class CloudController(object): db.security_group_get_by_name(context.elevated(), source_project_id, source_security_group_name) + notfound = exception.SecurityGroupNotFound + if not source_security_group: + raise notfound(security_group_id=source_security_group_name) values['group_id'] = source_security_group['id'] elif cidr_ip: # If this fails, it throws an exception. This is what we want. @@ -628,7 +634,7 @@ class CloudController(object): for rule in security_group.rules: if 'group_id' in values: if rule['group_id'] == values['group_id']: - return True + return rule['id'] else: is_duplicate = True for key in ('cidr', 'from_port', 'to_port', 'protocol'): @@ -636,7 +642,7 @@ class CloudController(object): is_duplicate = False break if is_duplicate: - return True + return rule['id'] return False def revoke_security_group_ingress(self, context, group_name=None, @@ -659,22 +665,30 @@ class CloudController(object): msg = "Revoke security group ingress %s" LOG.audit(_(msg), security_group['name'], context=context) + prevalues = [] + try: + prevalues = kwargs['ip_permissions'] + except KeyError: + prevalues.append(kwargs) + rule_id = None + for values in prevalues: + rulesvalues = self._rule_args_to_dict(context, values) + if not rulesvalues: + err = "%s Not enough parameters to build a valid rule" + raise exception.ApiError(_(err % rulesvalues)) - criteria = self._rule_args_to_dict(context, kwargs)[0] - if criteria is None: - raise exception.ApiError(_("Not enough parameters to build a " - "valid rule.")) - - for rule in security_group.rules: - match = True - for (k, v) in criteria.iteritems(): - if getattr(rule, k, False) != v: - match = False - if match: - db.security_group_rule_destroy(context, rule['id']) - self.compute_api.trigger_security_group_rules_refresh(context, - security_group_id=security_group['id']) - return True + for values_for_rule in rulesvalues: + values_for_rule['parent_group_id'] = security_group.id + rule_id = self._security_group_rule_exists(security_group, + values_for_rule) + if rule_id: + db.security_group_rule_destroy(context, rule_id) + if rule_id: + # NOTE(vish): we removed a rule, so refresh + self.compute_api.trigger_security_group_rules_refresh( + context, + security_group_id=security_group['id']) + return True raise exception.ApiError(_("No rule for the specified parameters.")) # TODO(soren): This has only been tested with Boto as the client. @@ -721,15 +735,17 @@ class CloudController(object): postvalues.append(values_for_rule) for values_for_rule in postvalues: - security_group_rule = db.security_group_rule_create(context, - values_for_rule) + security_group_rule = db.security_group_rule_create( + context, + values_for_rule) - self.compute_api.trigger_security_group_rules_refresh(context, - security_group_id=security_group['id']) + if postvalues: + self.compute_api.trigger_security_group_rules_refresh( + context, + security_group_id=security_group['id']) + return True - group = db.security_group_get_by_name(context, context.project_id, - security_group['name']) - return True + raise exception.ApiError(_("No rule for the specified parameters.")) def _get_source_project_id(self, context, source_security_group_owner_id): if source_security_group_owner_id: diff --git a/nova/auth/dbdriver.py b/nova/auth/dbdriver.py index a429b7812..0158c4e23 100644 --- a/nova/auth/dbdriver.py +++ b/nova/auth/dbdriver.py @@ -127,7 +127,7 @@ class DbDriver(object): try: project = db.project_create(context.get_admin_context(), values) - except exception.Duplicate: + except (exception.Duplicate, exception.DBError): raise exception.ProjectExists(project=name) for member in members: diff --git a/nova/compute/manager.py b/nova/compute/manager.py index c79abd696..173469bc3 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -871,7 +871,7 @@ class ComputeManager(manager.SchedulerDependentManager): """ self.network_api.add_fixed_ip_to_instance(context, instance_id, - network_id) + self.host, network_id) self.inject_network_info(context, instance_id) self.reset_network(context, instance_id) diff --git a/nova/db/sqlalchemy/migrate_repo/versions/034_change_instance_id_in_migrations.py b/nova/db/sqlalchemy/migrate_repo/versions/034_change_instance_id_in_migrations.py index b002ba064..4e8eaf0fd 100644 --- a/nova/db/sqlalchemy/migrate_repo/versions/034_change_instance_id_in_migrations.py +++ b/nova/db/sqlalchemy/migrate_repo/versions/034_change_instance_id_in_migrations.py @@ -17,6 +17,7 @@ from sqlalchemy import Column, Integer, String, MetaData, Table + meta = MetaData() @@ -33,6 +34,14 @@ def upgrade(migrate_engine): meta.bind = migrate_engine migrations = Table('migrations', meta, autoload=True) migrations.create_column(instance_uuid) + + if migrate_engine.name == "mysql": + try: + migrate_engine.execute("ALTER TABLE migrations DROP FOREIGN KEY " \ + "`migrations_ibfk_1`;") + except Exception: # Don't care, just fail silently. + pass + migrations.c.instance_id.drop() diff --git a/nova/exception.py b/nova/exception.py index 38e705417..8c9b45a80 100644 --- a/nova/exception.py +++ b/nova/exception.py @@ -116,7 +116,8 @@ def wrap_exception(notifier=None, publisher_id=None, event_type=None, notifier.notify(publisher_id, temp_type, temp_level, payload) - if not isinstance(e, Error): + if (not isinstance(e, Error) and + not isinstance(e, NovaException)): #exc_type, exc_value, exc_traceback = sys.exc_info() LOG.exception(_('Uncaught exception')) #logging.error(traceback.extract_stack(exc_traceback)) @@ -372,6 +373,10 @@ class StorageRepositoryNotFound(NotFound): message = _("Cannot find SR to read/write VDI.") +class NetworkNotCreated(NovaException): + message = _("%(req)s is required to create a network.") + + class NetworkNotFound(NotFound): message = _("Network %(network_id)s could not be found.") diff --git a/nova/flags.py b/nova/flags.py index 49355b436..fa6d8860a 100644 --- a/nova/flags.py +++ b/nova/flags.py @@ -343,7 +343,7 @@ DEFINE_string('lock_path', os.path.join(os.path.dirname(__file__), '../'), 'Directory for lock files') DEFINE_string('logdir', None, 'output to a per-service log file in named ' 'directory') - +DEFINE_integer('logfile_mode', 0644, 'Default file mode of the logs.') DEFINE_string('sqlite_db', 'nova.sqlite', 'file name for sqlite') DEFINE_string('sql_connection', 'sqlite:///$state_path/$sqlite_db', diff --git a/nova/log.py b/nova/log.py index f8c0ba68d..133ee45f8 100644 --- a/nova/log.py +++ b/nova/log.py @@ -257,6 +257,7 @@ class NovaRootLogger(NovaLogger): self.filelog = WatchedFileHandler(logpath) self.addHandler(self.filelog) self.logpath = logpath + os.chmod(self.logpath, FLAGS.logfile_mode) else: self.removeHandler(self.filelog) self.addHandler(self.streamlog) diff --git a/nova/network/api.py b/nova/network/api.py index 33a9fe239..247768722 100644 --- a/nova/network/api.py +++ b/nova/network/api.py @@ -164,9 +164,10 @@ class API(base.Base): {'method': 'deallocate_for_instance', 'args': args}) - def add_fixed_ip_to_instance(self, context, instance_id, network_id): + def add_fixed_ip_to_instance(self, context, instance_id, host, network_id): """Adds a fixed ip to instance from specified network.""" args = {'instance_id': instance_id, + 'host': host, 'network_id': network_id} rpc.cast(context, FLAGS.network_topic, {'method': 'add_fixed_ip_to_instance', diff --git a/nova/network/manager.py b/nova/network/manager.py index 6f7573f66..4a3791d8a 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -68,7 +68,7 @@ LOG = logging.getLogger("nova.network.manager") FLAGS = flags.FLAGS -flags.DEFINE_string('flat_network_bridge', 'br100', +flags.DEFINE_string('flat_network_bridge', None, 'Bridge for simple network instances') flags.DEFINE_string('flat_network_dns', '8.8.4.4', 'Dns for simple network') @@ -614,12 +614,13 @@ class NetworkManager(manager.SchedulerDependentManager): bridge_interface, dns1=None, dns2=None, **kwargs): """Create networks based on parameters.""" fixed_net = netaddr.IPNetwork(cidr) - fixed_net_v6 = netaddr.IPNetwork(cidr_v6) - significant_bits_v6 = 64 - network_size_v6 = 1 << 64 + if FLAGS.use_ipv6: + fixed_net_v6 = netaddr.IPNetwork(cidr_v6) + significant_bits_v6 = 64 + network_size_v6 = 1 << 64 + for index in range(num_networks): start = index * network_size - start_v6 = index * network_size_v6 significant_bits = 32 - int(math.log(network_size, 2)) cidr = '%s/%s' % (fixed_net[start], significant_bits) project_net = netaddr.IPNetwork(cidr) @@ -640,6 +641,7 @@ class NetworkManager(manager.SchedulerDependentManager): net['label'] = label if FLAGS.use_ipv6: + start_v6 = index * network_size_v6 cidr_v6 = '%s/%s' % (fixed_net_v6[start_v6], significant_bits_v6) net['cidr_v6'] = cidr_v6 @@ -720,9 +722,9 @@ class FlatManager(NetworkManager): """Basic network where no vlans are used. FlatManager does not do any bridge or vlan creation. The user is - responsible for setting up whatever bridge is specified in - flat_network_bridge (br100 by default). This bridge needs to be created - on all compute hosts. + responsible for setting up whatever bridges are specified when creating + networks through nova-manage. This bridge needs to be created on all + compute hosts. The idea is to create a single network for the host with a command like: nova-manage network create 192.168.0.0/24 1 256. Creating multiple diff --git a/nova/tests/fake_flags.py b/nova/tests/fake_flags.py index 2297d2f0e..073216495 100644 --- a/nova/tests/fake_flags.py +++ b/nova/tests/fake_flags.py @@ -42,3 +42,4 @@ FLAGS['iscsi_num_targets'].SetDefault(8) FLAGS['verbose'].SetDefault(True) FLAGS['sqlite_db'].SetDefault("tests.sqlite") FLAGS['use_ipv6'].SetDefault(True) +FLAGS['flat_network_bridge'].SetDefault('br100') diff --git a/nova/tests/test_api.py b/nova/tests/test_api.py index 26ac5ff24..fe7fd8402 100644 --- a/nova/tests/test_api.py +++ b/nova/tests/test_api.py @@ -213,7 +213,11 @@ class ApiEc2TestCase(test.TestCase): self.http = FakeHttplibConnection( self.app, '%s:8773' % (self.host), False) # pylint: disable=E1103 - self.ec2.new_http_connection(host, is_secure).AndReturn(self.http) + if boto.Version >= '2': + self.ec2.new_http_connection(host or '%s:8773' % (self.host), + is_secure).AndReturn(self.http) + else: + self.ec2.new_http_connection(host, is_secure).AndReturn(self.http) return self.http def test_return_valid_isoformat(self): diff --git a/nova/tests/test_cloud.py b/nova/tests/test_cloud.py index 136082cc1..e419e7a50 100644 --- a/nova/tests/test_cloud.py +++ b/nova/tests/test_cloud.py @@ -121,7 +121,6 @@ class CloudTestCase(test.TestCase): public_ip=address) db.floating_ip_destroy(self.context, address) - @test.skip_test("Skipping this pending future merge") def test_allocate_address(self): address = "10.10.10.10" allocate = self.cloud.allocate_address @@ -161,13 +160,10 @@ class CloudTestCase(test.TestCase): # ApiError: Floating ip is in use. Disassociate it before releasing. self.assertRaises(exception.ApiError, release, self.context, address) - @test.skip_test("Skipping this pending future merge") def test_associate_disassociate_address(self): """Verifies associate runs cleanly without raising an exception""" address = "10.10.10.10" - db.floating_ip_create(self.context, - {'address': address, - 'host': self.network.host}) + db.floating_ip_create(self.context, {'address': address}) self.cloud.allocate_address(self.context) # TODO(jkoelker) Probably need to query for instance_type_id and # make sure we get a valid one @@ -175,11 +171,14 @@ class CloudTestCase(test.TestCase): 'instance_type_id': 1}) networks = db.network_get_all(self.context) for network in networks: - self.network.set_network_host(self.context, network['id']) + db.network_update(self.context, network['id'], + {'host': self.network.host}) project_id = self.context.project_id type_id = inst['instance_type_id'] ips = self.network.allocate_for_instance(self.context, instance_id=inst['id'], + host=inst['host'], + vpn=None, instance_type_id=type_id, project_id=project_id) # TODO(jkoelker) Make this mas bueno @@ -287,7 +286,7 @@ class CloudTestCase(test.TestCase): 'ip_protocol': u'tcp'}]} self.assertTrue(authz(self.context, group_name=sec['name'], **kwargs)) - def test_authorize_security_group_ingress_ip_permissions_groups(self): + def test_authorize_security_group_fail_missing_source_group(self): kwargs = {'project_id': self.context.project_id, 'name': 'test'} sec = db.security_group_create(self.context, kwargs) authz = self.cloud.authorize_security_group_ingress @@ -295,6 +294,23 @@ class CloudTestCase(test.TestCase): 'ip_ranges':{'1': {'cidr_ip': u'0.0.0.0/0'}, '2': {'cidr_ip': u'10.10.10.10/32'}}, 'groups': {'1': {'user_id': u'someuser', + 'group_name': u'somegroup1'}}, + 'ip_protocol': u'tcp'}]} + self.assertRaises(exception.SecurityGroupNotFound, authz, + self.context, group_name=sec['name'], **kwargs) + + def test_authorize_security_group_ingress_ip_permissions_groups(self): + kwargs = {'project_id': self.context.project_id, 'name': 'test'} + sec = db.security_group_create(self.context, + {'project_id': 'someuser', + 'name': 'somegroup1'}) + sec = db.security_group_create(self.context, + {'project_id': 'someuser', + 'name': 'othergroup2'}) + sec = db.security_group_create(self.context, kwargs) + authz = self.cloud.authorize_security_group_ingress + kwargs = {'ip_permissions': [{'to_port': 81, 'from_port': 81, + 'groups': {'1': {'user_id': u'someuser', 'group_name': u'somegroup1'}, '2': {'user_id': u'someuser', 'group_name': u'othergroup2'}}, @@ -405,8 +421,6 @@ class CloudTestCase(test.TestCase): db.service_destroy(self.context, service1['id']) db.service_destroy(self.context, service2['id']) - # NOTE(jkoelker): this test relies on fixed_ip being in instances - @test.skip_test("EC2 stuff needs fixed_ip in instance_ref") def test_describe_snapshots(self): """Makes sure describe_snapshots works and filters results.""" vol = db.volume_create(self.context, {}) @@ -1041,12 +1055,6 @@ class CloudTestCase(test.TestCase): self.cloud.delete_key_pair(self.context, 'test') def test_run_instances(self): - # stub out the rpc call - def stub_cast(*args, **kwargs): - pass - - self.stubs.Set(rpc, 'cast', stub_cast) - kwargs = {'image_id': FLAGS.default_image, 'instance_type': FLAGS.default_instance_type, 'max_count': 1} @@ -1056,7 +1064,7 @@ class CloudTestCase(test.TestCase): self.assertEqual(instance['imageId'], 'ami-00000001') self.assertEqual(instance['displayName'], 'Server 1') self.assertEqual(instance['instanceId'], 'i-00000001') - self.assertEqual(instance['instanceState']['name'], 'scheduling') + self.assertEqual(instance['instanceState']['name'], 'running') self.assertEqual(instance['instanceType'], 'm1.small') def test_run_instances_image_state_none(self): @@ -1128,16 +1136,15 @@ class CloudTestCase(test.TestCase): self.assertEqual('c00l 1m4g3', inst['display_name']) db.instance_destroy(self.context, inst['id']) - # NOTE(jkoelker): This test relies on mac_address in instance - @test.skip_test("EC2 stuff needs mac_address in instance_ref") def test_update_of_instance_wont_update_private_fields(self): inst = db.instance_create(self.context, {}) + host = inst['host'] ec2_id = ec2utils.id_to_ec2_id(inst['id']) self.cloud.update_instance(self.context, ec2_id, display_name='c00l 1m4g3', - mac_address='DE:AD:BE:EF') + host='otherhost') inst = db.instance_get(self.context, inst['id']) - self.assertEqual(None, inst['mac_address']) + self.assertEqual(host, inst['host']) db.instance_destroy(self.context, inst['id']) def test_update_of_volume_display_fields(self): @@ -1193,7 +1200,6 @@ class CloudTestCase(test.TestCase): elevated = self.context.elevated(read_deleted=True) self._wait_for_state(elevated, instance_id, is_deleted) - @test.skip_test("skipping, test is hanging with multinic for rpc reasons") def test_stop_start_instance(self): """Makes sure stop/start instance works""" # enforce periodic tasks run in short time to avoid wait for 60s. @@ -1251,7 +1257,6 @@ class CloudTestCase(test.TestCase): self.assertEqual(vol['status'], "available") self.assertEqual(vol['attach_status'], "detached") - @test.skip_test("skipping, test is hanging with multinic for rpc reasons") def test_stop_start_with_volume(self): """Make sure run instance with block device mapping works""" @@ -1320,7 +1325,6 @@ class CloudTestCase(test.TestCase): self._restart_compute_service() - @test.skip_test("skipping, test is hanging with multinic for rpc reasons") def test_stop_with_attached_volume(self): """Make sure attach info is reflected to block device mapping""" # enforce periodic tasks run in short time to avoid wait for 60s. @@ -1396,7 +1400,6 @@ class CloudTestCase(test.TestCase): greenthread.sleep(0.3) return result['snapshotId'] - @test.skip_test("skipping, test is hanging with multinic for rpc reasons") def test_run_with_snapshot(self): """Makes sure run/stop/start instance with snapshot works.""" vol = self._volume_create() diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 2a8f33dd3..0ede4f469 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -583,8 +583,9 @@ class ComputeTestCase(test.TestCase): the same host""" instance_id = self._create_instance() self.compute.run_instance(self.context, instance_id) + inst_ref = db.instance_get(self.context, instance_id) self.assertRaises(exception.Error, self.compute.prep_resize, - self.context, instance_id, 1) + self.context, inst_ref['uuid'], 1) self.compute.terminate_instance(self.context, instance_id) def test_migrate(self): diff --git a/nova/tests/test_libvirt.py b/nova/tests/test_libvirt.py index ad0931a89..bab4d200b 100644 --- a/nova/tests/test_libvirt.py +++ b/nova/tests/test_libvirt.py @@ -88,7 +88,7 @@ def _setup_networking(instance_id, ip='1.2.3.4'): 'virtual_interface_id': vif_ref['id']} db.fixed_ip_create(ctxt, fixed_ip) db.fixed_ip_update(ctxt, ip, {'allocated': True, - 'instance_id': instance_id}) + 'instance_id': instance_id}) class CacheConcurrencyTestCase(test.TestCase): @@ -177,13 +177,13 @@ class LibvirtConnTestCase(test.TestCase): self.context = context.get_admin_context() FLAGS.instances_path = '' self.call_libvirt_dependant_setup = False + self.test_ip = '10.11.12.13' def tearDown(self): self.manager.delete_project(self.project) self.manager.delete_user(self.user) super(LibvirtConnTestCase, self).tearDown() - test_ip = '10.11.12.13' test_instance = {'memory_kb': '1024000', 'basepath': '/some/path', 'bridge_name': 'br100', @@ -232,6 +232,16 @@ class LibvirtConnTestCase(test.TestCase): def setattr(self, key, val): self.__setattr__(key, val) + def plug(self, instance, network, mapping): + return { + 'id': 'fake', + 'bridge_name': 'fake', + 'mac_address': 'fake', + 'ip_address': 'fake', + 'dhcp_server': 'fake', + 'extra_params': 'fake' + } + # Creating mocks fake = FakeLibvirtConnection() fakeip = FakeIptablesFirewallDriver @@ -280,7 +290,6 @@ class LibvirtConnTestCase(test.TestCase): return db.service_create(context.get_admin_context(), service_ref) - @test.skip_test("Please review this test to ensure intent") def test_preparing_xml_info(self): conn = connection.LibvirtConnection(True) instance_ref = db.instance_create(self.context, self.test_instance) @@ -296,27 +305,23 @@ class LibvirtConnTestCase(test.TestCase): _create_network_info(2)) self.assertTrue(len(result['nics']) == 2) - @test.skip_test("skipping libvirt tests depends on get_network_info shim") def test_xml_and_uri_no_ramdisk_no_kernel(self): instance_data = dict(self.test_instance) self._check_xml_and_uri(instance_data, expect_kernel=False, expect_ramdisk=False) - @test.skip_test("skipping libvirt tests depends on get_network_info shim") def test_xml_and_uri_no_ramdisk(self): instance_data = dict(self.test_instance) instance_data['kernel_id'] = 'aki-deadbeef' self._check_xml_and_uri(instance_data, expect_kernel=True, expect_ramdisk=False) - @test.skip_test("skipping libvirt tests depends on get_network_info shim") def test_xml_and_uri_no_kernel(self): instance_data = dict(self.test_instance) instance_data['ramdisk_id'] = 'ari-deadbeef' self._check_xml_and_uri(instance_data, expect_kernel=False, expect_ramdisk=False) - @test.skip_test("skipping libvirt tests depends on get_network_info shim") def test_xml_and_uri(self): instance_data = dict(self.test_instance) instance_data['ramdisk_id'] = 'ari-deadbeef' @@ -324,7 +329,6 @@ class LibvirtConnTestCase(test.TestCase): self._check_xml_and_uri(instance_data, expect_kernel=True, expect_ramdisk=True) - @test.skip_test("skipping libvirt tests depends on get_network_info shim") def test_xml_and_uri_rescue(self): instance_data = dict(self.test_instance) instance_data['ramdisk_id'] = 'ari-deadbeef' @@ -332,7 +336,6 @@ class LibvirtConnTestCase(test.TestCase): self._check_xml_and_uri(instance_data, expect_kernel=True, expect_ramdisk=True, rescue=True) - @test.skip_test("skipping libvirt tests depends on get_network_info shim") def test_lxc_container_and_uri(self): instance_data = dict(self.test_instance) self._check_xml_and_container(instance_data) @@ -412,6 +415,15 @@ class LibvirtConnTestCase(test.TestCase): self.assertEquals(snapshot['status'], 'active') self.assertEquals(snapshot['name'], snapshot_name) + def test_attach_invalid_device(self): + self.create_fake_libvirt_mock() + connection.LibvirtConnection._conn.lookupByName = self.fake_lookup + self.mox.ReplayAll() + conn = connection.LibvirtConnection(False) + self.assertRaises(exception.InvalidDevicePath, + conn.attach_volume, + "fake", "bad/device/path", "/dev/fake") + def test_multi_nic(self): instance_data = dict(self.test_instance) network_info = _create_network_info(2) @@ -432,24 +444,7 @@ class LibvirtConnTestCase(test.TestCase): user_context = context.RequestContext(project=self.project, user=self.user) instance_ref = db.instance_create(user_context, instance) - # Re-get the instance so it's bound to an actual session - instance_ref = db.instance_get(user_context, instance_ref['id']) - network_ref = db.project_get_networks(context.get_admin_context(), - self.project.id)[0] - - vif = {'address': '56:12:12:12:12:12', - 'network_id': network_ref['id'], - 'instance_id': instance_ref['id']} - vif_ref = db.virtual_interface_create(self.context, vif) - fixed_ip = {'address': self.test_ip, - 'network_id': network_ref['id'], - 'virtual_interface_id': vif_ref['id']} - - ctxt = context.get_admin_context() - fixed_ip_ref = db.fixed_ip_create(ctxt, fixed_ip) - db.fixed_ip_update(ctxt, self.test_ip, - {'allocated': True, - 'instance_id': instance_ref['id']}) + _setup_networking(instance_ref['id'], self.test_ip) self.flags(libvirt_type='lxc') conn = connection.LibvirtConnection(True) @@ -481,7 +476,7 @@ class LibvirtConnTestCase(test.TestCase): network_ref = db.project_get_networks(context.get_admin_context(), self.project.id)[0] - _setup_networking(instance_ref['id'], ip=self.test_ip) + _setup_networking(instance_ref['id'], self.test_ip) type_uri_map = {'qemu': ('qemu:///system', [(lambda t: t.find('.').get('type'), 'qemu'), @@ -743,7 +738,6 @@ class LibvirtConnTestCase(test.TestCase): db.volume_destroy(self.context, volume_ref['id']) db.instance_destroy(self.context, instance_ref['id']) - @test.skip_test("test needs rewrite: instance no longer has mac_address") def test_spawn_with_network_info(self): # Skip if non-libvirt environment if not self.lazy_load_library_exists(): @@ -762,17 +756,7 @@ class LibvirtConnTestCase(test.TestCase): conn.firewall_driver.setattr('setup_basic_filtering', fake_none) conn.firewall_driver.setattr('prepare_instance_filter', fake_none) - network = db.project_get_networks(context.get_admin_context(), - self.project.id)[0] - ip_dict = {'ip': self.test_ip, - 'netmask': network['netmask'], - 'enabled': '1'} - mapping = {'label': network['label'], - 'gateway': network['gateway'], - 'mac': instance['mac_address'], - 'dns': [network['dns']], - 'ips': [ip_dict]} - network_info = [(network, mapping)] + network_info = _create_network_info() try: conn.spawn(instance, network_info) @@ -830,6 +814,7 @@ class IptablesFirewallTestCase(test.TestCase): """setup_basic_rules in nwfilter calls this.""" pass self.fake_libvirt_connection = FakeLibvirtConnection() + self.test_ip = '10.11.12.13' self.fw = firewall.IptablesFirewallDriver( get_connection=lambda: self.fake_libvirt_connection) @@ -895,27 +880,11 @@ class IptablesFirewallTestCase(test.TestCase): 'project_id': 'fake', 'instance_type_id': 1}) - @test.skip_test("skipping libvirt tests depends on get_network_info shim") def test_static_filters(self): instance_ref = self._create_instance_ref() - ip = '10.11.12.13' - - network_ref = db.project_get_networks(self.context, - 'fake', - associate=True)[0] - vif = {'address': '56:12:12:12:12:12', - 'network_id': network_ref['id'], - 'instance_id': instance_ref['id']} - vif_ref = db.virtual_interface_create(self.context, vif) - - fixed_ip = {'address': ip, - 'network_id': network_ref['id'], - 'virtual_interface_id': vif_ref['id']} - admin_ctxt = context.get_admin_context() - db.fixed_ip_create(admin_ctxt, fixed_ip) - db.fixed_ip_update(admin_ctxt, ip, {'allocated': True, - 'instance_id': instance_ref['id']}) + _setup_networking(instance_ref['id'], self.test_ip) + admin_ctxt = context.get_admin_context() secgroup = db.security_group_create(admin_ctxt, {'user_id': 'fake', 'project_id': 'fake', @@ -1047,7 +1016,6 @@ class IptablesFirewallTestCase(test.TestCase): self.assertEquals(ipv6_network_rules, ipv6_rules_per_network * networks_count) - @test.skip_test("skipping libvirt tests") def test_do_refresh_security_group_rules(self): instance_ref = self._create_instance_ref() self.mox.StubOutWithMock(self.fw, @@ -1058,7 +1026,6 @@ class IptablesFirewallTestCase(test.TestCase): self.mox.ReplayAll() self.fw.do_refresh_security_group_rules("fake") - @test.skip_test("skip libvirt test project_get_network no longer exists") def test_unfilter_instance_undefines_nwfilter(self): # Skip if non-libvirt environment if not self.lazy_load_library_exists(): @@ -1072,38 +1039,24 @@ class IptablesFirewallTestCase(test.TestCase): self.fw.nwfilter._conn.nwfilterLookupByName =\ fakefilter.nwfilterLookupByName instance_ref = self._create_instance_ref() - inst_id = instance_ref['id'] - instance = db.instance_get(self.context, inst_id) - ip = '10.11.12.13' - network_ref = db.project_get_network(self.context, 'fake') - fixed_ip = {'address': ip, 'network_id': network_ref['id']} - db.fixed_ip_create(admin_ctxt, fixed_ip) - db.fixed_ip_update(admin_ctxt, ip, {'allocated': True, - 'instance_id': inst_id}) - self.fw.setup_basic_filtering(instance) - self.fw.prepare_instance_filter(instance) - self.fw.apply_instance_filter(instance) + _setup_networking(instance_ref['id'], self.test_ip) + self.fw.setup_basic_filtering(instance_ref) + self.fw.prepare_instance_filter(instance_ref) + self.fw.apply_instance_filter(instance_ref) original_filter_count = len(fakefilter.filters) - self.fw.unfilter_instance(instance) + self.fw.unfilter_instance(instance_ref) # should undefine just the instance filter self.assertEqual(original_filter_count - len(fakefilter.filters), 1) db.instance_destroy(admin_ctxt, instance_ref['id']) - @test.skip_test("skip libvirt test project_get_network no longer exists") def test_provider_firewall_rules(self): # setup basic instance data instance_ref = self._create_instance_ref() nw_info = _create_network_info(1) - ip = '10.11.12.13' - network_ref = db.project_get_network(self.context, 'fake') - admin_ctxt = context.get_admin_context() - fixed_ip = {'address': ip, 'network_id': network_ref['id']} - db.fixed_ip_create(admin_ctxt, fixed_ip) - db.fixed_ip_update(admin_ctxt, ip, {'allocated': True, - 'instance_id': instance_ref['id']}) + _setup_networking(instance_ref['id'], self.test_ip) # FRAGILE: peeks at how the firewall names chains chain_name = 'inst-%s' % instance_ref['id'] @@ -1115,6 +1068,7 @@ class IptablesFirewallTestCase(test.TestCase): if rule.chain == 'provider'] self.assertEqual(0, len(rules)) + admin_ctxt = context.get_admin_context() # add a rule and send the update message, check for 1 rule provider_fw0 = db.provider_fw_rule_create(admin_ctxt, {'protocol': 'tcp', @@ -1173,6 +1127,7 @@ class NWFilterTestCase(test.TestCase): self.fake_libvirt_connection = Mock() + self.test_ip = '10.11.12.13' self.fw = firewall.NWFilterFirewall( lambda: self.fake_libvirt_connection) @@ -1259,7 +1214,6 @@ class NWFilterTestCase(test.TestCase): inst.update(params) return db.instance_type_create(context, inst)['id'] - @test.skip_test('Skipping this test') def test_creates_base_rule_first(self): # These come pre-defined by libvirt self.defined_filters = ['no-mac-spoofing', @@ -1291,21 +1245,11 @@ class NWFilterTestCase(test.TestCase): instance_ref = self._create_instance() inst_id = instance_ref['id'] - ip = '10.11.12.13' - - #network_ref = db.project_get_networks(self.context, 'fake')[0] - #fixed_ip = {'address': ip, 'network_id': network_ref['id']} - - #admin_ctxt = context.get_admin_context() - #db.fixed_ip_create(admin_ctxt, fixed_ip) - #db.fixed_ip_update(admin_ctxt, ip, {'allocated': True, - # 'instance_id': inst_id}) - - self._setup_networking(instance_ref['id'], ip=ip) + _setup_networking(instance_ref['id'], self.test_ip) def _ensure_all_called(): instance_filter = 'nova-instance-%s-%s' % (instance_ref['name'], - '00A0C914C829') + '561212121212') secgroup_filter = 'nova-secgroup-%s' % self.security_group['id'] for required in [secgroup_filter, 'allow-dhcp-server', 'no-arp-spoofing', 'no-ip-spoofing', @@ -1326,7 +1270,7 @@ class NWFilterTestCase(test.TestCase): self.fw.apply_instance_filter(instance) _ensure_all_called() self.teardown_security_group() - db.instance_destroy(admin_ctxt, instance_ref['id']) + db.instance_destroy(context.get_admin_context(), instance_ref['id']) def test_create_network_filters(self): instance_ref = self._create_instance() @@ -1336,7 +1280,6 @@ class NWFilterTestCase(test.TestCase): "fake") self.assertEquals(len(result), 3) - @test.skip_test("skip libvirt test project_get_network no longer exists") def test_unfilter_instance_undefines_nwfilters(self): admin_ctxt = context.get_admin_context() @@ -1354,12 +1297,7 @@ class NWFilterTestCase(test.TestCase): instance = db.instance_get(self.context, inst_id) - ip = '10.11.12.13' - network_ref = db.project_get_network(self.context, 'fake') - fixed_ip = {'address': ip, 'network_id': network_ref['id']} - db.fixed_ip_create(admin_ctxt, fixed_ip) - db.fixed_ip_update(admin_ctxt, ip, {'allocated': True, - 'instance_id': inst_id}) + _setup_networking(instance_ref['id'], self.test_ip) self.fw.setup_basic_filtering(instance) self.fw.prepare_instance_filter(instance) self.fw.apply_instance_filter(instance) diff --git a/nova/tests/test_quota.py b/nova/tests/test_quota.py index 69d2deafe..a35caadf8 100644 --- a/nova/tests/test_quota.py +++ b/nova/tests/test_quota.py @@ -269,11 +269,10 @@ class QuotaTestCase(test.TestCase): for volume_id in volume_ids: db.volume_destroy(self.context, volume_id) - @test.skip_test def test_too_many_addresses(self): address = '192.168.0.100' db.floating_ip_create(context.get_admin_context(), - {'address': address, 'host': FLAGS.host, + {'address': address, 'project_id': self.project.id}) self.assertRaises(quota.QuotaError, self.network.allocate_floating_ip, diff --git a/nova/tests/test_vmwareapi.py b/nova/tests/test_vmwareapi.py index cbf7801cf..7313508a6 100644 --- a/nova/tests/test_vmwareapi.py +++ b/nova/tests/test_vmwareapi.py @@ -19,9 +19,6 @@ Test suite for VMWareAPI. """ -import stubout - -from nova import context from nova import db from nova import flags from nova import test @@ -41,51 +38,66 @@ FLAGS = flags.FLAGS class VMWareAPIVMTestCase(test.TestCase): """Unit tests for Vmware API connection calls.""" - # NOTE(jkoelker): This is leaking stubs into the db module. - # Commenting out until updated for multi-nic. - #def setUp(self): - # super(VMWareAPIVMTestCase, self).setUp() - # self.flags(vmwareapi_host_ip='test_url', - # vmwareapi_host_username='test_username', - # vmwareapi_host_password='test_pass') - # self.manager = manager.AuthManager() - # self.user = self.manager.create_user('fake', 'fake', 'fake', - # admin=True) - # self.project = self.manager.create_project('fake', 'fake', 'fake') - # self.network = utils.import_object(FLAGS.network_manager) - # self.stubs = stubout.StubOutForTesting() - # vmwareapi_fake.reset() - # db_fakes.stub_out_db_instance_api(self.stubs) - # stubs.set_stubs(self.stubs) - # glance_stubs.stubout_glance_client(self.stubs, - # glance_stubs.FakeGlance) - # self.conn = vmwareapi_conn.get_connection(False) - - #def tearDown(self): - # super(VMWareAPIVMTestCase, self).tearDown() - # vmwareapi_fake.cleanup() - # self.manager.delete_project(self.project) - # self.manager.delete_user(self.user) - # self.stubs.UnsetAll() + def setUp(self): + super(VMWareAPIVMTestCase, self).setUp() + self.flags(vmwareapi_host_ip='test_url', + vmwareapi_host_username='test_username', + vmwareapi_host_password='test_pass') + self.manager = manager.AuthManager() + self.user = self.manager.create_user('fake', 'fake', 'fake', + admin=True) + self.project = self.manager.create_project('fake', 'fake', 'fake') + self.network = utils.import_object(FLAGS.network_manager) + vmwareapi_fake.reset() + db_fakes.stub_out_db_instance_api(self.stubs) + stubs.set_stubs(self.stubs) + glance_stubs.stubout_glance_client(self.stubs) + self.conn = vmwareapi_conn.get_connection(False) + # NOTE(vish): none of the network plugging code is actually + # being tested + self.network_info = [({'bridge': 'fa0', + 'id': 0, + 'vlan': None, + 'bridge_interface': None, + 'injected': True}, + {'broadcast': '192.168.0.255', + 'dns': ['192.168.0.1'], + 'gateway': '192.168.0.1', + 'gateway6': 'dead:beef::1', + 'ip6s': [{'enabled': '1', + 'ip': 'dead:beef::dcad:beff:feef:0', + 'netmask': '64'}], + 'ips': [{'enabled': '1', + 'ip': '192.168.0.100', + 'netmask': '255.255.255.0'}], + 'label': 'fake', + 'mac': 'DE:AD:BE:EF:00:00', + 'rxtx_cap': 3})] + + def tearDown(self): + super(VMWareAPIVMTestCase, self).tearDown() + vmwareapi_fake.cleanup() + self.manager.delete_project(self.project) + self.manager.delete_user(self.user) def _create_instance_in_the_db(self): values = {'name': 1, 'id': 1, 'project_id': self.project.id, 'user_id': self.user.id, - 'image_id': "1", + 'image_ref': "1", 'kernel_id': "1", 'ramdisk_id': "1", + 'mac_address': "de:ad:be:ef:be:ef", 'instance_type': 'm1.large', - 'mac_address': 'aa:bb:cc:dd:ee:ff', } - self.instance = db.instance_create(values) + self.instance = db.instance_create(None, values) def _create_vm(self): """Create and spawn the VM.""" self._create_instance_in_the_db() self.type_data = db.instance_type_get_by_name(None, 'm1.large') - self.conn.spawn(self.instance) + self.conn.spawn(self.instance, self.network_info) self._check_vm_record() def _check_vm_record(self): @@ -129,24 +141,20 @@ class VMWareAPIVMTestCase(test.TestCase): self.assertEquals(info["mem"], mem_kib) self.assertEquals(info["num_cpu"], self.type_data['vcpus']) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_list_instances(self): instances = self.conn.list_instances() self.assertEquals(len(instances), 0) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_list_instances_1(self): self._create_vm() instances = self.conn.list_instances() self.assertEquals(len(instances), 1) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_spawn(self): self._create_vm() info = self.conn.get_info(1) self._check_vm_info(info, power_state.RUNNING) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_snapshot(self): self._create_vm() info = self.conn.get_info(1) @@ -155,27 +163,23 @@ class VMWareAPIVMTestCase(test.TestCase): info = self.conn.get_info(1) self._check_vm_info(info, power_state.RUNNING) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_snapshot_non_existent(self): self._create_instance_in_the_db() self.assertRaises(Exception, self.conn.snapshot, self.instance, "Test-Snapshot") - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_reboot(self): self._create_vm() info = self.conn.get_info(1) self._check_vm_info(info, power_state.RUNNING) - self.conn.reboot(self.instance) + self.conn.reboot(self.instance, self.network_info) info = self.conn.get_info(1) self._check_vm_info(info, power_state.RUNNING) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_reboot_non_existent(self): self._create_instance_in_the_db() self.assertRaises(Exception, self.conn.reboot, self.instance) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_reboot_not_poweredon(self): self._create_vm() info = self.conn.get_info(1) @@ -185,7 +189,6 @@ class VMWareAPIVMTestCase(test.TestCase): self._check_vm_info(info, power_state.PAUSED) self.assertRaises(Exception, self.conn.reboot, self.instance) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_suspend(self): self._create_vm() info = self.conn.get_info(1) @@ -194,13 +197,11 @@ class VMWareAPIVMTestCase(test.TestCase): info = self.conn.get_info(1) self._check_vm_info(info, power_state.PAUSED) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_suspend_non_existent(self): self._create_instance_in_the_db() self.assertRaises(Exception, self.conn.suspend, self.instance, self.dummy_callback_handler) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_resume(self): self._create_vm() info = self.conn.get_info(1) @@ -212,13 +213,11 @@ class VMWareAPIVMTestCase(test.TestCase): info = self.conn.get_info(1) self._check_vm_info(info, power_state.RUNNING) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_resume_non_existent(self): self._create_instance_in_the_db() self.assertRaises(Exception, self.conn.resume, self.instance, self.dummy_callback_handler) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_resume_not_suspended(self): self._create_vm() info = self.conn.get_info(1) @@ -226,49 +225,41 @@ class VMWareAPIVMTestCase(test.TestCase): self.assertRaises(Exception, self.conn.resume, self.instance, self.dummy_callback_handler) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_get_info(self): self._create_vm() info = self.conn.get_info(1) self._check_vm_info(info, power_state.RUNNING) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_destroy(self): self._create_vm() info = self.conn.get_info(1) self._check_vm_info(info, power_state.RUNNING) instances = self.conn.list_instances() self.assertEquals(len(instances), 1) - self.conn.destroy(self.instance) + self.conn.destroy(self.instance, self.network_info) instances = self.conn.list_instances() self.assertEquals(len(instances), 0) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_destroy_non_existent(self): self._create_instance_in_the_db() - self.assertEquals(self.conn.destroy(self.instance), None) + self.assertEquals(self.conn.destroy(self.instance, self.network_info), + None) - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_pause(self): pass - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_unpause(self): pass - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_diagnostics(self): pass - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_get_console_output(self): pass - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def test_get_ajax_console(self): pass - @test.skip_test("DB stubbing not removed, needs updating for multi-nic") def dummy_callback_handler(self, ret): """ Dummy callback function to be passed to suspend, resume, etc., calls. diff --git a/nova/tests/test_xenapi.py b/nova/tests/test_xenapi.py index 199a8bc52..8b3b5fa28 100644 --- a/nova/tests/test_xenapi.py +++ b/nova/tests/test_xenapi.py @@ -396,18 +396,22 @@ class XenAPIVMTestCase(test.TestCase): def _test_spawn(self, image_ref, kernel_id, ramdisk_id, instance_type_id="3", os_type="linux", architecture="x86-64", instance_id=1, - check_injection=False): + check_injection=False, + create_record=True): stubs.stubout_loopingcall_start(self.stubs) - values = {'id': instance_id, - 'project_id': self.project.id, - 'user_id': self.user.id, - 'image_ref': image_ref, - 'kernel_id': kernel_id, - 'ramdisk_id': ramdisk_id, - 'instance_type_id': instance_type_id, - 'os_type': os_type, - 'architecture': architecture} - instance = db.instance_create(self.context, values) + if create_record: + values = {'id': instance_id, + 'project_id': self.project.id, + 'user_id': self.user.id, + 'image_ref': image_ref, + 'kernel_id': kernel_id, + 'ramdisk_id': ramdisk_id, + 'instance_type_id': instance_type_id, + 'os_type': os_type, + 'architecture': architecture} + instance = db.instance_create(self.context, values) + else: + instance = db.instance_get(self.context, instance_id) network_info = [({'bridge': 'fa0', 'id': 0, 'injected': True}, {'broadcast': '192.168.0.255', 'dns': ['192.168.0.1'], @@ -599,41 +603,38 @@ class XenAPIVMTestCase(test.TestCase): # guest agent is detected self.assertFalse(self._tee_executed) - @test.skip_test("Never gets an address, not sure why") def test_spawn_vlanmanager(self): self.flags(xenapi_image_service='glance', network_manager='nova.network.manager.VlanManager', - network_driver='nova.network.xenapi_net', vlan_interface='fake0') def dummy(*args, **kwargs): pass - self.stubs.Set(VMOps, 'create_vifs', dummy) + self.stubs.Set(vmops.VMOps, 'create_vifs', dummy) # Reset network table xenapi_fake.reset_table('network') # Instance id = 2 will use vlan network (see db/fakes.py) ctxt = self.context.elevated() - instance_ref = self._create_instance(2) - network_bk = self.network - # Ensure we use xenapi_net driver - self.network = utils.import_object(FLAGS.network_manager) + instance = self._create_instance(2, False) networks = self.network.db.network_get_all(ctxt) for network in networks: - self.network.set_network_host(ctxt, network['id']) - - self.network.allocate_for_instance(ctxt, instance_id=instance_ref.id, - instance_type_id=1, project_id=self.project.id) - self.network.setup_compute_network(ctxt, instance_ref.id) + self.network.set_network_host(ctxt, network) + + self.network.allocate_for_instance(ctxt, + instance_id=2, + host=FLAGS.host, + vpn=None, + instance_type_id=1, + project_id=self.project.id) self._test_spawn(glance_stubs.FakeGlance.IMAGE_MACHINE, glance_stubs.FakeGlance.IMAGE_KERNEL, glance_stubs.FakeGlance.IMAGE_RAMDISK, - instance_id=instance_ref.id, + instance_id=2, create_record=False) # TODO(salvatore-orlando): a complete test here would require # a check for making sure the bridge for the VM's VIF is # consistent with bridge specified in nova db - self.network = network_bk def test_spawn_with_network_qos(self): self._create_instance() @@ -644,7 +645,7 @@ class XenAPIVMTestCase(test.TestCase): str(3 * 1024)) def test_rescue(self): - self.flags(xenapi_inject_image=False) + self.flags(flat_injected=False) instance = self._create_instance() conn = xenapi_conn.get_connection(False) conn.rescue(instance, None, []) @@ -663,7 +664,7 @@ class XenAPIVMTestCase(test.TestCase): self.vm = None self.stubs.UnsetAll() - def _create_instance(self, instance_id=1): + def _create_instance(self, instance_id=1, spawn=True): """Creates and spawns a test instance.""" stubs.stubout_loopingcall_start(self.stubs) values = { @@ -691,7 +692,8 @@ class XenAPIVMTestCase(test.TestCase): 'label': 'fake', 'mac': 'DE:AD:BE:EF:00:00', 'rxtx_cap': 3})] - self.conn.spawn(instance, network_info) + if spawn: + self.conn.spawn(instance, network_info) return instance diff --git a/nova/tests/vmwareapi/db_fakes.py b/nova/tests/vmwareapi/db_fakes.py index d4eb87daf..afd672c7a 100644 --- a/nova/tests/vmwareapi/db_fakes.py +++ b/nova/tests/vmwareapi/db_fakes.py @@ -70,8 +70,8 @@ def stub_out_db_instance_api(stubs): 'launch_time': time.strftime('%Y-%m-%dT%H:%M:%SZ', time.gmtime()),
'instance_type': values['instance_type'],
'memory_mb': type_data['memory_mb'],
- 'mac_address': values['mac_address'],
'vcpus': type_data['vcpus'],
+ 'mac_addresses': [{'address': values['mac_address']}],
'local_gb': type_data['local_gb'],
}
return FakeModel(base_options)
@@ -83,6 +83,8 @@ def stub_out_db_instance_api(stubs): 'bridge': 'vmnet0',
'netmask': '255.255.255.0',
'gateway': '10.10.10.1',
+ 'broadcast': '10.10.10.255',
+ 'dns1': 'fake',
'vlan': 100}
return FakeModel(fields)
@@ -90,7 +92,7 @@ def stub_out_db_instance_api(stubs): """Stubs out the db.instance_action_create method."""
pass
- def fake_instance_get_fixed_address(context, instance_id):
+ def fake_instance_get_fixed_addresses(context, instance_id):
"""Stubs out the db.instance_get_fixed_address method."""
return '10.10.10.10'
@@ -103,7 +105,7 @@ def stub_out_db_instance_api(stubs): stubs.Set(db, 'instance_create', fake_instance_create)
stubs.Set(db, 'network_get_by_instance', fake_network_get_by_instance)
stubs.Set(db, 'instance_action_create', fake_instance_action_create)
- stubs.Set(db, 'instance_get_fixed_address',
- fake_instance_get_fixed_address)
+ stubs.Set(db, 'instance_get_fixed_addresses',
+ fake_instance_get_fixed_addresses)
stubs.Set(db, 'instance_type_get_all', fake_instance_type_get_all)
stubs.Set(db, 'instance_type_get_by_name', fake_instance_type_get_by_name)
diff --git a/nova/tests/vmwareapi/stubs.py b/nova/tests/vmwareapi/stubs.py index a648efb16..0ed5e9b68 100644 --- a/nova/tests/vmwareapi/stubs.py +++ b/nova/tests/vmwareapi/stubs.py @@ -22,6 +22,8 @@ Stubouts for the test suite from nova.virt import vmwareapi_conn
from nova.virt.vmwareapi import fake
from nova.virt.vmwareapi import vmware_images
+from nova.virt.vmwareapi import vmops
+from nova.virt.vmwareapi import network_utils
def fake_get_vim_object(arg):
@@ -36,11 +38,16 @@ def fake_is_vim_object(arg, module): def set_stubs(stubs):
"""Set the stubs."""
+ stubs.Set(vmops.VMWareVMOps, 'plug_vifs', fake.fake_plug_vifs)
+ stubs.Set(network_utils, 'get_network_with_the_name',
+ fake.fake_get_network)
stubs.Set(vmware_images, 'fetch_image', fake.fake_fetch_image)
stubs.Set(vmware_images, 'get_vmdk_size_and_properties',
fake.fake_get_vmdk_size_and_properties)
stubs.Set(vmware_images, 'upload_image', fake.fake_upload_image)
stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object",
fake_get_vim_object)
+ stubs.Set(vmwareapi_conn.VMWareAPISession, "_get_vim_object",
+ fake_get_vim_object)
stubs.Set(vmwareapi_conn.VMWareAPISession, "_is_vim_object",
fake_is_vim_object)
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py index 96f9c41f9..c27e92feb 100644 --- a/nova/virt/libvirt/connection.py +++ b/nova/virt/libvirt/connection.py @@ -351,7 +351,7 @@ class LibvirtConnection(driver.ComputeDriver): virt_dom = self._lookup_by_name(instance_name) mount_device = mountpoint.rpartition("/")[2] (type, protocol, name) = \ - self._get_volume_device_info(vol['device_path']) + self._get_volume_device_info(device_path) if type == 'block': xml = """<disk type='block'> <driver name='qemu' type='raw'/> @@ -364,9 +364,6 @@ class LibvirtConnection(driver.ComputeDriver): <source protocol='%s' name='%s'/> <target dev='%s' bus='virtio'/> </disk>""" % (protocol, name, mount_device) - else: - raise exception.InvalidDevicePath(path=device_path) - virt_dom.attachDevice(xml) def _get_disk_xml(self, xml, device): @@ -955,7 +952,6 @@ class LibvirtConnection(driver.ComputeDriver): return True return False - @exception.wrap_exception def _get_volume_device_info(self, device_path): if device_path.startswith('/dev/'): return ('block', None, None) diff --git a/nova/virt/libvirt/netutils.py b/nova/virt/libvirt/netutils.py index 041eacb2d..a8e88fc07 100644 --- a/nova/virt/libvirt/netutils.py +++ b/nova/virt/libvirt/netutils.py @@ -25,6 +25,7 @@ import netaddr from nova import context from nova import db +from nova import exception from nova import flags from nova import ipv6 from nova import utils @@ -55,10 +56,12 @@ def get_network_info(instance): # we should cache network_info admin_context = context.get_admin_context() - fixed_ips = db.fixed_ip_get_by_instance(admin_context, instance['id']) + try: + fixed_ips = db.fixed_ip_get_by_instance(admin_context, instance['id']) + except exception.FixedIpNotFoundForInstance: + fixed_ips = [] + vifs = db.virtual_interface_get_by_instance(admin_context, instance['id']) - networks = db.network_get_all_by_instance(admin_context, - instance['id']) flavor = db.instance_type_get(admin_context, instance['instance_type_id']) network_info = [] @@ -89,6 +92,7 @@ def get_network_info(instance): 'label': network['label'], 'gateway': network['gateway'], 'broadcast': network['broadcast'], + 'dhcp_server': network['gateway'], 'mac': vif['address'], 'rxtx_cap': flavor['rxtx_cap'], 'dns': [], diff --git a/nova/virt/libvirt/vif.py b/nova/virt/libvirt/vif.py index 24d45d1a7..eef582fac 100644 --- a/nova/virt/libvirt/vif.py +++ b/nova/virt/libvirt/vif.py @@ -126,7 +126,7 @@ class LibvirtOpenVswitchDriver(VIFDriver): dev = "tap-%s" % vif_id try: utils.execute('sudo', 'ovs-vsctl', 'del-port', - FLAGS.flat_network_bridge, dev) + network['bridge'], dev) utils.execute('sudo', 'ip', 'link', 'delete', dev) except: LOG.warning(_("Failed while unplugging vif of instance '%s'"), diff --git a/nova/virt/vmwareapi/fake.py b/nova/virt/vmwareapi/fake.py index 7370684bd..4c62d18bb 100644 --- a/nova/virt/vmwareapi/fake.py +++ b/nova/virt/vmwareapi/fake.py @@ -402,6 +402,16 @@ def _remove_file(file_path): lst_files.remove(file)
+def fake_plug_vifs(*args, **kwargs):
+ """Fakes plugging vifs."""
+ pass
+
+
+def fake_get_network(*args, **kwargs):
+ """Fake get network."""
+ return [{'type': 'fake'}]
+
+
def fake_fetch_image(image, instance, **kwargs):
"""Fakes fetch image call. Just adds a reference to the db for the file."""
ds_name = kwargs.get("datastore_name")
diff --git a/nova/virt/vmwareapi/network_utils.py b/nova/virt/vmwareapi/network_utils.py index 08e3bf0b1..ec3b93fe7 100644 --- a/nova/virt/vmwareapi/network_utils.py +++ b/nova/virt/vmwareapi/network_utils.py @@ -46,6 +46,7 @@ def get_network_with_the_name(session, network_name="vmnet0"): "get_properties_for_a_collection_of_objects",
"Network", vm_networks, ["summary.name"])
network_obj = {}
+ LOG.warn(vm_networks)
for network in vm_networks:
# Get network properties
if network._type == 'DistributedVirtualPortgroup':
diff --git a/nova/virt/vmwareapi/vm_util.py b/nova/virt/vmwareapi/vm_util.py index 55578dd3c..82b5f7214 100644 --- a/nova/virt/vmwareapi/vm_util.py +++ b/nova/virt/vmwareapi/vm_util.py @@ -110,7 +110,8 @@ def create_network_spec(client_factory, network_name, mac_address, # ephemeral. Invalid configuration if set to static and the NIC does
# not come up on boot if set to dynamic.
backing = None
- if (network_ref['type'] == "DistributedVirtualPortgroup"):
+ if (network_ref and
+ network_ref['type'] == "DistributedVirtualPortgroup"):
backing_name = \
'ns0:VirtualEthernetCardDistributedVirtualPortBackingInfo'
backing = \
diff --git a/nova/virt/vmwareapi/vmops.py b/nova/virt/vmwareapi/vmops.py index 7e7d2dac3..1ee8fa1c0 100644 --- a/nova/virt/vmwareapi/vmops.py +++ b/nova/virt/vmwareapi/vmops.py @@ -734,13 +734,14 @@ class VMWareVMOps(object): net_mask = network["netmask"]
gateway = network["gateway"]
broadcast = network["broadcast"]
- dns = network["dns"]
+ # TODO(vish): add support for dns2
+ dns = network["dns1"]
addresses = db.instance_get_fixed_addresses(admin_context,
instance['id'])
ip_addr = addresses[0] if addresses else None
- machine_id_chanfge_spec = \
+ machine_id_change_spec = \
vm_util.get_machine_id_change_spec(client_factory, mac_address,
ip_addr, net_mask, gateway,
broadcast, dns)
@@ -750,7 +751,7 @@ class VMWareVMOps(object): 'ip_addr': ip_addr}))
reconfig_task = self._session._call_method(self._session._get_vim(),
"ReconfigVM_Task", vm_ref,
- spec=machine_id_chanfge_spec)
+ spec=machine_id_change_spec)
self._session._wait_for_task(instance.id, reconfig_task)
LOG.debug(_("Reconfigured VM instance %(name)s to set the machine id "
"with ip - %(ip_addr)s") %
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 0473abb97..77efe1bf0 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -255,7 +255,7 @@ class VMOps(object): userdevice += 1 # Alter the image before VM start for, e.g. network injection - if FLAGS.xenapi_inject_image: + if FLAGS.flat_injected: VMHelper.preconfigure_instance(self._session, instance, first_vdi_ref, network_info) @@ -471,7 +471,7 @@ class VMOps(object): self._session, instance, template_vdi_uuids, image_id) finally: if template_vm_ref: - self._destroy(instance, template_vm_ref, None, + self._destroy(instance, template_vm_ref, shutdown=False, destroy_kernel_ramdisk=False) logging.debug(_("Finished snapshot and upload for VM %s"), instance) @@ -853,7 +853,7 @@ class VMOps(object): vm_ref = VMHelper.lookup(self._session, instance.name) return self._destroy(instance, vm_ref, network_info, shutdown=True) - def _destroy(self, instance, vm_ref, network_info, shutdown=True, + def _destroy(self, instance, vm_ref, network_info=None, shutdown=True, destroy_kernel_ramdisk=True): """Destroys VM instance by performing: @@ -1092,7 +1092,7 @@ class VMOps(object): LOG.debug(_('Created VIF %(vif_ref)s for VM %(vm_ref)s,' ' network %(network_ref)s.') % locals()) - def plug_vifs(instance, network_info): + def plug_vifs(self, instance, network_info): """Set up VIF networking on the host.""" for (network, mapping) in network_info: self.vif_driver.plug(self._session, instance, network, mapping) diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 7c355a55b..cddb8203b 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -112,22 +112,15 @@ flags.DEFINE_integer('xenapi_vhd_coalesce_max_attempts', 5, 'Max number of times to poll for VHD to coalesce.' ' Used only if connection_type=xenapi.') -flags.DEFINE_bool('xenapi_inject_image', - True, - 'Specifies whether an attempt to inject network/key' - ' data into the disk image should be made.' - ' Used only if connection_type=xenapi.') flags.DEFINE_string('xenapi_agent_path', 'usr/sbin/xe-update-networking', 'Specifies the path in which the xenapi guest agent' ' should be located. If the agent is present,' ' network configuration is not injected into the image' ' Used only if connection_type=xenapi.' - ' and xenapi_inject_image=True') - + ' and flat_injected=True') flags.DEFINE_string('xenapi_sr_base_path', '/var/run/sr-mount', 'Base path to the storage repository') - flags.DEFINE_string('target_host', None, 'iSCSI Target Host') |
