Ejemplo n.º 1
0
def _find_existing_installations(devicetree):
    """Find existing GNU/Linux installations on devices from the device tree.

    :param devicetree: a device tree to find existing installations in
    :return: roots of all found installations
    """
    if not os.path.exists(util.getTargetPhysicalRoot()):
        blivet_util.makedirs(util.getTargetPhysicalRoot())

    sysroot = util.getSysroot()
    roots = []
    direct_devices = (dev for dev in devicetree.devices if dev.direct)
    for device in direct_devices:
        if not device.format.linux_native or not device.format.mountable or \
           not device.controllable:
            continue

        try:
            device.setup()
        except Exception:  # pylint: disable=broad-except
            log_exception_info(log.warning, "setup of %s failed", [device.name])
            continue

        options = device.format.options + ",ro"
        try:
            device.format.mount(options=options, mountpoint=sysroot)
        except Exception:  # pylint: disable=broad-except
            log_exception_info(log.warning, "mount of %s as %s failed", [device.name, device.format.type])
            blivet_util.umount(mountpoint=sysroot)
            continue

        if not os.access(sysroot + "/etc/fstab", os.R_OK):
            blivet_util.umount(mountpoint=sysroot)
            device.teardown()
            continue

        try:
            (architecture, product, version) = get_release_string()
        except ValueError:
            name = _("Linux on %s") % device.name
        else:
            # I'd like to make this finer grained, but it'd be very difficult
            # to translate.
            if not product or not version or not architecture:
                name = _("Unknown Linux")
            elif "linux" in product.lower():
                name = _("%(product)s %(version)s for %(arch)s") % \
                    {"product": product, "version": version, "arch": architecture}
            else:
                name = _("%(product)s Linux %(version)s for %(arch)s") % \
                    {"product": product, "version": version, "arch": architecture}

        (mounts, swaps) = _parse_fstab(devicetree, chroot=sysroot)
        blivet_util.umount(mountpoint=sysroot)
        if not mounts and not swaps:
            # empty /etc/fstab. weird, but I've seen it happen.
            continue
        roots.append(Root(mounts=mounts, swaps=swaps, name=name))

    return roots
Ejemplo n.º 2
0
    def sysroot_test(self):
        self.assertEqual(util.getTargetPhysicalRoot(), "/mnt/sysimage")
        self.assertEqual(util.getSysroot(), "/mnt/sysimage")

        util.setSysroot("/what/ever")
        self.assertEqual(util.getTargetPhysicalRoot(), "/mnt/sysimage")
        self.assertEqual(util.getSysroot(), "/what/ever")

        util.setSysroot(None)
        self.assertEqual(util.getTargetPhysicalRoot(), "/mnt/sysimage")
        self.assertEqual(util.getSysroot(), "/mnt/sysimage")
Ejemplo n.º 3
0
    def mount_filesystems(self):
        root_path = util.getTargetPhysicalRoot()

        # Mount the root and the filesystems.
        self.fsset.mount_filesystems(root_path=root_path)

        # Set up the sysroot.
        util.setSysroot(root_path)
Ejemplo n.º 4
0
    def root_device(self):
        for path in ["/", util.getTargetPhysicalRoot()]:
            for device in self.devices:
                try:
                    mountpoint = device.format.mountpoint
                except AttributeError:
                    mountpoint = None

                if mountpoint == path:
                    return device
Ejemplo n.º 5
0
    def root_device(self):
        for path in ["/", util.getTargetPhysicalRoot()]:
            for device in self.devices:
                try:
                    mountpoint = device.format.mountpoint
                except AttributeError:
                    mountpoint = None

                if mountpoint == path:
                    return device
Ejemplo n.º 6
0
    def write(self):
        """Write the bootloader configuration and install the bootloader."""
        if self.skip_bootloader:
            return

        if self.update_only:
            self.update()
            return

        try:
            self.write_device_map()
            self.stage2_device.format.sync(root=util.getTargetPhysicalRoot())
            os.sync()
            self.install()
            os.sync()
            self.stage2_device.format.sync(root=util.getTargetPhysicalRoot())
        finally:
            self.write_config()
            os.sync()
            self.stage2_device.format.sync(root=util.getTargetPhysicalRoot())
