diff options
| author | Soren Hansen <soren@linux2go.dk> | 2011-03-24 00:51:08 +0100 |
|---|---|---|
| committer | Soren Hansen <soren@linux2go.dk> | 2011-03-24 00:51:08 +0100 |
| commit | 8fa54f515ebb271a69ac32d293257dcb7ed5ef90 (patch) | |
| tree | 067556ea668d136605b04cad10b25caa22497ad6 /nova/virt | |
| parent | 06815cb729d8687403fc736ae6125c26867f42b3 (diff) | |
| parent | 6912b0e1efd6ba3814d3b29beef236bfe4da52ea (diff) | |
Merge trunk
Diffstat (limited to 'nova/virt')
| -rw-r--r-- | nova/virt/interfaces.template | 16 | ||||
| -rw-r--r-- | nova/virt/libvirt.xml.template | 4 | ||||
| -rw-r--r-- | nova/virt/libvirt_conn.py | 58 | ||||
| -rw-r--r-- | nova/virt/xenapi/vmops.py | 62 | ||||
| -rw-r--r-- | nova/virt/xenapi_conn.py | 12 |
5 files changed, 98 insertions, 54 deletions
diff --git a/nova/virt/interfaces.template b/nova/virt/interfaces.template index 87b92b84a..3b34e54f4 100644 --- a/nova/virt/interfaces.template +++ b/nova/virt/interfaces.template @@ -8,10 +8,16 @@ iface lo inet loopback # The primary network interface auto eth0 iface eth0 inet static - address %(address)s - netmask %(netmask)s - broadcast %(broadcast)s - gateway %(gateway)s - dns-nameservers %(dns)s + address ${address} + netmask ${netmask} + broadcast ${broadcast} + gateway ${gateway} + dns-nameservers ${dns} +#if $use_ipv6 +iface eth0 inet6 static + address ${address_v6} + netmask ${netmask_v6} + gateway ${gateway_v6} +#end if diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template index 88bfbc668..ef2d2cd6b 100644 --- a/nova/virt/libvirt.xml.template +++ b/nova/virt/libvirt.xml.template @@ -79,8 +79,8 @@ #if $getVar('extra_params', False) ${extra_params} #end if -#if $getVar('ra_server', False) - <parameter name="RASERVER" value="${ra_server}" /> +#if $getVar('gateway_v6', False) + <parameter name="RASERVER" value="${gateway_v6}" /> #end if </filterref> </interface> diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py index fcd78b3b2..214670180 100644 --- a/nova/virt/libvirt_conn.py +++ b/nova/virt/libvirt_conn.py @@ -46,7 +46,7 @@ import time import uuid from xml.dom import minidom - +from eventlet import greenthread from eventlet import tpool import IPy @@ -159,6 +159,7 @@ class LibvirtConnection(object): self.libvirt_uri = self.get_uri() self.libvirt_xml = open(FLAGS.libvirt_xml_template).read() + self.interfaces_xml = open(FLAGS.injected_network_template).read() self.cpuinfo_xml = open(FLAGS.cpuinfo_xml_template).read() self._wrapped_conn = None self.read_only = read_only @@ -338,7 +339,11 @@ class LibvirtConnection(object): def reboot(self, instance): self.destroy(instance, False) xml = self.to_xml(instance) + self.firewall_driver.setup_basic_filtering(instance) + self.firewall_driver.prepare_instance_filter(instance) self._conn.createXML(xml, 0) + self.firewall_driver.apply_instance_filter(instance) + timer = utils.LoopingCall(f=None) def _wait_for_reboot(): @@ -657,16 +662,23 @@ class LibvirtConnection(object): if network_ref['injected']: admin_context = context.get_admin_context() address = db.instance_get_fixed_address(admin_context, inst['id']) - ra_server = network_ref['ra_server'] - if not ra_server: - ra_server = "fd00::" - with open(FLAGS.injected_network_template) as f: - net = f.read() % {'address': address, - 'netmask': network_ref['netmask'], - 'gateway': network_ref['gateway'], - 'broadcast': network_ref['broadcast'], - 'dns': network_ref['dns'], - 'ra_server': ra_server} + address_v6 = None + if FLAGS.use_ipv6: + address_v6 = db.instance_get_fixed_address_v6(admin_context, + inst['id']) + + interfaces_info = {'address': address, + 'netmask': network_ref['netmask'], + 'gateway': network_ref['gateway'], + 'broadcast': network_ref['broadcast'], + 'dns': network_ref['dns'], + 'address_v6': address_v6, + 'gateway_v6': network_ref['gateway_v6'], + 'netmask_v6': network_ref['netmask_v6'], + 'use_ipv6': FLAGS.use_ipv6} + + net = str(Template(self.interfaces_xml, + searchList=[interfaces_info])) if key or net: inst_name = inst['name'] img_id = inst.image_id @@ -701,7 +713,7 @@ class LibvirtConnection(object): instance['id']) # Assume that the gateway also acts as the dhcp server. dhcp_server = network['gateway'] - ra_server = network['ra_server'] + gateway_v6 = network['gateway_v6'] if FLAGS.allow_project_net_traffic: if FLAGS.use_ipv6: @@ -746,8 +758,8 @@ class LibvirtConnection(object): 'local': instance_type['local_gb'], 'driver_type': driver_type} - if ra_server: - xml_info['ra_server'] = ra_server + "/128" + if gateway_v6: + xml_info['gateway_v6'] = gateway_v6 + "/128" if not rescue: if instance['kernel_id']: xml_info['kernel'] = xml_info['basepath'] + "/kernel" @@ -1304,10 +1316,10 @@ class FirewallDriver(object): """ raise NotImplementedError() - def _ra_server_for_instance(self, instance): + def _gateway_v6_for_instance(self, instance): network = db.network_get_by_instance(context.get_admin_context(), instance['id']) - return network['ra_server'] + return network['gateway_v6'] class NWFilterFirewall(FirewallDriver): @@ -1523,8 +1535,8 @@ class NWFilterFirewall(FirewallDriver): 'nova-base-ipv6', 'nova-allow-dhcp-server'] if FLAGS.use_ipv6: - ra_server = self._ra_server_for_instance(instance) - if ra_server: + gateway_v6 = self._gateway_v6_for_instance(instance) + if gateway_v6: instance_secgroup_filter_children += ['nova-allow-ra-server'] ctxt = context.get_admin_context() @@ -1692,9 +1704,9 @@ class IptablesFirewallDriver(FirewallDriver): # they're not worth the clutter. if FLAGS.use_ipv6: # Allow RA responses - ra_server = self._ra_server_for_instance(instance) - if ra_server: - ipv6_rules += ['-s %s/128 -p icmpv6 -j ACCEPT' % (ra_server,)] + gateway_v6 = self._gateway_v6_for_instance(instance) + if gateway_v6: + ipv6_rules += ['-s %s/128 -p icmpv6 -j ACCEPT' % (gateway_v6,)] #Allow project network traffic if FLAGS.allow_project_net_traffic: @@ -1795,10 +1807,10 @@ class IptablesFirewallDriver(FirewallDriver): instance['id']) return network['gateway'] - def _ra_server_for_instance(self, instance): + def _gateway_v6_for_instance(self, instance): network = db.network_get_by_instance(context.get_admin_context(), instance['id']) - return network['ra_server'] + return network['gateway_v6'] def _project_cidr_for_instance(self, instance): network = db.network_get_by_instance(context.get_admin_context(), diff --git a/nova/virt/xenapi/vmops.py b/nova/virt/xenapi/vmops.py index 61ff00903..872e67f01 100644 --- a/nova/virt/xenapi/vmops.py +++ b/nova/virt/xenapi/vmops.py @@ -63,6 +63,17 @@ class VMOps(object): vm_refs.append(vm_rec["name_label"]) return vm_refs + def revert_resize(self, instance): + vm_ref = VMHelper.lookup(self._session, instance.name) + self._start(instance, vm_ref) + + def finish_resize(self, instance, disk_info): + vdi_uuid = self.link_disks(instance, disk_info['base_copy'], + disk_info['cow']) + vm_ref = self._create_vm(instance, vdi_uuid) + self.resize_instance(instance, vdi_uuid) + self._spawn(instance, vm_ref) + def _start(self, instance, vm_ref=None): """Power on a VM instance""" if not vm_ref: @@ -73,7 +84,7 @@ class VMOps(object): LOG.debug(_("Starting instance %s"), instance.name) self._session.call_xenapi('VM.start', vm_ref, False, False) - def create_disk(self, instance): + def _create_disk(self, instance): user = AuthManager().get_user(instance.user_id) project = AuthManager().get_project(instance.project_id) disk_image_type = VMHelper.determine_disk_image_type(instance) @@ -82,10 +93,11 @@ class VMOps(object): return vdi_uuid def spawn(self, instance, network_info=None): - vdi_uuid = self.create_disk(instance) - self._spawn_with_disk(instance, vdi_uuid, network_info) + vdi_uuid = self._create_disk(instance) + vm_ref = self._create_vm(instance, vdi_uuid, network_info) + self._spawn(instance, vm_ref) - def _spawn_with_disk(self, instance, vdi_uuid, network_info=None): + def _create_vm(self, instance, vdi_uuid, network_info=None): """Create VM instance""" instance_name = instance.name vm_ref = VMHelper.lookup(self._session, instance_name) @@ -128,16 +140,19 @@ class VMOps(object): VMHelper.create_vbd(session=self._session, vm_ref=vm_ref, vdi_ref=vdi_ref, userdevice=0, bootable=True) - # inject_network_info and create vifs # TODO(tr3buchet) - check to make sure we have network info, otherwise # create it now. This goes away once nova-multi-nic hits. if network_info is None: network_info = self._get_network_info(instance) self.create_vifs(vm_ref, network_info) self.inject_network_info(instance, vm_ref, network_info) + return vm_ref + def _spawn(self, instance, vm_ref): + """Spawn a new instance""" LOG.debug(_('Starting VM %s...'), vm_ref) self._start(instance, vm_ref) + instance_name = instance.name LOG.info(_('Spawning VM %(instance_name)s created %(vm_ref)s.') % locals()) @@ -310,7 +325,7 @@ class VMOps(object): try: # transfer the base copy template_vm_ref, template_vdi_uuids = self._get_snapshot(instance) - base_copy_uuid = template_vdi_uuids[1] + base_copy_uuid = template_vdi_uuids['image'] vdi_ref, vm_vdi_rec = \ VMHelper.get_vdi_for_vm_safely(self._session, vm_ref) cow_uuid = vm_vdi_rec['uuid'] @@ -325,7 +340,7 @@ class VMOps(object): self._session.wait_for_task(task, instance.id) # Now power down the instance and transfer the COW VHD - self._shutdown(instance, vm_ref, method='clean') + self._shutdown(instance, vm_ref, hard=False) params = {'host': dest, 'vdi_uuid': cow_uuid, @@ -345,7 +360,7 @@ class VMOps(object): # sensible so we don't need to blindly pass around dictionaries return {'base_copy': base_copy_uuid, 'cow': cow_uuid} - def attach_disk(self, instance, base_copy_uuid, cow_uuid): + def link_disks(self, instance, base_copy_uuid, cow_uuid): """Links the base copy VHD to the COW via the XAPI plugin""" vm_ref = VMHelper.lookup(self._session, instance.name) new_base_copy_uuid = str(uuid.uuid4()) @@ -366,9 +381,19 @@ class VMOps(object): return new_cow_uuid - def resize(self, instance, flavor): + def resize_instance(self, instance, vdi_uuid): """Resize a running instance by changing it's RAM and disk size """ - raise NotImplementedError() + #TODO(mdietz): this will need to be adjusted for swap later + #The new disk size must be in bytes + + new_disk_size = str(instance.local_gb * 1024 * 1024 * 1024) + instance_name = instance.name + instance_local_gb = instance.local_gb + LOG.debug(_("Resizing VDI %(vdi_uuid)s for instance %(instance_name)s." + " Expanding to %(instance_local_gb)d GB") % locals()) + vdi_ref = self._session.call_xenapi('VDI.get_by_uuid', vdi_uuid) + self._session.call_xenapi('VDI.resize_online', vdi_ref, new_disk_size) + LOG.debug(_("Resize instance %s complete") % (instance.name)) def reboot(self, instance): """Reboot VM instance""" @@ -443,8 +468,9 @@ class VMOps(object): """Shutdown an instance""" state = self.get_info(instance['name'])['state'] if state == power_state.SHUTDOWN: - LOG.warn(_("VM %(vm)s already halted, skipping shutdown...") % - locals()) + instance_name = instance.name + LOG.warn(_("VM %(instance_name)s already halted," + "skipping shutdown...") % locals()) return instance_id = instance.id @@ -711,9 +737,10 @@ class VMOps(object): def ip6_dict(ip6): return { - "ip": ip6.addressV6, - "netmask": ip6.netmaskV6, - "gateway": ip6.gatewayV6, + "ip": utils.to_global_ipv6(network['cidr_v6'], + instance['mac_address']), + "netmask": network['netmask_v6'], + "gateway": network['gateway_v6'], "enabled": "1"} info = { @@ -722,8 +749,9 @@ class VMOps(object): 'mac': instance.mac_address, 'rxtx_cap': flavor['rxtx_cap'], 'dns': [network['dns']], - 'ips': [ip_dict(ip) for ip in network_IPs], - 'ip6s': [ip6_dict(ip) for ip in network_IPs]} + 'ips': [ip_dict(ip) for ip in network_IPs]} + if network['cidr_v6']: + info['ip6s'] = [ip6_dict(ip) for ip in network_IPs] network_info.append((network, info)) return network_info diff --git a/nova/virt/xenapi_conn.py b/nova/virt/xenapi_conn.py index da42a83b6..da2fb51f1 100644 --- a/nova/virt/xenapi_conn.py +++ b/nova/virt/xenapi_conn.py @@ -164,20 +164,18 @@ class XenAPIConnection(object): """Create VM instance""" self._vmops.spawn(instance) + def revert_resize(self, instance): + """Reverts a resize, powering back on the instance""" + self._vmops.revert_resize(instance) + def finish_resize(self, instance, disk_info): """Completes a resize, turning on the migrated instance""" - vdi_uuid = self._vmops.attach_disk(instance, disk_info['base_copy'], - disk_info['cow']) - self._vmops._spawn_with_disk(instance, vdi_uuid) + self._vmops.finish_resize(instance, disk_info) def snapshot(self, instance, image_id): """ Create snapshot from a running VM instance """ self._vmops.snapshot(instance, image_id) - def resize(self, instance, flavor): - """Resize a VM instance""" - raise NotImplementedError() - def reboot(self, instance): """Reboot VM instance""" self._vmops.reboot(instance) |
