Example #1
0
    def mount_partitions(self):
        """ Do not call this in automatic mode as AutoPartition class mounts
        the root and boot devices itself. """

        if os.path.exists(DEST_DIR):
            # If we're recovering from a failed/stoped install, there'll be
            # some mounted directories. Try to unmount them first.
            # We use unmount_all from auto_partition to do this.
            auto_partition.unmount_all(DEST_DIR)

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

        # 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 and boot partitions (only if it's needed)
        # Not doing this in automatic mode as AutoPartition class mounts
        # the root and boot devices itself.
        txt = _("Mounting partition {0} into {1} directory").format(root_partition, DEST_DIR)
        logging.debug(txt)
        subprocess.check_call(['mount', root_partition, DEST_DIR])
        # 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" in self.mount_devices:
            txt = _("Mounting partition {0} into {1}/boot directory")
            txt = txt.format(boot_partition, boot_path)
            logging.debug(txt)
            subprocess.check_call(['mount', boot_partition, boot_path])

        # 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 (or they will be mounted at "DEST_DIR")
                    continue

                mount_part = self.mount_devices[path]

                if mount_part != root_partition and mount_part != boot_partition and mount_part != 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").format(mount_part, mount_dir)
                        logging.debug(txt)
                        subprocess.check_call(['mount', mount_part, mount_dir])
                    except subprocess.CalledProcessError as process_error:
                        # We will continue as root and boot are already mounted
                        txt = "Unable to mount {0}, command {1} failed: {2}".format(
                            mount_part, process_error.cmd, process_error.output)
                        logging.warning(txt)
                elif mount_part == swap_partition:
                    try:
                        logging.debug("Activating swap in %s", mount_part)
                        subprocess.check_call(['swapon', swap_partition])
                    except subprocess.CalledProcessError as process_error:
                        # We can continue even if no swap is on
                        txt = "Unable to activate swap {0}, command {1} failed: {2}".format(
                            mount_part, process_error.cmd, process_error.output)
                        logging.warning(txt)