Ejemplo n.º 7
0
    def write(self):
        """Write the bootloader configuration and install the bootloader."""
        if self.skip_bootloader:
            return

        if self.update_only:
            self.update()
            return

        try:
            self.write_device_map()
            self.stage2_device.format.sync(root=util.getTargetPhysicalRoot())
            os.sync()
            self.install()
            os.sync()
            self.stage2_device.format.sync(root=util.getTargetPhysicalRoot())
        finally:
            self.write_config()
            os.sync()
            self.stage2_device.format.sync(root=util.getTargetPhysicalRoot())
Ejemplo n.º 8
0
    def write(self):
        """ Write the bootloader configuration and install the bootloader. """
        if self.skip_bootloader:  # pylint: disable=no-member
            return

        if self.update_only:  # pylint: disable=no-member
            self.update()
            return

        try:
            os.sync()
            self.stage2_device.format.sync(root=util.getTargetPhysicalRoot())  # pylint: disable=no-member
            self.install()
        finally:
            self.write_config()  # pylint: disable=no-member
Ejemplo n.º 9
0
    def write(self):
        """ Write the bootloader configuration and install the bootloader. """
        if self.skip_bootloader:  # pylint: disable=no-member
            return

        if self.update_only:  # pylint: disable=no-member
            self.update()
            return

        try:
            os.sync()
            self.stage2_device.format.sync(root=util.getTargetPhysicalRoot()) # pylint: disable=no-member
            self.install()
        finally:
            self.write_config()  # pylint: disable=no-member
Ejemplo n.º 10
0
    def _copyBootloaderData(self):
        # Copy bootloader data files from the deployment
        # checkout to the target root.  See
        # https://bugzilla.gnome.org/show_bug.cgi?id=726757 This
        # happens once, at installation time.
        # extlinux ships its modules directly in the RPM in /boot.
        # For GRUB2, Anaconda installs device.map there.  We may need
        # to add other bootloaders here though (if they can't easily
        # be fixed to *copy* data into /boot at install time, instead
        # of shipping it in the RPM).
        is_efi = isinstance(self.storage.bootloader, EFIBase)
        physboot = util.getTargetPhysicalRoot() + '/boot'
        ostree_boot_source = util.getSysroot() + '/usr/lib/ostree-boot'
        if not os.path.isdir(ostree_boot_source):
            ostree_boot_source = util.getSysroot() + '/boot'
        for fname in os.listdir(ostree_boot_source):
            srcpath = os.path.join(ostree_boot_source, fname)
            destpath = os.path.join(physboot, fname)

            # We're only copying directories
            if not os.path.isdir(srcpath):
                continue

            # Special handling for EFI; first, we only want to copy
            # the data if the system is actually EFI (simulating grub2-efi
            # being installed).  Second, as it's a mount point that's
            # expected to already exist (so if we used copytree, we'd
            # traceback).  If it doesn't, we're not on a UEFI system,
            # so we don't want to copy the data.
            if fname == 'efi':
                if is_efi:
                    for subname in os.listdir(srcpath):
                        sub_srcpath = os.path.join(srcpath, subname)
                        sub_destpath = os.path.join(destpath, subname)
                        self._safeExecWithRedirect(
                            'cp', ['-r', '-p', sub_srcpath, sub_destpath])
            else:
                log.info("Copying bootloader data: " + fname)
                self._safeExecWithRedirect('cp',
                                           ['-r', '-p', srcpath, destpath])

            # Unfortunate hack, see https://github.com/rhinstaller/anaconda/issues/1188
            efi_grubenv_link = physboot + '/grub2/grubenv'
            if not is_efi and os.path.islink(efi_grubenv_link):
                os.unlink(efi_grubenv_link)
