summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChristopher MacGown <chris@pistoncloud.com>2011-08-11 17:40:13 -0700
committerChristopher MacGown <chris@pistoncloud.com>2011-08-11 17:40:13 -0700
commitf22cfa05f7c796fbda3d832e4bfadc325f8af6f5 (patch)
treee2e9cab86590cbbae8dcdbc05828643c3450d0c1
parentd963e25906b75a48c75b6e589deb2a53f75d6ee3 (diff)
downloadnova-f22cfa05f7c796fbda3d832e4bfadc325f8af6f5.tar.gz
nova-f22cfa05f7c796fbda3d832e4bfadc325f8af6f5.tar.xz
nova-f22cfa05f7c796fbda3d832e4bfadc325f8af6f5.zip
Updates to libvirt, write metadata, net, and key to the config drive
-rw-r--r--nova/network/manager.py3
-rw-r--r--nova/virt/disk.py33
-rw-r--r--nova/virt/libvirt.xml.template14
-rw-r--r--nova/virt/libvirt/connection.py51
4 files changed, 68 insertions, 33 deletions
diff --git a/nova/network/manager.py b/nova/network/manager.py
index 75c3f668d..44bf662ce 100644
--- a/nova/network/manager.py
+++ b/nova/network/manager.py
@@ -893,7 +893,6 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
def _setup_network(self, context, network_ref):
"""Sets up network on this host."""
- network_ref['dhcp_server'] = self._get_dhcp_ip(context, network_ref)
if not network_ref['vpn_public_address']:
net = {}
address = FLAGS.vpn_ip
@@ -901,6 +900,8 @@ class VlanManager(RPCAllocateFixedIP, FloatingIP, NetworkManager):
network_ref = db.network_update(context, network_ref['id'], net)
else:
address = network_ref['vpn_public_address']
+
+ network_ref['dhcp_server'] = self._get_dhcp_ip(context, network_ref)
self.driver.ensure_vlan_bridge(network_ref['vlan'],
network_ref['bridge'],
network_ref['bridge_interface'],
diff --git a/nova/virt/disk.py b/nova/virt/disk.py
index f8aea1f34..fda3f5f29 100644
--- a/nova/virt/disk.py
+++ b/nova/virt/disk.py
@@ -2,6 +2,9 @@
# Copyright 2010 United States Government as represented by the
# Administrator of the National Aeronautics and Space Administration.
+#
+# Copyright 2011, Piston Cloud Computing, Inc.
+#
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -22,6 +25,7 @@ Includes injection of SSH PGP keys into authorized_keys file.
"""
+import json
import os
import tempfile
import time
@@ -60,7 +64,8 @@ def extend(image, size):
utils.execute('resize2fs', image, check_exit_code=False)
-def inject_data(image, key=None, net=None, partition=None, nbd=False):
+def inject_data(image, key=None, net=None, metadata=None,
+ partition=None, nbd=False, tune2fs=True):
"""Injects a ssh key and optionally net data into a disk image.
it will mount the image as a fully partitioned disk and attempt to inject
@@ -89,9 +94,10 @@ def inject_data(image, key=None, net=None, partition=None, nbd=False):
' only inject raw disk images): %s' %
mapped_device)
- # Configure ext2fs so that it doesn't auto-check every N boots
- out, err = utils.execute('sudo', 'tune2fs',
- '-c', 0, '-i', 0, mapped_device)
+ if tune2fs:
+ # Configure ext2fs so that it doesn't auto-check every N boots
+ out, err = utils.execute('sudo', 'tune2fs',
+ '-c', 0, '-i', 0, mapped_device)
tmpdir = tempfile.mkdtemp()
try:
@@ -103,7 +109,8 @@ def inject_data(image, key=None, net=None, partition=None, nbd=False):
% err)
try:
- inject_data_into_fs(tmpdir, key, net, utils.execute)
+ inject_data_into_fs(tmpdir, key, net, metadata,
+ utils.execute)
finally:
# unmount device
utils.execute('sudo', 'umount', mapped_device)
@@ -155,6 +162,7 @@ def destroy_container(target, instance, nbd=False):
def _link_device(image, nbd):
"""Link image to device using loopback or nbd"""
+
if nbd:
device = _allocate_device()
utils.execute('sudo', 'qemu-nbd', '-c', device, image)
@@ -189,6 +197,7 @@ def _allocate_device():
# NOTE(vish): This assumes no other processes are allocating nbd devices.
# It may race cause a race condition if multiple
# workers are running on a given machine.
+
while True:
if not _DEVICES:
raise exception.Error(_('No free nbd devices'))
@@ -202,7 +211,7 @@ def _free_device(device):
_DEVICES.append(device)
-def inject_data_into_fs(fs, key, net, execute):
+def inject_data_into_fs(fs, key, net, metadata, execute):
"""Injects data into a filesystem already mounted by the caller.
Virt connections can call this directly if they mount their fs
in a different way to inject_data
@@ -211,7 +220,19 @@ def inject_data_into_fs(fs, key, net, execute):
_inject_key_into_fs(key, fs, execute=execute)
if net:
_inject_net_into_fs(net, fs, execute=execute)
+ if metadata:
+ _inject_metadata_into_fs(metadata, fs, execute=execute)
+
+def _inject_file_into_fs(injected_files, fs, execute=None):
+ for path, data in injected_files:
+
+
+def _inject_metadata_into_fs(metadata, fs, execute=None):
+ metadata_path = os.path.join(fs, "meta.js")
+ metadata = dict([(m.key, m.value) for m in metadata])
+ utils.execute('sudo', 'tee', '-a', metadata_path,
+ process_input=json.dumps(metadata))
def _inject_key_into_fs(key, fs, execute=None):
"""Add the given public ssh key to root's authorized_keys.
diff --git a/nova/virt/libvirt.xml.template b/nova/virt/libvirt.xml.template
index 4422f349f..1fa536ad1 100644
--- a/nova/virt/libvirt.xml.template
+++ b/nova/virt/libvirt.xml.template
@@ -55,13 +55,6 @@
<target dir='/'/>
</filesystem>
#else
- #if $getVar('config', False)
- <disk type='file'>
- <driver type='${driver_type}' />
- <source file='${basepath}/disk.config' />
- <target dev='${disk_prefix}z' bus='${disk_bus}' />
- </disk>
- #end if
#if $getVar('rescue', False)
<disk type='file'>
<driver type='${driver_type}'/>
@@ -96,6 +89,13 @@
</disk>
#end for
#end if
+ #if $getVar('config_drive', False)
+ <disk type='file'>
+ <driver type='raw' />
+ <source file='${basepath}/disk.config' />
+ <target dev='${disk_prefix}z' bus='${disk_bus}' />
+ </disk>
+ #end if
#end if
#for $nic in $nics
diff --git a/nova/virt/libvirt/connection.py b/nova/virt/libvirt/connection.py
index ad97dc796..35ce0dcde 100644
--- a/nova/virt/libvirt/connection.py
+++ b/nova/virt/libvirt/connection.py
@@ -781,6 +781,7 @@ class LibvirtConnection(driver.ComputeDriver):
network_info=None, block_device_mapping=None):
block_device_mapping = block_device_mapping or []
+
if not suffix:
suffix = ''
@@ -857,7 +858,7 @@ class LibvirtConnection(driver.ComputeDriver):
target=basepath('disk.local'),
fname="local_%s" % inst_type['local_gb'],
cow=FLAGS.use_cow_images,
- local_gb=inst_type['local_gb'])
+ local_size=inst_type['local_gb'])
# For now, we assume that if we're not using a kernel, we're using a
# partitioned disk image where the target partition is the first
@@ -866,20 +867,23 @@ class LibvirtConnection(driver.ComputeDriver):
if not inst['kernel_id']:
target_partition = "1"
- if FLAGS.libvirt_type == 'lxc':
+ config_drive_id = inst.get('config_drive_id')
+ config_drive = inst.get('config_drive')
+
+ if any((FLAGS.libvirt_type == 'lxc', config_drive, config_drive_id)):
target_partition = None
- else:
- if inst['config_drive_id']:
- fname = '%08x' % int(inst['config_drive_id'])
- self._cache_image(fn=self._fetch_image,
- target=basepath('config'),
- fname=fname,
- image_id=inst['config_drive_id'],
- user=user,
- project=project)
- elif inst['config_drive']:
- self._create_local(basepath('config'), 64, prefix="M",
- fs_format='msdos') # 64MB
+
+ if config_drive_id:
+ fname = '%08x' % int(config_drive_id)
+ self._cache_image(fn=self._fetch_image,
+ target=basepath('disk.config'),
+ fname=fname,
+ image_id=config_drive_id,
+ user=user,
+ project=project)
+ elif config_drive:
+ self._create_local(basepath('disk.config'), 64, prefix="M",
+ fs_format='msdos') # 64MB
if inst['key_data']:
key = str(inst['key_data'])
@@ -924,15 +928,18 @@ class LibvirtConnection(driver.ComputeDriver):
searchList=[{'interfaces': nets,
'use_ipv6': FLAGS.use_ipv6}]))
- if any(key, net, inst['metadata']):
+ metadata = inst.get('metadata')
+ if any((key, net, metadata)):
inst_name = inst['name']
- if inst['config_drive']: # Should be True or None by now.
- injection_path = basepath('config')
+ if config_drive: # Should be True or None by now.
+ injection_path = basepath('disk.config')
img_id = 'config-drive'
+ tune2fs = False
else:
injection_path = basepath('disk')
img_id = inst.image_ref
+ tune2fs = True
for injection in ('metadata', 'key', 'net'):
if locals()[injection]:
@@ -940,9 +947,10 @@ class LibvirtConnection(driver.ComputeDriver):
'%(injection)s into image %(img_id)s'
% locals()))
try:
- disk.inject_data(injection_path, key, net, inst['metadata'],
+ disk.inject_data(injection_path, key, net, metadata,
partition=target_partition,
- nbd=FLAGS.use_cow_images)
+ nbd=FLAGS.use_cow_images,
+ tune2fs=tune2fs)
if FLAGS.libvirt_type == 'lxc':
disk.setup_container(basepath('disk'),
@@ -1043,6 +1051,11 @@ class LibvirtConnection(driver.ComputeDriver):
'ebs_root': ebs_root,
'volumes': block_device_mapping}
+
+ config_drive = False
+ if instance.get('config_drive') or instance.get('config_drive_id'):
+ xml_info['config_drive'] = xml_info['basepath'] + "/disk.config"
+
if FLAGS.vnc_enabled and FLAGS.libvirt_type not in ('lxc', 'uml'):
xml_info['vncserver_host'] = FLAGS.vncserver_host
xml_info['vnc_keymap'] = FLAGS.vnc_keymap