diff options
| author | Sandy Walsh <sandy.walsh@rackspace.com> | 2011-09-12 07:36:14 -0700 |
|---|---|---|
| committer | Sandy Walsh <sandy.walsh@rackspace.com> | 2011-09-12 07:36:14 -0700 |
| commit | 043a13690dc4f2ba20965cced85d705e59f7406b (patch) | |
| tree | d385fe22f81b435e8cb56a774f5244db7b45637c | |
| parent | a27aa5dce2788560b29fd33b4805acf0190a27e3 (diff) | |
| parent | 66dd77887641f9db5f690f871b0cfb4d381d6a3e (diff) | |
| download | nova-043a13690dc4f2ba20965cced85d705e59f7406b.tar.gz nova-043a13690dc4f2ba20965cced85d705e59f7406b.tar.xz nova-043a13690dc4f2ba20965cced85d705e59f7406b.zip | |
bug fixes
| -rwxr-xr-x | bin/nova-manage | 3 | ||||
| -rwxr-xr-x | bin/nova-vncproxy | 15 | ||||
| -rw-r--r-- | nova/api/openstack/servers.py | 5 | ||||
| -rw-r--r-- | nova/compute/api.py | 11 | ||||
| -rw-r--r-- | nova/compute/manager.py | 4 | ||||
| -rw-r--r-- | nova/db/api.py | 6 | ||||
| -rw-r--r-- | nova/db/sqlalchemy/api.py | 9 | ||||
| -rw-r--r-- | nova/network/manager.py | 3 | ||||
| -rw-r--r-- | nova/scheduler/abstract_scheduler.py | 2 | ||||
| -rw-r--r-- | nova/scheduler/api.py | 3 | ||||
| -rw-r--r-- | nova/scheduler/base_scheduler.py | 7 | ||||
| -rw-r--r-- | nova/tests/test_compute.py | 15 | ||||
| -rw-r--r-- | nova/tests/test_network.py | 3 | ||||
| -rw-r--r-- | nova/tests/test_virt_drivers.py | 3 | ||||
| -rw-r--r-- | nova/tests/test_vmwareapi.py | 3 | ||||
| -rw-r--r-- | nova/virt/disk.py | 2 | ||||
| -rw-r--r-- | nova/virt/driver.py | 3 | ||||
| -rw-r--r-- | nova/virt/fake.py | 2 | ||||
| -rw-r--r-- | nova/virt/hyperv.py | 2 | ||||
| -rw-r--r-- | nova/virt/vmwareapi_conn.py | 2 | ||||
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 9 | ||||
| -rw-r--r-- | nova/virt/xenapi_conn.py | 4 |
22 files changed, 75 insertions, 41 deletions
diff --git a/bin/nova-manage b/bin/nova-manage index bc191b2f0..089b2eeae 100755 --- a/bin/nova-manage +++ b/bin/nova-manage @@ -724,8 +724,7 @@ class NetworkCommands(object): 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'] + interface_required = ['nova.network.manager.VlanManager'] if FLAGS.network_manager in interface_required: raise exception.NetworkNotCreated(req='--bridge_interface') diff --git a/bin/nova-vncproxy b/bin/nova-vncproxy index dc08e2433..8e75451cb 100755 --- a/bin/nova-vncproxy +++ b/bin/nova-vncproxy @@ -107,10 +107,13 @@ if __name__ == "__main__": else: with_auth = auth.VNCNovaAuthMiddleware(with_logging) - server = wsgi.Server("VNC Proxy", - with_auth, - host=FLAGS.vncproxy_host, - port=FLAGS.vncproxy_port) - server.start_tcp(handle_flash_socket_policy, 843, host=FLAGS.vncproxy_host) - service.serve(server) + wsgi_server = wsgi.Server("VNC Proxy", + with_auth, + host=FLAGS.vncproxy_host, + port=FLAGS.vncproxy_port) + wsgi_server.start_tcp(handle_flash_socket_policy, + 843, + host=FLAGS.vncproxy_host) + server = service.Service.create(binary='nova-vncproxy') + service.serve(wsgi_server, server) service.wait() diff --git a/nova/api/openstack/servers.py b/nova/api/openstack/servers.py index d084ac360..f5447edc5 100644 --- a/nova/api/openstack/servers.py +++ b/nova/api/openstack/servers.py @@ -334,9 +334,8 @@ class Controller(object): LOG.exception(msg) raise exc.HTTPBadRequest(explanation=msg) try: - # TODO(gundlach): pass reboot_type, support soft reboot in - # virt driver - self.compute_api.reboot(req.environ['nova.context'], id) + self.compute_api.reboot(req.environ['nova.context'], id, + reboot_type) except Exception, e: LOG.exception(_("Error in reboot %s"), e) raise exc.HTTPUnprocessableEntity() diff --git a/nova/compute/api.py b/nova/compute/api.py index 4e2944bb7..7211c2cf0 100644 --- a/nova/compute/api.py +++ b/nova/compute/api.py @@ -908,10 +908,8 @@ class API(base.Base): if not recurse_zones: return instances - # Recurse zones. Need admin context for this. Send along - # the un-modified search options we received.. - admin_context = context.elevated() - children = scheduler_api.call_zone_method(admin_context, + # Recurse zones. Send along the un-modified search options we received. + children = scheduler_api.call_zone_method(context, "list", errors_to_ignore=[novaclient.exceptions.NotFound], novaclient_collection_name="servers", @@ -1042,13 +1040,14 @@ class API(base.Base): return recv_meta @scheduler_api.reroute_compute("reboot") - def reboot(self, context, instance_id): + def reboot(self, context, instance_id, reboot_type): """Reboot the given instance.""" self.update(context, instance_id, vm_state=vm_states.ACTIVE, task_state=task_states.REBOOTING) - self._cast_compute_message('reboot_instance', context, instance_id) + self._cast_compute_message('reboot_instance', context, instance_id, + reboot_type) @scheduler_api.reroute_compute("rebuild") def rebuild(self, context, instance_id, image_href, admin_password, diff --git a/nova/compute/manager.py b/nova/compute/manager.py index 0477db745..0be12297f 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -579,7 +579,7 @@ class ComputeManager(manager.SchedulerDependentManager): @exception.wrap_exception(notifier=notifier, publisher_id=publisher_id()) @checks_instance_lock - def reboot_instance(self, context, instance_id): + def reboot_instance(self, context, instance_id, reboot_type="SOFT"): """Reboot an instance on this host.""" LOG.audit(_("Rebooting instance %s"), instance_id, context=context) context = context.elevated() @@ -601,7 +601,7 @@ class ComputeManager(manager.SchedulerDependentManager): context=context) network_info = self._get_instance_nw_info(context, instance_ref) - self.driver.reboot(instance_ref, network_info) + self.driver.reboot(instance_ref, network_info, reboot_type) current_power_state = self._get_power_state(context, instance_ref) self._instance_update(context, diff --git a/nova/db/api.py b/nova/db/api.py index c03a86671..a9d2dc065 100644 --- a/nova/db/api.py +++ b/nova/db/api.py @@ -324,13 +324,15 @@ def migration_get_by_instance_and_status(context, instance_uuid, status): #################### -def fixed_ip_associate(context, address, instance_id, network_id=None): +def fixed_ip_associate(context, address, instance_id, network_id=None, + reserved=False): """Associate fixed ip to instance. Raises if fixed ip is not available. """ - return IMPL.fixed_ip_associate(context, address, instance_id, network_id) + return IMPL.fixed_ip_associate(context, address, instance_id, network_id, + reserved) def fixed_ip_associate_pool(context, network_id, instance_id=None, host=None): diff --git a/nova/db/sqlalchemy/api.py b/nova/db/sqlalchemy/api.py index 523258841..40e2ca167 100644 --- a/nova/db/sqlalchemy/api.py +++ b/nova/db/sqlalchemy/api.py @@ -669,14 +669,19 @@ def floating_ip_update(context, address, values): @require_admin_context -def fixed_ip_associate(context, address, instance_id, network_id=None): +def fixed_ip_associate(context, address, instance_id, network_id=None, + reserved=False): + """Keyword arguments: + reserved -- should be a boolean value(True or False), exact value will be + used to filter on the fixed ip address + """ session = get_session() with session.begin(): network_or_none = or_(models.FixedIp.network_id == network_id, models.FixedIp.network_id == None) fixed_ip_ref = session.query(models.FixedIp).\ filter(network_or_none).\ - filter_by(reserved=False).\ + filter_by(reserved=reserved).\ filter_by(deleted=False).\ filter_by(address=address).\ with_lockmode('update').\ diff --git a/nova/network/manager.py b/nova/network/manager.py index 05d928fab..da360720b 100644 --- a/nova/network/manager.py +++ b/nova/network/manager.py @@ -1005,7 +1005,8 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager): address = network['vpn_private_address'] self.db.fixed_ip_associate(context, address, - instance_id) + instance_id, + reserved=True) else: address = kwargs.get('address', None) if address: diff --git a/nova/scheduler/abstract_scheduler.py b/nova/scheduler/abstract_scheduler.py index 657ac1483..b121444f2 100644 --- a/nova/scheduler/abstract_scheduler.py +++ b/nova/scheduler/abstract_scheduler.py @@ -20,8 +20,8 @@ customize the behavior: filter_hosts() and weigh_hosts(). The default behavior is to simply select all hosts and weight them the same. """ -import operator import json +import operator import M2Crypto diff --git a/nova/scheduler/api.py b/nova/scheduler/api.py index ace8d1b04..6c5118751 100644 --- a/nova/scheduler/api.py +++ b/nova/scheduler/api.py @@ -119,7 +119,8 @@ def call_zone_method(context, method_name, errors_to_ignore=None, try: # Do this on behalf of the user ... nova = novaclient.Client(zone.username, zone.password, None, - zone.api_url, token = context.auth_token) + zone.api_url, region_name=zone.name, + token = context.auth_token) nova.authenticate() except novaclient_exceptions.BadRequest, e: url = zone.api_url diff --git a/nova/scheduler/base_scheduler.py b/nova/scheduler/base_scheduler.py index e9c078b81..e8629ca92 100644 --- a/nova/scheduler/base_scheduler.py +++ b/nova/scheduler/base_scheduler.py @@ -27,6 +27,8 @@ from nova.scheduler import abstract_scheduler from nova.scheduler import host_filter FLAGS = flags.FLAGS +flags.DEFINE_boolean('spread_first', False, + 'Use a spread-first zone scheduler strategy') LOG = logging.getLogger('nova.scheduler.base_scheduler') @@ -68,4 +70,9 @@ class BaseScheduler(abstract_scheduler.AbstractScheduler): if num_instances > 0: instances.extend(hosts[:num_instances]) + # Adjust the weights for a spread-first strategy + if FLAGS.spread_first: + for i, host in enumerate(hosts): + host['weight'] = i + 1 + return instances diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 65fdffbd6..4d463572b 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -300,11 +300,20 @@ class ComputeTestCase(test.TestCase): self.compute.resume_instance(self.context, instance_id) self.compute.terminate_instance(self.context, instance_id) - def test_reboot(self): - """Ensure instance can be rebooted""" + def test_soft_reboot(self): + """Ensure instance can be soft rebooted""" instance_id = self._create_instance() + reboot_type = "SOFT" self.compute.run_instance(self.context, instance_id) - self.compute.reboot_instance(self.context, instance_id) + self.compute.reboot_instance(self.context, instance_id, reboot_type) + self.compute.terminate_instance(self.context, instance_id) + + def test_hard_reboot(self): + """Ensure instance can be hard rebooted""" + instance_id = self._create_instance() + reboot_type = "HARD" + self.compute.run_instance(self.context, instance_id) + self.compute.reboot_instance(self.context, instance_id, reboot_type) self.compute.terminate_instance(self.context, instance_id) def test_set_admin_password(self): diff --git a/nova/tests/test_network.py b/nova/tests/test_network.py index c947bbc58..926ea065a 100644 --- a/nova/tests/test_network.py +++ b/nova/tests/test_network.py @@ -286,7 +286,8 @@ class VlanNetworkTestCase(test.TestCase): db.fixed_ip_associate(mox.IgnoreArg(), mox.IgnoreArg(), - mox.IgnoreArg()).AndReturn('192.168.0.1') + mox.IgnoreArg(), + reserved=True).AndReturn('192.168.0.1') db.fixed_ip_update(mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg()) diff --git a/nova/tests/test_virt_drivers.py b/nova/tests/test_virt_drivers.py index 480247c91..440d3401b 100644 --- a/nova/tests/test_virt_drivers.py +++ b/nova/tests/test_virt_drivers.py @@ -103,8 +103,9 @@ class _VirtDriverTestCase(test.TestCase): def test_reboot(self): instance_ref = test_utils.get_test_instance() network_info = test_utils.get_test_network_info() + reboot_type = "SOFT" self.connection.spawn(self.ctxt, instance_ref, network_info) - self.connection.reboot(instance_ref, network_info) + self.connection.reboot(instance_ref, network_info, reboot_type) @catch_notimplementederror def test_get_host_ip_addr(self): diff --git a/nova/tests/test_vmwareapi.py b/nova/tests/test_vmwareapi.py index 06daf46e8..e6da1690f 100644 --- a/nova/tests/test_vmwareapi.py +++ b/nova/tests/test_vmwareapi.py @@ -170,7 +170,8 @@ class VMWareAPIVMTestCase(test.TestCase): self._create_vm() info = self.conn.get_info(1) self._check_vm_info(info, power_state.RUNNING) - self.conn.reboot(self.instance, self.network_info) + reboot_type = "SOFT" + self.conn.reboot(self.instance, self.network_info, reboot_type) info = self.conn.get_info(1) self._check_vm_info(info, power_state.RUNNING) diff --git a/nova/virt/disk.py b/nova/virt/disk.py index 52b2881e8..50c7c40e9 100644 --- a/nova/virt/disk.py +++ b/nova/virt/disk.py @@ -58,7 +58,7 @@ def extend(image, size): file_size = os.path.getsize(image) if file_size >= size: return - utils.execute('truncate', '-s', size, image) + utils.execute('qemu-img', 'resize', image, size) # NOTE(vish): attempts to resize filesystem utils.execute('e2fsck', '-fp', image, check_exit_code=False) utils.execute('resize2fs', image, check_exit_code=False) diff --git a/nova/virt/driver.py b/nova/virt/driver.py index d05b51bd9..301346c6b 100644 --- a/nova/virt/driver.py +++ b/nova/virt/driver.py @@ -165,12 +165,13 @@ class ComputeDriver(object): # TODO(Vek): Need to pass context in for access to auth_token raise NotImplementedError() - def reboot(self, instance, network_info): + def reboot(self, instance, network_info, reboot_type): """Reboot the specified instance. :param instance: Instance object as returned by DB layer. :param network_info: :py:meth:`~nova.network.manager.NetworkManager.get_instance_nw_info` + :param reboot_type: Either a HARD or SOFT reboot """ # TODO(Vek): Need to pass context in for access to auth_token raise NotImplementedError() diff --git a/nova/virt/fake.py b/nova/virt/fake.py index d5e2bf31b..3596d8353 100644 --- a/nova/virt/fake.py +++ b/nova/virt/fake.py @@ -103,7 +103,7 @@ class FakeConnection(driver.ComputeDriver): if not instance['name'] in self.instances: raise exception.InstanceNotRunning() - def reboot(self, instance, network_info): + def reboot(self, instance, network_info, reboot_type): pass def get_host_ip_addr(self): diff --git a/nova/virt/hyperv.py b/nova/virt/hyperv.py index 03a78db1f..76925b405 100644 --- a/nova/virt/hyperv.py +++ b/nova/virt/hyperv.py @@ -367,7 +367,7 @@ class HyperVConnection(driver.ComputeDriver): wmi_obj.Properties_.Item(prop).Value return newinst - def reboot(self, instance, network_info): + def reboot(self, instance, network_info, reboot_type): """Reboot the specified instance.""" vm = self._lookup(instance.name) if vm is None: diff --git a/nova/virt/vmwareapi_conn.py b/nova/virt/vmwareapi_conn.py index 243ee64f5..fa89a8f45 100644 --- a/nova/virt/vmwareapi_conn.py +++ b/nova/virt/vmwareapi_conn.py @@ -133,7 +133,7 @@ class VMWareESXConnection(driver.ComputeDriver): """Create snapshot from a running VM instance."""
self._vmops.snapshot(context, instance, name)
- def reboot(self, instance, network_info):
+ def reboot(self, instance, network_info, reboot_type):
"""Reboot VM instance."""
self._vmops.reboot(instance, network_info)
diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 9c138ee41..996bdb209 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -624,10 +624,15 @@ class VMOps(object): str(new_disk_size)) LOG.debug(_("Resize instance %s complete") % (instance.name)) - def reboot(self, instance): + def reboot(self, instance, reboot_type): """Reboot VM instance.""" vm_ref = self._get_vm_opaque_ref(instance) - task = self._session.call_xenapi('Async.VM.clean_reboot', vm_ref) + + if reboot_type == "HARD": + task = self._session.call_xenapi('Async.VM.hard_reboot', vm_ref) + else: + task = self._session.call_xenapi('Async.VM.clean_reboot', vm_ref) + self._session.wait_for_task(task, instance.id) def get_agent_version(self, instance, timeout=None): diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index 0d23e7689..f6dbc19f8 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -203,9 +203,9 @@ class XenAPIConnection(driver.ComputeDriver): """ Create snapshot from a running VM instance """ self._vmops.snapshot(context, instance, image_id) - def reboot(self, instance, network_info): + def reboot(self, instance, network_info, reboot_type): """Reboot VM instance""" - self._vmops.reboot(instance) + self._vmops.reboot(instance, reboot_type) def set_admin_password(self, instance, new_pass): """Set the root/admin password on the VM instance""" |