Ejemplo n.º 11
0
    def _copy_bootloader_data(self):
        # Copy bootloader data files from the deployment
        # checkout to the target root.  See
        # https://bugzilla.gnome.org/show_bug.cgi?id=726757 This
        # happens once, at installation time.
        # extlinux ships its modules directly in the RPM in /boot.
        # For GRUB2, Anaconda installs device.map there.  We may need
        # to add other bootloaders here though (if they can't easily
        # be fixed to *copy* data into /boot at install time, instead
        # of shipping it in the RPM).
        is_efi = isinstance(self.storage.bootloader, EFIBase)
        physboot = util.getTargetPhysicalRoot() + '/boot'
        ostree_boot_source = util.getSysroot() + '/usr/lib/ostree-boot'
        if not os.path.isdir(ostree_boot_source):
            ostree_boot_source = util.getSysroot() + '/boot'
        for fname in os.listdir(ostree_boot_source):
            srcpath = os.path.join(ostree_boot_source, fname)
            destpath = os.path.join(physboot, fname)

            # We're only copying directories
            if not os.path.isdir(srcpath):
                continue

            # Special handling for EFI; first, we only want to copy
            # the data if the system is actually EFI (simulating grub2-efi
            # being installed).  Second, as it's a mount point that's
            # expected to already exist (so if we used copytree, we'd
            # traceback).  If it doesn't, we're not on a UEFI system,
            # so we don't want to copy the data.
            if fname == 'efi':
                if is_efi:
                    for subname in os.listdir(srcpath):
                        sub_srcpath = os.path.join(srcpath, subname)
                        sub_destpath = os.path.join(destpath, subname)
                        self._safe_exec_with_redirect('cp',
                                                      ['-r', '-p', sub_srcpath, sub_destpath])
            else:
                log.info("Copying bootloader data: %s", fname)
                self._safe_exec_with_redirect('cp', ['-r', '-p', srcpath, destpath])

            # Unfortunate hack, see https://github.com/rhinstaller/anaconda/issues/1188
            efi_grubenv_link = physboot + '/grub2/grubenv'
            if not is_efi and os.path.islink(efi_grubenv_link):
                os.unlink(efi_grubenv_link)
Ejemplo n.º 12
0
    def create_swap_file(self, device, size):
        """Create and activate a swap file under storage root."""
        filename = "/SWAP"
        count = 0
        basedir = os.path.normpath(
            "%s/%s" % (util.getTargetPhysicalRoot(), device.format.mountpoint))
        while os.path.exists("%s/%s" % (basedir, filename)) or \
                self.devicetree.get_device_by_name(filename):
            count += 1
            filename = "/SWAP-%d" % count

        dev = FileDevice(filename,
                         size=size,
                         parents=[device],
                         fmt=get_format("swap", device=filename))
        dev.create()
        dev.setup()
        dev.format.create()
        dev.format.setup()
        # nasty, nasty
        self.devicetree._add_device(dev)
Ejemplo n.º 13
0
    def create_swap_file(self, device, size):
        """Create and activate a swap file under storage root."""
        filename = "/SWAP"
        count = 0
        basedir = os.path.normpath("%s/%s" % (util.getTargetPhysicalRoot(),
                                              device.format.mountpoint))
        while os.path.exists("%s/%s" % (basedir, filename)) or \
                self.devicetree.get_device_by_name(filename):
            count += 1
            filename = "/SWAP-%d" % count

        dev = FileDevice(filename,
                         size=size,
                         parents=[device],
                         fmt=get_format("swap", device=filename))
        dev.create()
        dev.setup()
        dev.format.create()
        dev.format.setup()
        # nasty, nasty
        self.devicetree._add_device(dev)
