diff --git a/ccnode/kvm.py b/ccnode/kvm.py index 99c269dc55abd7a1143e08d5559b8a598c16ab56..5cde5e1513c555d749bbd594d21ac7c94fb875ba 100644 --- a/ccnode/kvm.py +++ b/ccnode/kvm.py @@ -7,6 +7,7 @@ Two entites belong to this module: a Kvm hypervisor or a Kvm virtual machine from libvirtwrapper import * from exceptions import * import subprocess +import hashlib class KvmHypervisor(LibvirtHypervisor): @@ -109,13 +110,65 @@ class KvmHypervisor(LibvirtHypervisor): ''' #FIXME: stop using shell=true and parse arguments with shlex.split() p = subprocess.Popen(command, shell=True, - bufsize = -1, + bufsize=-1, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE) result = p.communicate() return result + def export_vm(self, name, target, port): + ''' + Migrates the given vm (name) to (target) hypervisor which is already + waiting for the migration + + :param name: the name of the vm + :type name: :class:`str` + :param target: the destination hypervisor + :type target: :class:`str` + :param port: the port on the destination to use for the transfer + :type port: :class:`str` + ''' + # We will be using subprocess to pipe the volume using dd in a netcat + # connection to the destination + # We send a hash of the volume before so that the target can checksum + # and validate integrity. + # This algorithm is just a proof of concept of the cold migration + # process it is likely that it does not anticipates some problems + + buff = 1024 * 1024 * 10 #10 Mo + path = [vm.get_disk_path() for vm in self._vm_list + if vm.get_name() == name].pop() + dd_cmd = ['dd', 'if=%s' % path] + + dd_process = subprocess.Popen(dd_cmd, bufsize=-1, + stdout=subprocess.PIPE) + nc_process = subprocess.Popen(['nc', target, port], + bufsize=-1, + stdin=subprocess.PIPE, + stdout=subprocess.PIPE, + stderr=subprocess.PIPE) + #We send dd output to nc + dd_out = dd_process.stdout + nc_in = nc_process.stdin + m = hashlib.md5() + print 'going to pipe loop' + try: + read = dd_out.read(buff) + except Exception as err: + raise IOError('error while reading dd process output %s' % err) + try: + while len(read) != 0: + print len(read) + m.update(read) + nc_in.write(read) + nc_in.flush() + read = dd_out.read(buff) + except Exception as err: + raise IOError('Error occured while writing to nc process %s' % err) + nc_in.close() + print m.hexdigest() + def get_network_conf(self): raise NotImplementedError