Example #2
0
    def run_installation(self):
        """
        Run installation

        From this point, on a warning situation, Thus 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.
        """

        # Create the directory where we will mount our new root partition
        try:
            os.makedirs(DEST_DIR)
        except OSError:
            # If we're recovering from a failed/stoped install, there'll be
            # some mounted directories. Try to unmount them first.
            auto_partition.unmount_all(DEST_DIR)

        # Create, format and mount partitions in automatic mode
        if self.method == 'automatic':
            logging.debug(_("Creating partitions and their filesystems in {0}"
                            .format(self.auto_device)))

            # If no key password is given a key file is generated and stored in /boot
            # (see auto_partition.py)

            auto = auto_partition.AutoPartition(
                dest_dir=DEST_DIR,
                auto_device=self.auto_device,
                use_luks=self.settings.get("use_luks"),
                luks_password=self.settings.get("luks_root_password"),
                use_lvm=self.settings.get("use_lvm"),
                use_home=self.settings.get("use_home"),
                bootloader=self.settings.get("bootloader"),
                callback_queue=self.callback_queue
            )
            auto.run()

            # used in modify_grub_default() and fstab
            self.mount_devices = auto.get_mount_devices()
            # used when configuring fstab
            self.fs_devices = auto.get_fs_devices()

        # In advanced mode we only need to mount partitions
        if self.method == 'advanced':
            for path in sorted(self.mount_devices):
                if path == "" or path == "swap":
                    continue
                mount_part = self.mount_devices[path]
                mount_dir = DEST_DIR + path
                os.makedirs(mount_dir, exist_ok=True)
                try:
                    logging.debug(_("Mounting partition {0} into {1} directory"
                                    .format(mount_part, mount_dir)))
                    subprocess.check_call(['mount', mount_part, mount_dir])
                except subprocess.CalledProcessError as err:
                    logging.warning(_("Can't mount {0} in {1}"
                                      .format(mount_part, mount_dir)))
                    logging.warning(_("Command {0} has failed."
                                      .format(err.cmd)))
                    logging.warning(_("Output : {0}".format(err.output)))

        # 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(_("{0} deleted".format(db_lock)))

        # Create some needed folders
        os.makedirs(os.path.join(DEST_DIR, 'var/lib/pacman'), exist_ok=True)
        os.makedirs(os.path.join(DEST_DIR, 'etc/pacman.d/gnupg'), exist_ok=True)
        os.makedirs(os.path.join(DEST_DIR, 'var/log'), exist_ok=True)

        all_ok = True

        try:
            logging.debug(_('Install System ...'))
            self.install_system()
            logging.debug(_('System installed.'))
            logging.debug(_('Configuring system ...'))
            self.configure_system()
            logging.debug(_('System configured.'))

        except subprocess.CalledProcessError as err:
            logging.error(err)
            self.queue_fatal_event("CalledProcessError.output = {0}".format(err.output))
            all_ok = False
        except InstallError as err:
            logging.error(err)
            self.queue_fatal_event(err.value)
            all_ok = False
        except Exception as err:
            try:
                logging.debug('Exception: {0}. Trying to continue.'.format(err))
                all_ok = True
                pass
            except Exception as err:
                txt = ('Unknown Error: {0}. Unable to continue.'.format(err))
                logging.debug(txt)
                self.queue_fatal_event(txt)
                self.running = False
                self.error = True
                all_ok = False

        if all_ok is False:
            self.error = True
            return False
        else:
            # Last but not least, copy Thus log to new installation
            datetime = time.strftime("%Y%m%d") + "-" + time.strftime("%H%M%S")
            dst = os.path.join(DEST_DIR,
                               "var/log/thus-{0}.log".format(datetime))
            try:
                shutil.copy("/tmp/thus.log", dst)
            except FileNotFoundError:
                logging.warning(_("Can't copy Thus log to {0}".format(dst)))
            except FileExistsError:
                pass
            
            source_dirs = ["/source", "/source_desktop"]

            partition_dirs = []
            for path in sorted(self.mount_devices, reverse=True):
                if path == "" or path == "swap" or path == "/":
                    continue
                partition_dirs += [DEST_DIR + path]

            install_dirs = ["/install"]
            unmount_points = source_dirs + partition_dirs + install_dirs

            logging.debug("Paths to unmount: {0}".format(unmount_points))
            for p in unmount_points:
                (fsname, fstype, writable) = misc.mount_info(p)
                if fsname:
                    logging.debug(_("Unmounting {0}".format(p)))
                    try:
                        subprocess.check_call(['umount', p])
                    except subprocess.CalledProcessError:
                        logging.debug("Can't unmount. Try -l to force it.")
                        try:
                            subprocess.check_call(["umount", "-l", p])
                        except subprocess.CalledProcessError as err:
                            logging.warning(_("Unable to umount {0}".format(p)))
                            logging.warning(_("Command {0} has failed."
                                              .format(err.cmd)))
                            logging.warning(_("Output : {0}"
                                              .format(err.output)))

            # Installation finished successfully
            self.queue_event("finished", _("Installation finished successfully."))
            self.running = False
            self.error = False
            return True