Ejemplo n.º 14
0
    def _setupInternalBindmount(self,
                                src,
                                dest=None,
                                src_physical=True,
                                bind_ro=False,
                                recurse=True):
        """Internal API for setting up bind mounts between the physical root and
           sysroot, also ensures we track them in self._internal_mounts so we can
           cleanly unmount them.

           :param src: Source path, will be prefixed with physical or sysroot
           :param dest: Destination, will be prefixed with sysroot (defaults to same as src)
           :param src_physical: Prefix src with physical root
           :param bind_ro: Make mount read-only
           :param recurse: Use --rbind to recurse, otherwise plain --bind
        """
        # Default to the same basename
        if dest is None:
            dest = src
        # Almost all of our mounts go from physical to sysroot
        if src_physical:
            src = util.getTargetPhysicalRoot() + src
        else:
            src = util.getSysroot() + src
        # Canonicalize dest to the full path
        dest = util.getSysroot() + dest
        if bind_ro:
            self._safeExecWithRedirect("mount", ["--bind", src, src])
            self._safeExecWithRedirect(
                "mount", ["--bind", "-o", "remount,ro", src, src])
        else:
            # Recurse for non-ro binds so we pick up sub-mounts
            # like /sys/firmware/efi/efivars.
            if recurse:
                bindopt = '--rbind'
            else:
                bindopt = '--bind'
            self._safeExecWithRedirect("mount", [bindopt, src, dest])
        self._internal_mounts.append(src if bind_ro else dest)
Ejemplo n.º 15
0
    def _setup_internal_bindmount(self, src, dest=None,
                                  src_physical=True,
                                  bind_ro=False,
                                  recurse=True):
        """Internal API for setting up bind mounts between the physical root and
           sysroot, also ensures we track them in self._internal_mounts so we can
           cleanly unmount them.

           :param src: Source path, will be prefixed with physical or sysroot
           :param dest: Destination, will be prefixed with sysroot (defaults to same as src)
           :param src_physical: Prefix src with physical root
           :param bind_ro: Make mount read-only
           :param recurse: Use --rbind to recurse, otherwise plain --bind
        """
        # Default to the same basename
        if dest is None:
            dest = src
        # Almost all of our mounts go from physical to sysroot
        if src_physical:
            src = util.getTargetPhysicalRoot() + src
        else:
            src = util.getSysroot() + src
        # Canonicalize dest to the full path
        dest = util.getSysroot() + dest
        if bind_ro:
            self._safe_exec_with_redirect("mount",
                                          ["--bind", src, src])
            self._safe_exec_with_redirect("mount",
                                          ["--bind", "-o", "remount,ro", src, src])
        else:
            # Recurse for non-ro binds so we pick up sub-mounts
            # like /sys/firmware/efi/efivars.
            if recurse:
                bindopt = '--rbind'
            else:
                bindopt = '--bind'
            self._safe_exec_with_redirect("mount",
                                          [bindopt, src, dest])
        self._internal_mounts.append(src if bind_ro else dest)
Ejemplo n.º 16
0
def mount_existing_system(storage, root_device, read_only=None, sysroot=None):
    """Mount filesystems specified in root_device's /etc/fstab file."""
    root_path = sysroot or util.getTargetPhysicalRoot()
    read_only = "ro" if read_only else ""

    # Mount the root device.
    if root_device.protected and os.path.ismount("/mnt/install/isodir"):
        blivet_util.mount("/mnt/install/isodir",
                          root_path,
                          fstype=root_device.format.type,
                          options="bind")
    else:
        root_device.setup()
        root_device.format.mount(chroot=root_path,
                                 mountpoint="/",
                                 options="%s,%s" %
                                 (root_device.format.options, read_only))

    # Set up the sysroot.
    util.setSysroot(root_path)

    # Mount the filesystems.
    storage.fsset.parse_fstab(chroot=root_path)
    storage.fsset.mount_filesystems(root_path=root_path,
                                    read_only=read_only,
                                    skip_root=True)

    # Turn on swap.
    if not conf.target.is_image or not read_only:
        try:
            storage.fsset.turn_on_swap(root_path=sysroot)
        except StorageError as e:
            log.error("Error enabling swap: %s", str(e))

    # Generate mtab.
    if not read_only:
        storage.make_mtab(chroot=root_path)
Ejemplo n.º 17
0
    def install(self):
        mainctx = create_new_context()
        mainctx.push_thread_default()

        cancellable = None
        gi.require_version("OSTree", "1.0")
        gi.require_version("RpmOstree", "1.0")
        from gi.repository import OSTree, RpmOstree
        ostreesetup = self.data.ostreesetup
        log.info("executing ostreesetup=%r", ostreesetup)

        # Initialize the filesystem - this will create the repo as well
        self._safeExecWithRedirect("ostree", [
            "admin", "--sysroot=" + util.getTargetPhysicalRoot(), "init-fs",
            util.getTargetPhysicalRoot()
        ])

        # Here, we use the physical root as sysroot, because we haven't
        # yet made a deployment.
        sysroot_file = Gio.File.new_for_path(util.getTargetPhysicalRoot())
        sysroot = OSTree.Sysroot.new(sysroot_file)
        sysroot.load(cancellable)
        repo = sysroot.get_repo(None)[1]
        # We don't support resuming from interrupted installs
        repo.set_disable_fsync(True)

        self._remoteOptions = {}

        if hasattr(ostreesetup, 'nogpg') and ostreesetup.nogpg:
            self._remoteOptions['gpg-verify'] = Variant('b', False)

        if flags.noverifyssl:
            self._remoteOptions['tls-permissive'] = Variant('b', True)

        repo.remote_change(None, OSTree.RepoRemoteChange.ADD_IF_NOT_EXISTS,
                           ostreesetup.remote, ostreesetup.url,
                           Variant('a{sv}', self._remoteOptions), cancellable)

        # Variable substitute the ref: https://pagure.io/atomic-wg/issue/299
        ref = RpmOstree.varsubst_basearch(ostreesetup.ref)

        progressQ.send_message(_("Starting pull of %(branchName)s from %(source)s") % \
                               {"branchName": ref, "source": ostreesetup.remote})

        progress = OSTree.AsyncProgress.new()
        progress.connect('changed', self._pullProgressCb)

        pull_opts = {'refs': Variant('as', [ref])}
        # If we're doing a kickstart, we can at least use the content as a reference:
        # See <https://github.com/rhinstaller/anaconda/issues/1117>
        # The first path here is used by <https://pagure.io/fedora-lorax-templates>
        # and the second by <https://github.com/projectatomic/rpm-ostree-toolbox/>
        if OSTree.check_version(2017, 8):
            for path in ['/ostree/repo', '/install/ostree/repo']:
                if os.path.isdir(path + '/objects'):
                    pull_opts['localcache-repos'] = Variant('as', [path])
                    break

        try:
            repo.pull_with_options(ostreesetup.remote,
                                   Variant('a{sv}', pull_opts), progress,
                                   cancellable)
        except GError as e:
            exn = PayloadInstallError("Failed to pull from repository: %s" % e)
            log.error(str(exn))
            if errors.errorHandler.cb(exn) == errors.ERROR_RAISE:
                progressQ.send_quit(1)
                util.ipmi_abort(scripts=self.data.scripts)
                sys.exit(1)

        log.info("ostree pull: " + (progress.get_status() or ""))
        progressQ.send_message(_("Preparing deployment of %s") % (ref, ))

        # Now that we have the data pulled, delete the remote for now.
        # This will allow a remote configuration defined in the tree
        # (if any) to override what's in the kickstart.  Otherwise,
        # we'll re-add it in post.  Ideally, ostree would support a
        # pull without adding a remote, but that would get quite
        # complex.
        repo.remote_delete(self.data.ostreesetup.remote, None)

        self._safeExecWithRedirect("ostree", [
            "admin", "--sysroot=" + util.getTargetPhysicalRoot(), "os-init",
            ostreesetup.osname
        ])

        admin_deploy_args = [
            "admin", "--sysroot=" + util.getTargetPhysicalRoot(), "deploy",
            "--os=" + ostreesetup.osname
        ]

        admin_deploy_args.append(ostreesetup.remote + ':' + ref)

        log.info("ostree admin deploy starting")
        progressQ.send_message(_("Deployment starting: %s") % (ref, ))
        self._safeExecWithRedirect("ostree", admin_deploy_args)
        log.info("ostree admin deploy complete")
        progressQ.send_message(_("Deployment complete: %s") % (ref, ))

        # Reload now that we've deployed, find the path to the new deployment
        sysroot.load(None)
        deployments = sysroot.get_deployments()
        assert len(deployments) > 0
        deployment = deployments[0]
        deployment_path = sysroot.get_deployment_directory(deployment)
        util.setSysroot(deployment_path.get_path())

        try:
            self._copyBootloaderData()
        except (OSError, RuntimeError) as e:
            exn = PayloadInstallError("Failed to copy bootloader data: %s" % e)
            log.error(str(exn))
            if errors.errorHandler.cb(exn) == errors.ERROR_RAISE:
                progressQ.send_quit(1)
                util.ipmi_abort(scripts=self.data.scripts)
                sys.exit(1)

        mainctx.pop_thread_default()
Ejemplo n.º 18
0
def _find_existing_installations(devicetree):
    """Find existing GNU/Linux installations on devices from the device tree.

    :param devicetree: a device tree to find existing installations in
    :return: roots of all found installations
    """
    if not os.path.exists(util.getTargetPhysicalRoot()):
        blivet_util.makedirs(util.getTargetPhysicalRoot())

    sysroot = util.getSysroot()
    roots = []
    direct_devices = (dev for dev in devicetree.devices if dev.direct)
    for device in direct_devices:
        if not device.format.linux_native or not device.format.mountable or \
           not device.controllable:
            continue

        try:
            device.setup()
        except Exception:  # pylint: disable=broad-except
            log_exception_info(log.warning, "setup of %s failed",
                               [device.name])
            continue

        options = device.format.options + ",ro"
        try:
            device.format.mount(options=options, mountpoint=sysroot)
        except Exception:  # pylint: disable=broad-except
            log_exception_info(log.warning, "mount of %s as %s failed",
                               [device.name, device.format.type])
            blivet_util.umount(mountpoint=sysroot)
            continue

        if not os.access(sysroot + "/etc/fstab", os.R_OK):
            blivet_util.umount(mountpoint=sysroot)
            device.teardown()
            continue

        try:
            (architecture, product, version) = get_release_string()
        except ValueError:
            name = _("Linux on %s") % device.name
        else:
            # I'd like to make this finer grained, but it'd be very difficult
            # to translate.
            if not product or not version or not architecture:
                name = _("Unknown Linux")
            elif "linux" in product.lower():
                name = _("%(product)s %(version)s for %(arch)s") % \
                    {"product": product, "version": version, "arch": architecture}
            else:
                name = _("%(product)s Linux %(version)s for %(arch)s") % \
                    {"product": product, "version": version, "arch": architecture}

        (mounts, swaps) = _parse_fstab(devicetree, chroot=sysroot)
        blivet_util.umount(mountpoint=sysroot)
        if not mounts and not swaps:
            # empty /etc/fstab. weird, but I've seen it happen.
            continue
        roots.append(Root(mounts=mounts, swaps=swaps, name=name))

    return roots
