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