Example #3
0
    def run_installation(self):
        """
        Run installation

        From this point, on a warning situation, Thus 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.
        """

        # Create the directory where we will mount our new root partition
        try:
            os.makedirs(DEST_DIR)
        except OSError:
            # If we're recovering from a failed/stoped install, there'll be
            # some mounted directories. Try to unmount them first.
            auto_partition.unmount_all(DEST_DIR)

        # Create, format and mount partitions in automatic mode
        if self.method == 'automatic':
            logging.debug(
                _("Creating partitions and their filesystems in {0}".format(
                    self.auto_device)))

            # If no key password is given a key file is generated and stored in /boot
            # (see auto_partition.py)

            auto = auto_partition.AutoPartition(
                dest_dir=DEST_DIR,
                auto_device=self.auto_device,
                use_luks=self.settings.get("use_luks"),
                luks_password=self.settings.get("luks_root_password"),
                use_lvm=self.settings.get("use_lvm"),
                use_home=self.settings.get("use_home"),
                bootloader=self.settings.get("bootloader"),
                callback_queue=self.callback_queue)
            auto.run()

            # used in modify_grub_default() and fstab
            self.mount_devices = auto.get_mount_devices()
            # used when configuring fstab
            self.fs_devices = auto.get_fs_devices()

        # In advanced mode we only need to mount partitions
        if self.method == 'advanced':
            for path in sorted(self.mount_devices):
                if path == "" or path == "swap":
                    continue
                mount_part = self.mount_devices[path]
                mount_dir = DEST_DIR + path
                os.makedirs(mount_dir, exist_ok=True)
                try:
                    logging.debug(
                        _("Mounting partition {0} into {1} directory".format(
                            mount_part, mount_dir)))
                    subprocess.check_call(['mount', mount_part, mount_dir])
                except subprocess.CalledProcessError as err:
                    logging.warning(
                        _("Can't mount {0} in {1}".format(
                            mount_part, mount_dir)))
                    logging.warning(
                        _("Command {0} has failed.".format(err.cmd)))
                    logging.warning(_("Output : {0}".format(err.output)))

        # 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(_("{0} deleted".format(db_lock)))

        # Create some needed folders
        os.makedirs(os.path.join(DEST_DIR, 'var/lib/pacman'), exist_ok=True)
        os.makedirs(os.path.join(DEST_DIR, 'etc/pacman.d/gnupg'),
                    exist_ok=True)
        os.makedirs(os.path.join(DEST_DIR, 'var/log'), exist_ok=True)

        all_ok = True

        try:
            logging.debug(_('Install System ...'))
            self.install_system()
            logging.debug(_('System installed.'))
            logging.debug(_('Configuring system ...'))
            self.configure_system()
            logging.debug(_('System configured.'))

        except subprocess.CalledProcessError as err:
            logging.error(err)
            self.queue_fatal_event("CalledProcessError.output = {0}".format(
                err.output))
            all_ok = False
        except InstallError as err:
            logging.error(err)
            self.queue_fatal_event(err.value)
            all_ok = False
        except Exception as err:
            try:
                logging.debug(
                    'Exception: {0}. Trying to continue.'.format(err))
                all_ok = True
                pass
            except Exception as err:
                txt = ('Unknown Error: {0}. Unable to continue.'.format(err))
                logging.debug(txt)
                self.queue_fatal_event(txt)
                self.running = False
                self.error = True
                all_ok = False

        if all_ok is False:
            self.error = True
            return False
        else:
            # Last but not least, copy Thus log to new installation
            datetime = time.strftime("%Y%m%d") + "-" + time.strftime("%H%M%S")
            dst = os.path.join(DEST_DIR,
                               "var/log/thus-{0}.log".format(datetime))
            try:
                shutil.copy("/tmp/thus.log", dst)
            except FileNotFoundError:
                logging.warning(_("Can't copy Thus log to {0}".format(dst)))
            except FileExistsError:
                pass

            source_dirs = ["/source", "/source_desktop"]

            partition_dirs = []
            for path in sorted(self.mount_devices, reverse=True):
                if path == "" or path == "swap" or path == "/":
                    continue
                partition_dirs += [DEST_DIR + path]

            install_dirs = ["/install"]
            unmount_points = source_dirs + partition_dirs + install_dirs

            logging.debug("Paths to unmount: {0}".format(unmount_points))
            for p in unmount_points:
                (fsname, fstype, writable) = misc.mount_info(p)
                if fsname:
                    logging.debug(_("Unmounting {0}".format(p)))
                    try:
                        subprocess.check_call(['umount', p])
                    except subprocess.CalledProcessError:
                        logging.debug("Can't unmount. Try -l to force it.")
                        try:
                            subprocess.check_call(["umount", "-l", p])
                        except subprocess.CalledProcessError as err:
                            logging.warning(_(
                                "Unable to umount {0}".format(p)))
                            logging.warning(
                                _("Command {0} has failed.".format(err.cmd)))
                            logging.warning(
                                _("Output : {0}".format(err.output)))

            # Installation finished successfully
            self.queue_event("finished",
                             _("Installation finished successfully."))
            self.running = False
            self.error = False
            return True