diff --git a/ccnode/kvm.py b/ccnode/kvm.py index 5cde5e1513c555d749bbd594d21ac7c94fb875ba..8a36ebeee3f514010abe42cbd6cf3d0c1299f47e 100644 --- a/ccnode/kvm.py +++ b/ccnode/kvm.py @@ -21,7 +21,6 @@ class KvmHypervisor(LibvirtHypervisor): super(KvmHypervisor, self).__init__('kvm') self.hv_type = 'KVM/QEMU' - def __new__(cls, *args, **kwargs): ''' .. note:: @@ -34,147 +33,3 @@ class KvmHypervisor(LibvirtHypervisor): cls._instance = super(KvmHypervisor, cls).__new__(cls, *args, **kwargs) return cls._instance - - - def start_vm(self, name, start_options=DEFAULT_VM_START): - ''' - Starts the vm identified by name - - :param name: The name of the virtual machine - :type nane: :class:`str` - - :param start_options: Options flags while starting vm - :type start_options: TODO reference to constants - - ''' - for vm in self._vm_list: - if vm.get_name() == name: - vm.start() - return - raise VMError('Virtual Machine %s not found: '% name) - - def stop_vm(self, name, force=False): - ''' - Poweroff the specifed vm with the specified options - - :param name: the name of the vm - :type name: :class:`str` - ''' - for vm in self._vm_list: - if vm.get_name() == name: - vm.force_poweroff() if force else vm.shutdown() - return - raise VMError('Virtual Machine %s not found: ' % name) - - def suspend_vm(self, name): - ''' - Suspends the specifed vm - - :param name: the name of the vm - :type name: :class:`str` - ''' - for vm in self._vm_list: - if vm.get_name() == name: - vm.suspend() - return - raise VMError('Virtual machine %s not found: ' % name) - - def resume_vm(self, name): - ''' - Resumes the specifed vm - - :param name: the name of the vm - :type name: :class:`str` - ''' - for vm in self._vm_list: - if vm.get_name() == name: - vm.resume() - return - raise VMError('Virtual machine %s not found: ' % name) - - - def local_execute(self, command): - ''' - Excecutes the command given in command on the local host - Returns a tuple with (stdout, stderr) from the process that has - been executed - - ..warning:: This is a dangerous function as it gives the command given - in paramter to a shell prompt, anything can then be executed locally - - ..warning:: If the command given is a long processing one, this may be - a deadlock to the node be carefull ! - - :param command: the command to execute with it's arguments - :type command: :class:`str` - ''' - #FIXME: stop using shell=true and parse arguments with shlex.split() - p = subprocess.Popen(command, shell=True, - 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 - - def get_storage_conf(self): - raise NotImplementedError - - def get_storage_stats(self): - raise NotImplementedError - diff --git a/ccnode/libvirtwrapper.py b/ccnode/libvirtwrapper.py index 0d4d2e4a80b83e654c4effcbf7d8c2ed35ec43b9..c61fc8f614bad6d6b108422a10c23427e72c2281 100644 --- a/ccnode/libvirtwrapper.py +++ b/ccnode/libvirtwrapper.py @@ -350,6 +350,147 @@ class LibvirtHypervisor(Hypervisor): def get_status(self): raise NotImplementedError() + + def start_vm(self, name, start_options=DEFAULT_VM_START): + ''' + Starts the vm identified by name + + :param name: The name of the virtual machine + :type nane: :class:`str` + + :param start_options: Options flags while starting vm + :type start_options: TODO reference to constants + + ''' + for vm in self._vm_list: + if vm.get_name() == name: + vm.start() + return + raise VMError('Virtual Machine %s not found: '% name) + + def stop_vm(self, name, force=False): + ''' + Poweroff the specifed vm with the specified options + + :param name: the name of the vm + :type name: :class:`str` + ''' + for vm in self._vm_list: + if vm.get_name() == name: + vm.force_poweroff() if force else vm.shutdown() + return + raise VMError('Virtual Machine %s not found: ' % name) + + def suspend_vm(self, name): + ''' + Suspends the specifed vm + + :param name: the name of the vm + :type name: :class:`str` + ''' + for vm in self._vm_list: + if vm.get_name() == name: + vm.suspend() + return + raise VMError('Virtual machine %s not found: ' % name) + + def resume_vm(self, name): + ''' + Resumes the specifed vm + + :param name: the name of the vm + :type name: :class:`str` + ''' + for vm in self._vm_list: + if vm.get_name() == name: + vm.resume() + return + raise VMError('Virtual machine %s not found: ' % name) + + def local_execute(self, command): + ''' + Excecutes the command given in command on the local host + Returns a tuple with (stdout, stderr) from the process that has + been executed + + ..warning:: This is a dangerous function as it gives the command given + in paramter to a shell prompt, anything can then be executed locally + + ..warning:: If the command given is a long processing one, this may be + a deadlock to the node be carefull ! + + :param command: the command to execute with it's arguments + :type command: :class:`str` + ''' + #FIXME: stop using shell=true and parse arguments with shlex.split() + p = subprocess.Popen(command, shell=True, + 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 + + def get_storage_conf(self): + raise NotImplementedError + + def get_storage_stats(self): + raise NotImplementedError #TODO: finish storage class, make tests, diff --git a/debian/changelog b/debian/changelog index 30d4eed9fa94e643723fb7bd2aa39706ecccf26d..606f24c467d000ba0bb3e8d5e9249578206592e1 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +cc-node (6) unstable; urgency=low + + * Bug fix + * Proper release with newer init scripts + + -- Thibault VINCENT Mon, 27 Dec 2010 17:12:40 +0100 + cc-node (5-2) unstable; urgency=low * Fix configuration option for HV detection