Example #1
0
    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
Example #2
0
    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)
Example #3
0
    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
Example #5
0
    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)
Example #6
0
    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 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
Example #8
0
    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)
Example #9
0
    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)