def _prepare_required_mounts(scratch_dir, mounts_dir, mount_points, xfs_info):
    result = {
        mountpoint: mounting.NullMount(_mount_dir(mounts_dir, mountpoint))
        for mountpoint in mount_points
    }
    if not xfs_info.mountpoints_without_ftype:
        return result

    space_needed = _overlay_disk_size() * len(
        xfs_info.mountpoints_without_ftype)
    disk_images_directory = os.path.join(scratch_dir, 'diskimages')

    # Ensure we cleanup old disk images before we check for space contraints.
    run(['rm', '-rf', disk_images_directory])
    _create_diskimages_dir(scratch_dir, disk_images_directory)
    _ensure_enough_diskimage_space(space_needed, scratch_dir)

    for mountpoint in xfs_info.mountpoints_without_ftype:
        if mountpoint in mount_points:
            image = _create_mount_disk_image(disk_images_directory, mountpoint)
            result[mountpoint] = mounting.LoopMount(source=image,
                                                    target=_mount_dir(
                                                        mounts_dir,
                                                        mountpoint))
    return result
def create_source_overlay(mounts_dir,
                          scratch_dir,
                          xfs_info,
                          storage_info,
                          mount_target=None):
    """
    Context manager that prepares the source system overlay and yields the mount.
    """
    api.current_logger().debug(
        'Creating source overlay in {scratch_dir} with mounts in {mounts_dir}'.
        format(scratch_dir=scratch_dir, mounts_dir=mounts_dir))
    try:
        _create_mounts_dir(scratch_dir, mounts_dir)
        mounts = _prepare_required_mounts(scratch_dir, mounts_dir,
                                          _get_mountpoints(storage_info),
                                          xfs_info)
        with mounts.pop('/') as root_mount:
            with mounting.OverlayMount(
                    name='system_overlay', source='/',
                    workdir=root_mount.target) as root_overlay:
                if mount_target:
                    target = mounting.BindMount(source=root_overlay.target,
                                                target=mount_target)
                else:
                    target = mounting.NullMount(target=root_overlay.target)
                with target:
                    with _build_overlay_mount(root_overlay, mounts) as overlay:
                        with _mount_dnf_cache(overlay.target):
                            yield overlay
    except Exception:
        cleanup_scratch(scratch_dir, mounts_dir)
        raise
Ejemplo n.º 3
0
    def process(self):
        if not architecture.matches_architecture(architecture.ARCH_S390X):
            return
        userspace = next(self.consume(TargetUserSpaceInfo), None)
        if not userspace:
            # actually this should not happen, but in such case, we want to still
            # rather continue even if we boot into the old kernel, but in such
            # case, people will have to do manual actions.
            # NOTE: it is really just hypothetical
            self.log_error(
                'TargetUserSpaceInfo is missing. Cannot execute zipl-switch-to-blscfg'
                ' to convert the zipl configuration to BLS.')
            raise StopActorExecutionError(
                'GENERAL FAILURE: Input data for the actor are missing.')

        # replace the original boot directory inside the container by the host one
        # - as we cannot use zipl* pointing anywhere else than default directory
        # - no, --bls-directory is not solution
        with mounting.BindMount(source='/boot',
                                target=os.path.join(userspace.path, 'boot')):
            userspace_zipl_conf = os.path.join(userspace.path, 'etc',
                                               'zipl.conf')
            if os.path.exists(userspace_zipl_conf):
                os.remove(userspace_zipl_conf)
            with mounting.NullMount(target=userspace.path) as userspace:
                with userspace.nspawn() as context:
                    context.copy_to('/etc/zipl.conf', '/etc/zipl.conf')
                    # zipl needs this one as well
                    context.copy_to('/etc/machine-id', '/etc/machine-id')
                    try:
                        context.call(['/usr/sbin/zipl-switch-to-blscfg'])
                        if filecmp.cmp('/etc/zipl.conf', userspace_zipl_conf):
                            # When the files are same, zipl failed - see the switch script
                            raise OSError(
                                'Failed to convert the ZIPL configuration to BLS.'
                            )
                        context.copy_from('/etc/zipl.conf', '/etc/zipl.conf')
                    except OSError as e:
                        self.log.error(
                            'Could not call zipl-switch-to-blscfg command.',
                            exc_info=True)
                        raise StopActorExecutionError(
                            message='Failed to execute zipl-switch-to-blscfg.',
                            details={'details': str(e)})
                    except CalledProcessError as e:
                        self.log.error(
                            'zipl-switch-to-blscfg execution failed,',
                            exc_info=True)
                        raise StopActorExecutionError(
                            message=
                            'zipl-switch-to-blscfg execution failed with non zero exit code.',
                            details={
                                'details': str(e),
                                'stdout': e.stdout,
                                'stderr': e.stderr
                            })
Ejemplo n.º 4
0
def _prepare_mounts(mounts_dir, scratch_dir, cleanup, detach, xfs_present):
    """
    A context manager function that prepares the scratch userspace and creates a mounting target directory. In case of
    XFS with ftype=0 it will trigger the creation of the disk image and mounts it and ensure the cleanup after leaving
    the context.
    """
    if cleanup:
        cleanup_scratch(scratch_dir, mounts_dir)
    _create_mounts_dir(scratch_dir=scratch_dir, mounts_dir=mounts_dir)
    if xfs_present:
        mount = mounting.LoopMount(source=_create_mount_disk_image(
            scratch_dir, mounts_dir),
                                   target=mounts_dir,
                                   config=mounting.MountConfig.MountOnly)
    else:
        mount = mounting.NullMount(target=mounts_dir)
    with mount:
        yield mount
Ejemplo n.º 5
0
def _prepare_required_mounts(scratch_dir, mounts_dir, mount_points, xfs_info):
    result = {
        mount_point.fs_file:
        mounting.NullMount(_mount_dir(mounts_dir, mount_point.fs_file))
        for mount_point in mount_points
    }

    if not xfs_info.mountpoints_without_ftype:
        return result

    space_needed = _overlay_disk_size() * len(
        xfs_info.mountpoints_without_ftype)
    disk_images_directory = os.path.join(scratch_dir, 'diskimages')

    # Ensure we cleanup old disk images before we check for space contraints.
    run(['rm', '-rf', disk_images_directory])
    _create_diskimages_dir(scratch_dir, disk_images_directory)
    _ensure_enough_diskimage_space(space_needed, scratch_dir)

    mount_names = [mount_point.fs_file for mount_point in mount_points]

    # TODO(pstodulk): this (adding rootfs into the set always) is hotfix for
    # bz #1911802 (not ideal one..). The problem occurs one rootfs is ext4 fs,
    # but /var/lib/leapp/... is under XFS without ftype; In such a case we can
    # see still the very same problems as before. But letting you know that
    # probably this is not the final solution, as we could possibly see the
    # same problems on another partitions too (needs to be tested...). However,
    # it could fit for now until we provide the complete solution around XFS
    # workarounds (including management of required spaces for virtual FSs per
    # mountpoints - without that, we cannot fix this properly)
    for mountpoint in set(xfs_info.mountpoints_without_ftype + ['/']):
        if mountpoint in mount_names:
            image = _create_mount_disk_image(disk_images_directory, mountpoint)
            result[mountpoint] = mounting.LoopMount(source=image,
                                                    target=_mount_dir(
                                                        mounts_dir,
                                                        mountpoint))
    return result
Ejemplo n.º 6
0
def _overlay_if(condition, name, source, workdir):
    if condition:
        return mounting.OverlayMount(name=name, source=source, workdir=workdir)
    return mounting.NullMount(target=source)