Skip to content

Instantly share code, notes, and snippets.

@wenjianhn
Created January 7, 2013 03:01
Show Gist options
  • Save wenjianhn/4471994 to your computer and use it in GitHub Desktop.
Save wenjianhn/4471994 to your computer and use it in GitHub Desktop.
patch against a5dc49c1e2d3173a0d336beb260bacad7441d99a
commit 9ec031bdee4633a3386cddfca791330680834b69
Author: Jian Wen <[email protected]>
Date: Fri Sep 14 17:42:21 2012 +0800
libvirt: Add copying image via rsync without ssh support
Change-Id: I4f4ec1b8466a4e8a8337f56f60473efc3b6bac00
diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py
index 41bbd2d..281d34b 100644
--- a/nova/virt/libvirt/driver.py
+++ b/nova/virt/libvirt/driver.py
@@ -188,6 +188,19 @@ libvirt_opts = [
default='$instances_path/snapshots',
help='Location where libvirt driver will store snapshots '
'before uploading them to image service'),
+ cfg.BoolOpt('libvirt_copy_image_use_rsync_daemon',
+ default=False,
+ help='Use rsync daemon to copy image from local to dest.'
+ 'rsync without ssh'),
+ cfg.StrOpt('libvirt_rsync_module_name',
+ default='nova',
+ help='Module name of the rsync server for nova'),
+ cfg.StrOpt('libvirt_rsync_user',
+ default='nova',
+ help='The rsync user name'),
+ cfg.StrOpt('libvirt_rsync_password',
+ default='password',
+ help='Password of the rsync user'),
]
FLAGS = flags.FLAGS
@@ -335,6 +348,9 @@ class LibvirtDriver(driver.ComputeDriver):
'%(major)i.%(minor)i.%(micro)i or greater.') %
locals())
+ if FLAGS.libvirt_copy_image_use_rsync_daemon:
+ os.environ['RSYNC_PASSWORD'] = FLAGS.libvirt_rsync_password
+
def _get_connection(self):
if not self._wrapped_conn or not self._test_connection():
LOG.debug(_('Connecting to libvirt: %s'), self.uri)
@@ -2795,7 +2811,12 @@ class LibvirtDriver(driver.ComputeDriver):
dest = None
utils.execute('mkdir', '-p', inst_base)
else:
- utils.execute('ssh', dest, 'mkdir', '-p', inst_base)
+ if FLAGS.libvirt_copy_image_use_rsync_daemon:
+ dest_dir_uri = libvirt_utils.get_rsync_inst_uri(dest,
+ instance)
+ utils.execute('rsync', inst_base_resize, dest_dir_uri)
+ else:
+ utils.execute('ssh', dest, 'mkdir', '-p', inst_base)
for info in disk_info:
# assume inst_base == dirname(info['path'])
img_path = info['path']
@@ -2810,17 +2831,41 @@ class LibvirtDriver(driver.ComputeDriver):
if same_host:
utils.execute('mv', tmp_path, img_path)
else:
- libvirt_utils.copy_image(tmp_path, img_path, host=dest)
+ if FLAGS.libvirt_copy_image_use_rsync_daemon:
+ libvirt_utils.rsync_image(tmp_path, fname, dest,
+ instance)
+ else:
+ libvirt_utils.copy_image(tmp_path,
+ img_path, host=dest)
+
utils.execute('rm', '-f', tmp_path)
else: # raw or qcow2 with no backing file
- libvirt_utils.copy_image(from_path, img_path, host=dest)
+ if FLAGS.libvirt_copy_image_use_rsync_daemon:
+ libvirt_utils.copy_image(from_path, img_path,
+ host=dest)
+ else:
+ libvirt_utils.rsync_image(tmp_path, fname, dest,
+ instance)
except Exception, e:
try:
if os.path.exists(inst_base_resize):
utils.execute('rm', '-rf', inst_base)
- utils.execute('mv', inst_base_resize, inst_base)
- utils.execute('ssh', dest, 'rm', '-rf', inst_base)
+ if FLAGS.libvirt_copy_image_use_rsync_daemon:
+ uri = libvirt_utils.get_rsync_uri(dest)
+ inst_path = "%s/" % FLAGS.instances_path
+ if dest != None:
+ utils.execute('rsync', '-r', '--delete',
+ "--include=%s/" % instance['name'],
+ "--include=%s/*" % instance['name'],
+ "--exclude=*",
+ inst_path,
+ uri)
+ utils.execute('mv', inst_base_resize, inst_base)
+ else:
+ # # TODO(wenjianhn): bug: dest is None
+ utils.execute('mv', inst_base_resize, inst_base)
+ utils.execute('ssh', dest, 'rm', '-rf', inst_base)
except Exception:
pass
raise e
diff --git a/nova/virt/libvirt/utils.py b/nova/virt/libvirt/utils.py
index 2dc0bfd..1cf7fec 100644
--- a/nova/virt/libvirt/utils.py
+++ b/nova/virt/libvirt/utils.py
@@ -209,6 +209,29 @@ def get_disk_backing_file(path):
return backing_file
+def get_rsync_uri(host):
+ user = FLAGS.libvirt_rsync_user
+ module_name = FLAGS.libvirt_rsync_module_name
+ uri = 'rsync://%s@%s/%s/' % (user, host, module_name)
+
+ return uri
+
+
+def get_rsync_inst_uri(host, instance):
+ base = get_rsync_uri(host)
+ uri = "%s%s/" % (base, instance['name'])
+
+ return uri
+
+
+def rsync_image(src, fname, host, instance):
+ rsync_uri = get_rsync_inst_uri(host, instance)
+ dest = "%s%s" % (rsync_uri, fname)
+
+ execute('rsync', '--sparse', '--compress', '--dry-run', src, dest)
+ execute('rsync', '--sparse', '--compress', src, dest)
+
+
def copy_image(src, dest, host=None):
"""Copy a disk image to an existing directory
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment