Example #1
0
    def start(self):
        """ Run installation """

        # From this point, on a warning situation, Cnchi should try to continue,
        # so we need to catch the exception here. If we don't catch the exception
        # here, it will be catched in run() and managed as a fatal error.
        # On the other hand, if we want to clarify the exception message we can
        # catch it here and then raise an InstallError exception.

        if not os.path.exists(DEST_DIR):
            with misc.raised_privileges():
                os.makedirs(DEST_DIR, mode=0o755, exist_ok=True)

        msg = _("Installing using the '{0}' method").format(self.method)
        self.queue_event("info", msg)

        # Mount needed partitions (in automatic it's already done)
        if self.method in ["alongside", "advanced", "zfs"]:
            self.mount_partitions()

        # Nasty workaround:
        # If pacman was stoped and /var is in another partition than root
        # (so as to be able to resume install), database lock file will still
        # be in place. We must delete it or this new installation will fail
        db_lock = os.path.join(DEST_DIR, "var/lib/pacman/db.lck")
        if os.path.exists(db_lock):
            with misc.raised_privileges():
                os.remove(db_lock)
            logging.debug("%s deleted", db_lock)

        # Create some needed folders
        folders = [
            os.path.join(DEST_DIR, "var/lib/pacman"),
            os.path.join(DEST_DIR, "etc/pacman.d/gnupg"),
            os.path.join(DEST_DIR, "var/log"),
        ]

        for folder in folders:
            os.makedirs(folder, mode=0o755, exist_ok=True)

        # If kernel images exists in /boot they are most likely from a failed
        # install attempt and need to be removed otherwise pyalpm will raise a
        # fatal exception later on.
        kernel_imgs = (
            "/install/boot/vmlinuz-linux",
            "/install/boot/vmlinuz-linux-lts",
            "/install/boot/initramfs-linux.img",
            "/install/boot/initramfs-linux-fallback.img",
            "/install/boot/initramfs-linux-lts.img",
            "/install/boot/initramfs-linux-lts-fallback.img",
        )

        for img in kernel_imgs:
            if os.path.exists(img):
                os.remove(img)

        logging.debug("Preparing pacman...")
        self.prepare_pacman()
        logging.debug("Pacman ready")

        # Run pre-install scripts (only catalyst does something here atm)
        # Note: Catalyst is disabled in catalyst.py
        try:
            logging.debug("Running hardware drivers pre-install jobs...")
            proprietary = self.settings.get("feature_graphic_drivers")
            self.hardware_install = hardware.HardwareInstall(use_proprietary_graphic_drivers=proprietary)
            self.hardware_install.pre_install(DEST_DIR)
        except Exception as ex:
            template = "Error in hardware module. An exception of type {0} occured. Arguments:\n{1!r}"
            message = template.format(type(ex).__name__, ex.args)
            logging.error(message)

        logging.debug("Downloading packages...")
        self.download_packages()

        # This mounts (binds) /dev and others to /DEST_DIR/dev and others
        special_dirs.mount(DEST_DIR)

        logging.debug("Installing packages...")
        self.install_packages()

        logging.debug("Configuring system...")
        self.configure_system()

        # This unmounts (unbinds) /dev and others to /DEST_DIR/dev and others
        special_dirs.umount(DEST_DIR)

        # Finally, try to unmount DEST_DIR
        auto_partition.unmount_all_in_directory(DEST_DIR)

        self.running = False

        # Installation finished successfully
        self.queue_event("finished", _("Installation finished"))
        self.error = False
        return True
Example #2
0
    def mount_partitions(self):
        """ Do not call this in automatic mode as AutoPartition class mounts
        the root and boot devices itself. (We call it if using ZFS, though) """

        if os.path.exists(DEST_DIR) and not self.method == "zfs":
            # If we're recovering from a failed/stoped install, there'll be
            # some mounted directories. Try to unmount them first.
            # We use unmount_all_in_directory from auto_partition to do this.
            # ZFS already mounts everything automagically (except /boot that
            # is not in zfs)
            auto_partition.unmount_all_in_directory(DEST_DIR)

        # NOTE: Advanced method formats root by default in advanced.py
        if "/" in self.mount_devices:
            root_partition = self.mount_devices["/"]
        else:
            root_partition = ""

        # Boot partition
        if "/boot" in self.mount_devices:
            boot_partition = self.mount_devices["/boot"]
        else:
            boot_partition = ""

        # Swap partition
        if "swap" in self.mount_devices:
            swap_partition = self.mount_devices["swap"]
        else:
            swap_partition = ""

        # Mount root partition
        if self.method == "zfs":
            # Mount /
            logging.debug("ZFS: Mounting root")
            cmd = ["zfs", "mount", "-a"]
            call(cmd)
        elif root_partition:
            txt = "Mounting partition {0} into {1} directory".format(root_partition, DEST_DIR)
            logging.debug(txt)
            cmd = ["mount", root_partition, DEST_DIR]
            call(cmd, fatal=True)

        # We also mount the boot partition if it's needed
        boot_path = os.path.join(DEST_DIR, "boot")
        os.makedirs(boot_path, mode=0o755, exist_ok=True)
        if boot_partition:
            txt = _("Mounting partition {0} into {1} directory").format(boot_partition, boot_path)
            logging.debug(txt)
            cmd = ["mount", boot_partition, boot_path]
            call(cmd, fatal=True)

        # In advanced mode, mount all partitions (root and boot are already mounted)
        if self.method == "advanced":
            for path in self.mount_devices:
                if path == "":
                    # Ignore devices without a mount path
                    continue

                mount_part = self.mount_devices[path]

                if mount_part not in [root_partition, boot_partition, swap_partition]:
                    if path[0] == "/":
                        path = path[1:]
                    mount_dir = os.path.join(DEST_DIR, path)
                    try:
                        os.makedirs(mount_dir, mode=0o755, exist_ok=True)
                        txt = _("Mounting partition {0} into {1} directory")
                        txt = txt.format(mount_part, mount_dir)
                        logging.debug(txt)
                        cmd = ["mount", mount_part, mount_dir]
                        call(cmd)
                    except OSError:
                        logging.warning("Could not create %s directory", mount_dir)
                elif mount_part == swap_partition:
                    logging.debug("Activating swap in %s", mount_part)
                    cmd = ["swapon", swap_partition]
                    call(cmd)