def verify(self, host_src, path_src, host_dst, path_dst, gateway=None): """ Verification that the file has been copied correctly. :param data: The dictionary with necessary information :return: True or False """ src_runner = self.runner(host_src, 'src', gateway) dst_runner = self.runner(host_dst, 'dst', gateway) src_size = files.remote_file_size(src_runner, path_src) dst_size = files.remote_file_size(dst_runner, path_dst) if src_size != dst_size: LOG.warning("The sizes of '%s' (%s) and '%s' (%s) are mismatch", path_src, sizeof_format.sizeof_fmt(src_size), path_dst, sizeof_format.sizeof_fmt(dst_size)) return False if CONF.migrate.copy_with_md5_verification: LOG.info("Running md5 checksum calculation on the file '%s' with " "size %s on host '%s'", path_src, sizeof_format.sizeof_fmt(src_size), host_src) src_md5 = files.remote_md5_sum(src_runner, path_src) LOG.info("Running md5 checksum calculation on the file '%s' with " "size %s on host '%s'", path_dst, sizeof_format.sizeof_fmt(dst_size), host_dst) dst_md5 = files.remote_md5_sum(dst_runner, path_dst) if src_md5 != dst_md5: LOG.warning("The md5 checksums of '%s' (%s) and '%s' (%s) are " "mismatch", path_src, src_md5, path_dst, dst_md5) return False return True
def copy(self, context, source_object, destination_object): src_user = context.cfg.src.ssh_user dst_user = context.cfg.dst.ssh_user src_host = source_object.host dst_host = destination_object.host rr = remote_runner.RemoteRunner(src_host, src_user) ssh_opts = ('-o UserKnownHostsFile=/dev/null ' '-o StrictHostKeyChecking=no') try: progress_view = "" if files.is_installed(rr, "pv"): src_file_size = files.remote_file_size(rr, source_object.path) progress_view = "pv --size {size} --progress | ".format( size=src_file_size) copy = ("dd if={src_file} | {progress_view} " "ssh {ssh_opts} {dst_user}@{dst_host} " "'dd of={dst_device}'") rr.run( copy.format(src_file=source_object.path, dst_user=dst_user, dst_host=dst_host, ssh_opts=ssh_opts, dst_device=destination_object.path, progress_view=progress_view)) except remote_runner.RemoteExecutionError as e: msg = "Cannot copy {src_object} to {dst_object}: {error}" msg = msg.format(src_object=source_object, dst_object=destination_object, error=e.message) raise CopyFailed(msg)
def copy(self, context, source_object, destination_object): src_user = context.cfg.src.ssh_user dst_user = context.cfg.dst.ssh_user src_host = source_object.host dst_host = destination_object.host rr = remote_runner.RemoteRunner(src_host, src_user) ssh_opts = ('-o UserKnownHostsFile=/dev/null ' '-o StrictHostKeyChecking=no') try: progress_view = "" if files.is_installed(rr, "pv"): src_file_size = files.remote_file_size(rr, source_object.path) progress_view = "pv --size {size} --progress | ".format( size=src_file_size) copy = ("dd if={src_file} | {progress_view} " "ssh {ssh_opts} {dst_user}@{dst_host} " "'dd of={dst_device}'") rr.run(copy.format(src_file=source_object.path, dst_user=dst_user, dst_host=dst_host, ssh_opts=ssh_opts, dst_device=destination_object.path, progress_view=progress_view)) except remote_runner.RemoteExecutionError as e: msg = "Cannot copy {src_object} to {dst_object}: {error}" msg = msg.format(src_object=source_object, dst_object=destination_object, error=e.message) raise CopyFailed(msg)
def restore_image(self, image_id, host, filename): """ Processing image file: copy from source to destination, create glance image :param image_id: image ID from source :param image_host: host of image from source :param diff: diff file of root disk for instance :return: new image if image is created """ LOG.debug('Processing an image %s from host %s and filename %s', image_id, host, filename) image_file_info = self.src_cloud.qemu_img.get_info(filename, host) image_resource = self.dst_cloud.resources[utils.IMAGE_RESOURCE] runner = remote_runner.RemoteRunner(host, self.cfg.src.ssh_user, self.cfg.src.ssh_sudo_password, True) file_size = files.remote_file_size(runner, filename) with files.RemoteStdout( host, self.cfg.src.ssh_user, 'dd if={filename}', filename=image_file_info.backing_filename) as f: fp = file_proxy.FileProxy(f.stdout, name='image %s' % image_id, size=file_size) new_image = image_resource.create_image( id=image_id, name='restored image %s from host %s' % (image_id, host), container_format='bare', disk_format=image_file_info.format, is_public=True, data=fp) return new_image
def volume_size(self, cloud, path): """ Get size of vol_file in bytes. :return: int """ runner = _remote_runner(cloud) return files.remote_file_size(runner, path)
def verify(self, host_src, path_src, host_dst, path_dst, gateway=None): """ Verification that the file has been copied correctly. :param data: The dictionary with necessary information :return: True or False """ src_runner = self.runner(host_src, 'src', gateway) dst_runner = self.runner(host_dst, 'dst', gateway) src_size = files.remote_file_size(src_runner, path_src) dst_size = files.remote_file_size(dst_runner, path_dst) if src_size != dst_size: LOG.warning("The sizes of '%s' (%s) and '%s' (%s) are mismatch", path_src, sizeof_format.sizeof_fmt(src_size), path_dst, sizeof_format.sizeof_fmt(dst_size)) return False if CONF.migrate.copy_with_md5_verification: LOG.info( "Running md5 checksum calculation on the file '%s' with " "size %s on host '%s'", path_src, sizeof_format.sizeof_fmt(src_size), host_src) src_md5 = files.remote_md5_sum(src_runner, path_src) LOG.info( "Running md5 checksum calculation on the file '%s' with " "size %s on host '%s'", path_dst, sizeof_format.sizeof_fmt(dst_size), host_dst) dst_md5 = files.remote_md5_sum(dst_runner, path_dst) if src_md5 != dst_md5: LOG.warning( "The md5 checksums of '%s' (%s) and '%s' (%s) are " "mismatch", path_src, src_md5, path_dst, dst_md5) return False return True
def copy(self, context, source_object, destination_object): cfg_src = context.cfg.src cfg_dst = context.cfg.dst src_user = cfg_src.ssh_user dst_user = cfg_dst.ssh_user src_host = source_object.host dst_host = destination_object.host rr_src = remote_runner.RemoteRunner(src_host, src_user, sudo=True, password=cfg_src.ssh_sudo_password) rr_dst = remote_runner.RemoteRunner(dst_host, dst_user, sudo=True, password=cfg_dst.ssh_sudo_password) ssh_opts = ('-o UserKnownHostsFile=/dev/null ' '-o StrictHostKeyChecking=no') # Choose auxiliary port for SSH tunnel aux_port_start, aux_port_end = \ context.cfg.migrate.ssh_transfer_port.split('-') aux_port = random.randint(int(aux_port_start), int(aux_port_end)) session_name = self._generate_session_name() try: progress_view = "" if files.is_installed(rr_src, "pv"): src_file_size = files.remote_file_size(rr_src, source_object.path) progress_view = "pv --size {size} --progress | ".format( size=src_file_size) # First step: prepare netcat listening on aux_port on dst and # forwarding all the data to block device rr_dst.run( 'screen -S {session_name} -d -m /bin/bash -c ' '\'nc -l {aux_port} | dd of={dst_device} bs=64k\'; ' 'sleep 1', session_name=session_name, aux_port=aux_port, dst_device=destination_object.path) # Second step: create SSH tunnel between source and destination rr_src.run( 'screen -S {session_name} -d -m ssh {ssh_opts} -L' ' {aux_port}:127.0.0.1:{aux_port} ' '{dst_user}@{dst_host}; sleep 1', session_name=session_name, ssh_opts=ssh_opts, aux_port=aux_port, dst_user=dst_user, dst_host=dst_host) # Third step: push data through the tunnel rr_src.run( '/bin/bash -c \'dd if={src_file} bs=64k | ' '{progress_view} nc 127.0.0.1 {aux_port}\'', aux_port=aux_port, progress_view=progress_view, src_file=source_object.path) except remote_runner.RemoteExecutionError as e: msg = "Cannot copy {src_object} to {dst_object}: {error}" msg = msg.format(src_object=source_object, dst_object=destination_object, error=e.message) raise CopyFailed(msg) finally: try: rr_src.run('screen -X -S {session_name} quit || true', session_name=session_name) rr_dst.run('screen -X -S {session_name} quit || true', session_name=session_name) except remote_runner.RemoteExecutionError: LOG.error('Failed to close copy sessions', exc_info=True)
def copy(self, context, source_object, destination_object): cfg_src = context.cfg.src cfg_dst = context.cfg.dst src_user = cfg_src.ssh_user dst_user = cfg_dst.ssh_user src_host = source_object.host dst_host = destination_object.host rr_src = remote_runner.RemoteRunner(src_host, src_user, sudo=True, password=cfg_src.ssh_sudo_password) rr_dst = remote_runner.RemoteRunner(dst_host, dst_user, sudo=True, password=cfg_dst.ssh_sudo_password) ssh_opts = ('-o UserKnownHostsFile=/dev/null ' '-o StrictHostKeyChecking=no') # Choose auxiliary port for SSH tunnel aux_port_start, aux_port_end = \ context.cfg.migrate.ssh_transfer_port.split('-') aux_port = random.randint(int(aux_port_start), int(aux_port_end)) session_name = self._generate_session_name() try: progress_view = "" if files.is_installed(rr_src, "pv"): src_file_size = files.remote_file_size(rr_src, source_object.path) progress_view = "pv --size {size} --progress | ".format( size=src_file_size) # First step: prepare netcat listening on aux_port on dst and # forwarding all the data to block device rr_dst.run('screen -S {session_name} -d -m /bin/bash -c ' '\'nc -l {aux_port} | dd of={dst_device}\'; sleep 1', session_name=session_name, aux_port=aux_port, dst_device=destination_object.path) # Second step: create SSH tunnel between source and destination rr_src.run('screen -S {session_name} -d -m ssh {ssh_opts} -L' ' {aux_port}:127.0.0.1:{aux_port} ' '{dst_user}@{dst_host}; sleep 1', session_name=session_name, ssh_opts=ssh_opts, aux_port=aux_port, dst_user=dst_user, dst_host=dst_host) # Third step: push data through the tunnel rr_src.run('/bin/bash -c \'dd if={src_file} | {progress_view} ' 'nc 127.0.0.1 {aux_port}\'', aux_port=aux_port, progress_view=progress_view, src_file=source_object.path) except remote_runner.RemoteExecutionError as e: msg = "Cannot copy {src_object} to {dst_object}: {error}" msg = msg.format(src_object=source_object, dst_object=destination_object, error=e.message) raise CopyFailed(msg) finally: try: rr_src.run('screen -X -S {session_name} quit || true', session_name=session_name) rr_dst.run('screen -X -S {session_name} quit || true', session_name=session_name) except remote_runner.RemoteExecutionError: LOG.error('Failed to close copy sessions', exc_info=True)