Ejemplo n.º 19
0
    def install(self):
        mainctx = create_new_context()
        mainctx.push_thread_default()

        cancellable = None
        gi.require_version("OSTree", "1.0")
        gi.require_version("RpmOstree", "1.0")
        from gi.repository import OSTree, RpmOstree
        ostreesetup = self.data.ostreesetup
        log.info("executing ostreesetup=%r", ostreesetup)

        # Initialize the filesystem - this will create the repo as well
        self._safe_exec_with_redirect("ostree",
                                      ["admin", "--sysroot=" + util.getTargetPhysicalRoot(),
                                       "init-fs", util.getTargetPhysicalRoot()])

        # Here, we use the physical root as sysroot, because we haven't
        # yet made a deployment.
        sysroot_file = Gio.File.new_for_path(util.getTargetPhysicalRoot())
        sysroot = OSTree.Sysroot.new(sysroot_file)
        sysroot.load(cancellable)
        repo = sysroot.get_repo(None)[1]
        # We don't support resuming from interrupted installs
        repo.set_disable_fsync(True)

        self._remoteOptions = {}

        if hasattr(ostreesetup, 'nogpg') and ostreesetup.nogpg:
            self._remoteOptions['gpg-verify'] = Variant('b', False)

        if flags.noverifyssl:
            self._remoteOptions['tls-permissive'] = Variant('b', True)

        repo.remote_change(None, OSTree.RepoRemoteChange.ADD_IF_NOT_EXISTS,
                           ostreesetup.remote, ostreesetup.url,
                           Variant('a{sv}', self._remoteOptions),
                           cancellable)

        # Variable substitute the ref: https://pagure.io/atomic-wg/issue/299
        ref = RpmOstree.varsubst_basearch(ostreesetup.ref)

        progressQ.send_message(_("Starting pull of %(branchName)s from %(source)s") %
                               {"branchName": ref, "source": ostreesetup.remote})

        progress = OSTree.AsyncProgress.new()
        progress.connect('changed', self._pull_progress_cb)

        pull_opts = {'refs': Variant('as', [ref])}
        # If we're doing a kickstart, we can at least use the content as a reference:
        # See <https://github.com/rhinstaller/anaconda/issues/1117>
        # The first path here is used by <https://pagure.io/fedora-lorax-templates>
        # and the second by <https://github.com/projectatomic/rpm-ostree-toolbox/>
        if OSTree.check_version(2017, 8):
            for path in ['/ostree/repo', '/install/ostree/repo']:
                if os.path.isdir(path + '/objects'):
                    pull_opts['localcache-repos'] = Variant('as', [path])
                    break

        try:
            repo.pull_with_options(ostreesetup.remote,
                                   Variant('a{sv}', pull_opts),
                                   progress, cancellable)
        except GError as e:
            exn = PayloadInstallError("Failed to pull from repository: %s" % e)
            log.error(str(exn))
            if errors.errorHandler.cb(exn) == errors.ERROR_RAISE:
                progressQ.send_quit(1)
                util.ipmi_abort(scripts=self.data.scripts)
                sys.exit(1)

        log.info("ostree pull: %s", progress.get_status() or "")
        progressQ.send_message(_("Preparing deployment of %s") % (ref, ))

        # Now that we have the data pulled, delete the remote for now.
        # This will allow a remote configuration defined in the tree
        # (if any) to override what's in the kickstart.  Otherwise,
        # we'll re-add it in post.  Ideally, ostree would support a
        # pull without adding a remote, but that would get quite
        # complex.
        repo.remote_delete(self.data.ostreesetup.remote, None)

        self._safe_exec_with_redirect("ostree",
                                      ["admin", "--sysroot=" + util.getTargetPhysicalRoot(),
                                       "os-init", ostreesetup.osname])

        admin_deploy_args = ["admin", "--sysroot=" + util.getTargetPhysicalRoot(),
                             "deploy", "--os=" + ostreesetup.osname]

        admin_deploy_args.append(ostreesetup.remote + ':' + ref)

        log.info("ostree admin deploy starting")
        progressQ.send_message(_("Deployment starting: %s") % (ref, ))
        self._safe_exec_with_redirect("ostree", admin_deploy_args)
        log.info("ostree admin deploy complete")
        progressQ.send_message(_("Deployment complete: %s") % (ref, ))

        # Reload now that we've deployed, find the path to the new deployment
        sysroot.load(None)
        deployments = sysroot.get_deployments()
        assert len(deployments) > 0
        deployment = deployments[0]
        deployment_path = sysroot.get_deployment_directory(deployment)
        util.setSysroot(deployment_path.get_path())

        try:
            self._copy_bootloader_data()
        except (OSError, RuntimeError) as e:
            exn = PayloadInstallError("Failed to copy bootloader data: %s" % e)
            log.error(str(exn))
            if errors.errorHandler.cb(exn) == errors.ERROR_RAISE:
                progressQ.send_quit(1)
                util.ipmi_abort(scripts=self.data.scripts)
                sys.exit(1)

        mainctx.pop_thread_default()
Ejemplo n.º 20
0
 def sysroot_test(self):
     self.assertEqual(util.getTargetPhysicalRoot(), "/mnt/sysimage")
     self.assertEqual(util.getSysroot(), "/mnt/sysroot")
Ejemplo n.º 21
0
 def _calculate_free_space(self):
     """Calculate the available space."""
     stat = os.statvfs(util.getTargetPhysicalRoot())
     return Size(stat.f_bsize * stat.f_bfree)