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)
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
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