summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorVishvananda Ishaya <vishvananda@gmail.com>2011-01-05 19:50:39 +0000
committerVishvananda Ishaya <vishvananda@gmail.com>2011-01-05 19:50:39 +0000
commitf1f292a787ba20134c007da087bd9585d1875e86 (patch)
treee3afe7332f067a19d5e47e06c371714d62ea5f43
parentb5f8ab0e913c121a80ff0efe358960099e7c87f8 (diff)
downloadnova-f1f292a787ba20134c007da087bd9585d1875e86.tar.gz
nova-f1f292a787ba20134c007da087bd9585d1875e86.tar.xz
nova-f1f292a787ba20134c007da087bd9585d1875e86.zip
more fixes, docstrings
-rw-r--r--nova/compute/disk.py18
-rw-r--r--nova/virt/libvirt_conn.py83
2 files changed, 51 insertions, 50 deletions
diff --git a/nova/compute/disk.py b/nova/compute/disk.py
index f640bdbbb..ac0d689d5 100644
--- a/nova/compute/disk.py
+++ b/nova/compute/disk.py
@@ -107,13 +107,15 @@ def partition(infile, outfile, local_bytes=0, resize=True, local_type='ext2'):
def extend(image, size):
+ """Increase image to size"""
file_size = os.path.getsize(image)
if file_size >= size:
return
+ # TODO(vish): attempt to resize filesystem
return utils.execute('truncate -s %s %s' % (size, image))
-def inject_data(image, key=None, net=None, partition=None):
+def inject_data(image, key=None, net=None, partition=None, nbd=False):
"""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
@@ -122,7 +124,7 @@ def inject_data(image, key=None, net=None, partition=None):
If partition is not specified it mounts the image as a single partition.
"""
- device = _link_device(image)
+ device = _link_device(image, nbd)
try:
if not partition is None:
# create partition
@@ -169,11 +171,12 @@ def inject_data(image, key=None, net=None, partition=None):
# remove partitions
utils.execute('sudo kpartx -d %s' % device)
finally:
- _unlink_device(image, device)
+ _unlink_device(device, nbd)
-def _link_device(image):
- if FLAGS.use_cow_images:
+def _link_device(image, nbd):
+ """Link image to device using loopback or nbd"""
+ if nbd:
device = _allocate_device()
utils.execute('sudo qemu-nbd -c %s %s' % (device, image))
return device
@@ -185,8 +188,9 @@ def _link_device(image):
return out.strip()
-def _unlink_device(device):
- if FLAGS.use_cow_images:
+def _unlink_device(device, nbd):
+ """Unlink image from device using loopback or nbd"""
+ if nbd:
utils.execute('sudo qemu-nbd -d %s' % device)
_free_device(device)
else:
diff --git a/nova/virt/libvirt_conn.py b/nova/virt/libvirt_conn.py
index ae725b766..95a374603 100644
--- a/nova/virt/libvirt_conn.py
+++ b/nova/virt/libvirt_conn.py
@@ -118,28 +118,38 @@ def _get_net_and_mask(cidr):
return str(net.net()), str(net.netmask())
-def wrap_cow_image(key):
+def wrap_image_cache(key):
+ """Decorator for a method that creates an image to store it in cache.
+
+ This wrapper will save the image into a common store and create a
+ copy for use by the hypervisor.
+
+ The underlying method should be called with kwargs and specify
+ a kwarg of target representing where the image will be saved. The
+ key argument to the wrapper defines which kwarg of the underlying
+ method to use as the filename of the base image. The filename needs
+ to be unique to a given image.
+
+ If kwargs['cow'] is True, it will make a CoW image instead of a copy.
+ """
def _decorator(retrieve_fn):
def _wrap(*args, **kwargs):
target = kwargs['target']
if not os.path.exists(target):
- if FLAGS.use_cow_images:
- base_dir = os.path.join(FLAGS.instances_path, '_base')
- if not os.path.exists(base_dir):
- os.mkdir(base_dir)
- os.chmod(base_dir, 0777)
- base = os.path.join(base_dir, str(kwargs[key]))
- if not os.path.exists(base):
- kwargs['target'] = base
- retrieve_fn(*args, **kwargs)
- if kwargs.get('cow'):
- utils.execute('qemu-img create -f qcow2 -o '
- 'cluster_size=2M,backing_file=%s %s'
- % (base, target))
- else:
- utils.execute('cp %s %s' % (base, target))
- else:
+ base_dir = os.path.join(FLAGS.instances_path, '_base')
+ if not os.path.exists(base_dir):
+ os.mkdir(base_dir)
+ os.chmod(base_dir, 0777)
+ base = os.path.join(base_dir, str(kwargs[key]))
+ if not os.path.exists(base):
+ kwargs['target'] = base
retrieve_fn(*args, **kwargs)
+ if kwargs.get('cow'):
+ utils.execute('qemu-img create -f qcow2 -o '
+ 'cluster_size=2M,backing_file=%s %s'
+ % (base, target))
+ else:
+ utils.execute('cp %s %s' % (base, target))
_wrap.func_name = retrieve_fn.func_name
return _wrap
return _decorator
@@ -447,36 +457,21 @@ class LibvirtConnection(object):
return self._dump_file(fpath)
- def _get_image(self, retrieve_fn, key, target, *args, **kwargs):
- if not os.path.exists(target):
- if FLAGS.use_cow_images:
- base_dir = os.path.join(FLAGS.instances_path, '_base')
- if not os.path.exists(base_dir):
- os.mkdir(base_dir)
- os.chmod(base_dir, 0777)
- base = os.path.join(base_dir, kwargs[key])
- if not os.path.exists(base):
- retrieve_fn(target=base, *args, **kwargs)
- utils.execute('qemu-img create -f qcow2 -o '
- 'cluster_size=2M,backing_file=%s %s'
- % (base, target))
- else:
- retrieve_fn(target=base, *args, **kwargs)
-
- @wrap_cow_image('image_id')
+ @wrap_image_cache('image_id')
def _fetch_image(self, target, image_id, user, project,
- size=None, **kwargs):
+ size=None, cow=False):
+ """Grab image and optionally attempt to resize it"""
images.fetch(image_id, target, user, project)
- # TODO(vish): resize filesystem
if size:
disk.extend(target, size)
- @wrap_cow_image('local_gb')
- def _create_local(self, target, local_gb):
+ @wrap_image_cache('local_gb')
+ def _create_local(self, target, local_gb, cow=False):
+ """Create a blank image of specified size"""
last_mb = local_gb * 1024 - 1
- utils.execute('dd if=/dev/zero of=%s bs=1M count=1'
+ utils.execute('dd if=/dev/zero of=%s bs=1M count=1 '
'seek=%s' % (target, last_mb))
- # TODO(vish): format disk
+ # TODO(vish): should we format disk by default?
def _create_image(self, inst, libvirt_xml, prefix='', disk_images=None):
# syntactic nicety
@@ -528,12 +523,13 @@ class LibvirtConnection(object):
user=user,
project=project,
size=size,
- cow=True)
+ cow=FLAGS.use_cow_images)
type_data = instance_types.INSTANCE_TYPES[inst['instance_type']]
if type_data['local_gb']:
self._create_local(target=basepath('local'),
- local_gb=type_data['local_gb'])
+ local_gb=type_data['local_gb'],
+ cow=FLAGS.use_cow_images)
# 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
@@ -564,7 +560,8 @@ class LibvirtConnection(object):
inst['name'], inst.image_id)
try:
disk.inject_data(basepath('disk'), key, net,
- partition=target_partition)
+ partition=target_partition,
+ nbd=FLAGS.use_cow_images)
except Exception as e:
# This could be a windows image, or a vmdk format disk
logging.exception('test')