Exemplo n.º 1
0
    def populate_devices(self):
        with misc.raised_privileges():
            device_list = parted.getAllDevices()

        self.device_store.remove_all()
        self.devices = {}

        self.bootloader_device_entry.remove_all()
        self.bootloader_devices.clear()

        for dev in device_list:
            # avoid cdrom and any raid, lvm volumes or encryptfs
            if not dev.path.startswith("/dev/sr") and \
               not dev.path.startswith("/dev/mapper"):
                # hard drives measure themselves assuming kilo=1000, mega=1mil, etc
                size_in_gigabytes = int((dev.length * dev.sectorSize) / 1000000000)
                line = '{0} [{1} GB] ({2})'.format(dev.model, size_in_gigabytes, dev.path)
                self.device_store.append_text(line)
                self.devices[line] = dev.path
                self.bootloader_device_entry.append_text(line)
                self.bootloader_devices[line] = dev.path
                logging.debug(line)

        self.select_first_combobox_item(self.device_store)
        self.select_first_combobox_item(self.bootloader_device_entry)
Exemplo n.º 2
0
    def unzip_and_copy(self, zip_path):
        """ Unzip (decompress) a zip file using zipfile standard module """
        import zipfile

        dst_dir = "/tmp"

        with zipfile.ZipFile(zip_path) as zip_file:
            for member in zip_file.infolist():
                zip_file.extract(member, dst_dir)
                full_path = os.path.join(dst_dir, member.filename)
                dst_full_path = os.path.join(
                    "/usr/share/thus",
                    full_path.split("/tmp/thus-{0}/".format(_branch))[1])
                if os.path.isfile(
                        dst_full_path) and dst_full_path in self.md5s:
                    if self.md5s[dst_full_path] == get_md5_from_file(
                            full_path):
                        try:
                            with misc.raised_privileges():
                                shutil.copyfile(full_path, dst_full_path)
                        except FileNotFoundError as file_error:
                            logging.error(
                                _("Can't copy {0} to {1}".format(
                                    full_path, dst_full_path)))
                            logging.error(file_error)
                    else:
                        logging.warning(
                            _("Wrong md5. Bad download or wrong file, won't update this one"
                              ))
Exemplo n.º 3
0
    def uncomment_antergos_mirrors(self):
        """ Uncomment Antergos mirrors and comment out auto selection so
        rankmirrors can find the best mirror. """

        autoselect = "http://mirrors.antergos.com/$repo/$arch"

        if os.path.exists(self.antergos_mirrorlist):
            with open(self.antergos_mirrorlist) as mirrors:
                lines = [x.strip() for x in mirrors.readlines()]

            for i in range(len(lines)):
                if lines[i].startswith("Server") and autoselect in lines[i]:
                    # Comment out auto selection
                    lines[i] = "#" + lines[i]
                elif lines[i].startswith("#Server") and autoselect not in lines[i]:
                    # Uncomment Antergos mirror
                    lines[i] = lines[i].lstrip("#")

                # sourceforge server does not get updated as often as necessary
                if "sourceforge" in lines[i]:
                    lines[i] = "#" + lines[i]

            with misc.raised_privileges():
                # Write new one
                with open(self.antergos_mirrorlist, 'w') as mirrors:
                    mirrors.write("\n".join(lines) + "\n")
            self.sync()
Exemplo n.º 4
0
    def setkb(self):
        subprocess.check_call(['setxkbmap', '-layout', self.keyboard_layout, "-variant", self.keyboard_variant])

        # OpenRC doesn't have localectl
        if os.path.exists("/usr/bin/localectl"):
            with misc.raised_privileges():
                subprocess.check_call(['localectl', 'set-keymap', '--no-convert', self.keyboard_layout])
Exemplo n.º 5
0
 def sync():
     """ Synchronize cached writes to persistent storage """
     with misc.raised_privileges():
         try:
             subprocess.check_call(['sync'])
         except subprocess.CalledProcessError as why:
             logging.warning("Can't synchronize cached writes to persistent storage: %s", why)
Exemplo n.º 6
0
    def populate_devices(self):
        with misc.raised_privileges():
            device_list = parted.getAllDevices()

        self.device_store.remove_all()
        self.devices = {}

        self.bootloader_device_entry.remove_all()
        self.bootloader_devices.clear()

        for dev in device_list:
            # avoid cdrom and any raid, lvm volumes or encryptfs
            if not dev.path.startswith("/dev/sr") and \
               not dev.path.startswith("/dev/mapper"):
                # hard drives measure themselves assuming kilo=1000, mega=1mil, etc
                size_in_gigabytes = int((dev.length * dev.sectorSize) / 1000000000)
                line = '{0} [{1} GB] ({2})'.format(dev.model, size_in_gigabytes, dev.path)
                self.device_store.append_text(line)
                self.devices[line] = dev.path
                self.bootloader_device_entry.append_text(line)
                self.bootloader_devices[line] = dev.path
                logging.debug(line)

        self.select_first_combobox_item(self.device_store)
        self.select_first_combobox_item(self.bootloader_device_entry)
Exemplo n.º 7
0
    def unzip_and_copy(self, zip_path):
        """ Unzip (decompress) a zip file using zipfile standard module """
        import zipfile

        dst_dir = "/tmp"

        with zipfile.ZipFile(zip_path) as zip_file:
            for member in zip_file.infolist():
                zip_file.extract(member, dst_dir)
                full_path = os.path.join(dst_dir, member.filename)
                dst_full_path = os.path.join(
                    "/usr/share/cnchi",
                    full_path.split("/tmp/Cnchi-master/")[1])
                if os.path.isfile(
                        dst_full_path) and dst_full_path in self.md5s:
                    if self.md5s[dst_full_path] == get_md5_from_file(
                            full_path):
                        try:
                            with misc.raised_privileges():
                                shutil.copyfile(full_path, dst_full_path)
                        except FileNotFoundError as file_error:
                            logging.error(
                                _("Can't copy %s to %s"), full_path,
                                dst_full_path)
                            logging.error(file_error)
                    else:
                        logging.warning(
                            _("Wrong md5. Bad download or wrong file, won't update this one"
                              ))
Exemplo n.º 8
0
def update_cnchi():
    """ Runs updater function to update cnchi to the latest version if necessary """
    upd = updater.Updater(
        force_update=cmd_line.update,
        local_cnchi_version=info.CNCHI_VERSION)

    if upd.update():
        logging.info("Program updated! Restarting...")
        misc.remove_temp_files()
        if cmd_line.update:
            # Remove -u and --update options from new call
            new_argv = []
            for argv in sys.argv:
                if argv != "-u" and argv != "--update":
                    new_argv.append(argv)
        else:
            new_argv = sys.argv

        # Do not try to update again now
        new_argv.append("--disable-update")

        # Run another instance of Cnchi (which will be the new version)
        with misc.raised_privileges():
            os.execl(sys.executable, *([sys.executable] + new_argv))
        sys.exit(0)
Exemplo n.º 9
0
    def run(self):
        """ Calculates download package list and then calls run_format and
        run_install. Takes care of the exceptions, too. """

        try:
            # Before formatting, let's try to calculate package download list
            # this way, if something fails (a missing package, mostly) we have
            # not formatted anything yet.

            pkg = pack.SelectPackages(self.settings, self.callback_queue)
            pkg.create_package_list()

            if not pkg.packages or len(pkg.packages) == 0:
                txt = _("Cannot create package list. Check log output for details.")
                raise misc.InstallError(txt)

            down = download.DownloadPackages(
                package_names=pkg.packages,
                download_module='requests',
                pacman_conf_file="/etc/pacman.conf",
                pacman_cache_dir="/var/cache/pacman/pkg",
                cache_dir="/var/cache/pacman/pkg",
                settings=self.settings,
                callback_queue=self.callback_queue)
                
            down.create_metalinks_list()

            if not down.metalinks or len(down.metalinks) == 0:
                txt = _("Cannot create download package list (metalinks). Check log output for details.")
                raise misc.InstallError(txt)

            # try except if pkg.packages is empty or down.metalinks is empty

            with misc.raised_privileges():
                self.install_screen.run_format()
                self.install_screen.run_install(pkg.packages, down.metalinks)
        except subprocess.CalledProcessError as process_error:
            txt = "Error running command {0}: {1}".format(process_error.cmd, process_error.output)
            logging.error(txt)
            exc_type, exc_value, exc_traceback = sys.exc_info()
            trace = traceback.format_exception(exc_type, exc_value, exc_traceback)
            for line in trace:
                logging.error(line.rstrip())
            txt = _("Error running command {0}: {1}").format(process_error.cmd, process_error.output)
            self.queue_fatal_event(txt)
        except (misc.InstallError,
                pyalpm.error,
                KeyboardInterrupt,
                TypeError,
                AttributeError,
                OSError,
                IOError) as install_error:
            logging.error(install_error)
            exc_type, exc_value, exc_traceback = sys.exc_info()
            trace = traceback.format_exception(exc_type, exc_value, exc_traceback)
            for line in trace:
                logging.error(line.rstrip())
            self.queue_fatal_event(install_error)
Exemplo n.º 10
0
    def unzip_and_copy(self, zip_path):
        """ Unzip (decompress) a zip file using zipfile standard module
            and copy DSGos_Installer's files to their destinations """
        import zipfile

        dst_dir = "/tmp"

        # First check all md5 signatures
        all_md5_ok = True
        with zipfile.ZipFile(zip_path) as zip_file:
            # Check md5 sums
            for member in zip_file.infolist():
                zip_file.extract(member, dst_dir)
                full_path = os.path.join(dst_dir, member.filename)
                dst_full_path = os.path.join(
                    "/usr/share/DSGos_Installer",
                    full_path.split("/tmp/DSGos_Installer-master/")[1])
                if os.path.isfile(dst_full_path):
                    if dst_full_path in self.md5s:
                        if "update.info" not in dst_full_path and self.md5s[dst_full_path] != get_md5_from_file(full_path):
                            logging.warning(
                                _("Wrong md5 (%s). Bad download or wrong file, DSGos_Installer won't update itself"),
                                member.filename)
                            all_md5_ok = False
                            break
                    else:
                        logging.warning(
                            _("File %s is not in md5 signatures list"),
                            member.filename)

            if all_md5_ok:
                # All md5 sums where ok. Let's copy all files
                for member in zip_file.infolist():
                    full_path = os.path.join(dst_dir, member.filename)
                    dst_full_path = os.path.join(
                        "/usr/share/DSGos_Installer",
                        full_path.split("/tmp/DSGos_Installer-master/")[1])
                    if os.path.isfile(dst_full_path):
                        try:
                            with misc.raised_privileges():
                                logging.debug(
                                    _("Copying %s to %s..."),
                                    full_path,
                                    dst_full_path)
                                shutil.copyfile(full_path, dst_full_path)
                        except FileNotFoundError as file_error:
                            logging.error(
                                _("Can't copy %s to %s"),
                                full_path,
                                dst_full_path)
                            logging.error(file_error)
Exemplo n.º 11
0
    def filter_and_sort_arch_mirrorlist(self):
        output = '# Arch Linux mirrorlist generated by Cnchi #\n'
        mlist = self.get_mirror_stats()
        mirrors = self.sort_mirrors_by_speed(mirrors=mlist)

        for mirror in mirrors:
            line = "Server = {0}{1}/os/{2}\n".format(mirror['url'], '$repo', '$arch')
            output += line

        # Write modified Arch mirrorlist
        with misc.raised_privileges():
            with open(self.arch_mirrorlist, 'w') as arch_mirrors:
                arch_mirrors.write(output)
        self.sync()
Exemplo n.º 12
0
    def unzip_and_copy(self, zip_path):
        """ Unzip (decompress) a zip file using zipfile standard module
            and copy cnchi's files to their destinations """
        import zipfile

        dst_dir = "/tmp"

        # First check all md5 signatures
        all_md5_ok = True
        with zipfile.ZipFile(zip_path) as zip_file:
            # Check md5 sums
            for member in zip_file.infolist():
                zip_file.extract(member, dst_dir)
                full_path = os.path.join(dst_dir, member.filename)
                dst_full_path = os.path.join(
                    "/usr/share/cnchi",
                    full_path.split("/tmp/Cnchi-master/")[1])
                if os.path.isfile(dst_full_path):
                    if dst_full_path in self.md5s:
                        if "update.info" not in dst_full_path and self.md5s[
                                dst_full_path] != get_md5_from_file(full_path):
                            logging.warning(
                                _("Wrong md5 (%s). Bad download or wrong file, Cnchi won't update itself"
                                  ), member.filename)
                            all_md5_ok = False
                            break
                    else:
                        logging.warning(
                            _("File %s is not in md5 signatures list"),
                            member.filename)

            if all_md5_ok:
                # All md5 sums where ok. Let's copy all files
                for member in zip_file.infolist():
                    full_path = os.path.join(dst_dir, member.filename)
                    dst_full_path = os.path.join(
                        "/usr/share/cnchi",
                        full_path.split("/tmp/Cnchi-master/")[1])
                    if os.path.isfile(dst_full_path):
                        try:
                            with misc.raised_privileges():
                                logging.debug(_("Copying %s to %s..."),
                                              full_path, dst_full_path)
                                shutil.copyfile(full_path, dst_full_path)
                        except FileNotFoundError as file_error:
                            logging.error(_("Can't copy %s to %s"), full_path,
                                          dst_full_path)
                            logging.error(file_error)
Exemplo n.º 13
0
 def update_mirrorlist(self):
     """ Make sure we have the latest antergos-mirrorlist files """
     with misc.raised_privileges():
         try:
             cmd = ['pacman', '-Syy', '--noconfirm', '--noprogressbar', '--quiet', 'antergos-mirrorlist']
             with open(os.devnull, 'w') as fnull:
                 subprocess.call(cmd, stdout=fnull, stderr=subprocess.STDOUT)
             # Use the new downloaded mirrorlist (.pacnew) files (if any)
             pacnew_path = self.antergos_mirrorlist + ".pacnew"
             if os.path.exists(pacnew_path):
                 shutil.copy(pacnew_path, self.antergos_mirrorlist)
         except subprocess.CalledProcessError as why:
             logging.debug('Update of antergos-mirrorlist package failed with error: %s', why)
         except OSError as why:
             logging.debug('Error copying new mirrorlist files: %s', why)
     self.sync()
Exemplo n.º 14
0
    def setkb(self):
        if len(self.keyboard_layout['code']) > 0:
            cmd = ['setxkbmap', '-layout', self.keyboard_layout['code']]

            if len(self.keyboard_variant['code']) > 0:
                cmd.extend(["-variant", self.keyboard_variant['code']])

            try:
                subprocess.check_call(cmd)
            except subprocess.CalledProcessError as process_error:
                logging.warning(process_error)

            with misc.raised_privileges():
                cmd = ['localectl', 'set-keymap', '--no-convert', self.keyboard_layout['code']]
                try:
                    subprocess.check_call(cmd)
                except subprocess.CalledProcessError as process_error:
                    logging.warning(process_error)
Exemplo n.º 15
0
    def run_rankmirrors(self):
        if os.path.exists("/usr/bin/rankmirrors"):
            # Uncomment Antergos mirrors and comment out auto selection so
            # rankmirrors can find the best mirror.
            self.uncomment_antergos_mirrors()

            with misc.raised_privileges():
                try:
                    # Store rankmirrors output in a temporary file
                    with tempfile.TemporaryFile(mode='w+t') as temp_file:
                        cmd = ['rankmirrors', '-n', '0', '-r', 'antergos', self.antergos_mirrorlist]
                        subprocess.call(cmd, stdout=temp_file)
                        temp_file.seek(0)
                        # Copy new mirrorlist to the old one
                        with open(self.antergos_mirrorlist, 'w') as antergos_mirrorlist_file:
                            antergos_mirrorlist_file.write(temp_file.read())
                except subprocess.CalledProcessError as why:
                    logging.debug('Error running rankmirrors on Antergos mirrorlist: %s', why)
            self.sync()
Exemplo n.º 16
0
def update_thus():
    """ Runs updater function to update thus to the latest version if necessary """
    upd = updater.Updater(force_update=cmd_line.update)

    if upd.update():
        logging.info(_("Program updated! Restarting..."))
        misc.remove_temp_files()
        if cmd_line.update:
            # Remove -u and --update options from new call
            new_argv = []
            for argv in sys.argv:
                if argv != "-u" and argv != "--update":
                    new_argv.append(argv)
        else:
            new_argv = sys.argv

        # Do not try to update again now
        new_argv.append("--disable-update")

        # Run another instance of Thus (which will be the new version)
        with misc.raised_privileges():
            os.execl(sys.executable, *([sys.executable] + new_argv))
        sys.exit(0)
Exemplo n.º 17
0
    def run(self):
        """ Run thread """

        # Wait until there is an Internet connection available
        while not misc.has_connection():
            time.sleep(1)  # Delay

        if not os.path.exists(self.reflector_script):
            logging.warning(_("Can't find update mirrors script"))
            return

        # Uncomment Antergos mirrors and comment out auto selection so rankmirrors can find the best mirror.

        autoselect = "http://mirrors.antergos.com/$repo/$arch"

        if os.path.exists(self.antergos_mirrorlist):
            with open(self.antergos_mirrorlist) as mirrors:
                lines = [x.strip() for x in mirrors.readlines()]

            for i in range(len(lines)):
                if lines[i].startswith("Server") and autoselect in lines[i]:
                    # Comment out auto selection
                    lines[i] = "#" + lines[i]
                elif lines[i].startswith("#Server") and autoselect not in lines[i]:
                    # Uncomment Antergos mirror
                    lines[i] = lines[i].lstrip("#")

            with misc.raised_privileges():
                # Backup original file
                shutil.copy(self.antergos_mirrorlist, self.antergos_mirrorlist + ".cnchi_backup")
                # Write new one
                with open(self.antergos_mirrorlist, 'w') as mirrors:
                    mirrors.write("\n".join(lines) + "\n")

        # Run rankmirrors command
        try:
            with misc.raised_privileges():
                self.rankmirrors_pid = subprocess.Popen([self.reflector_script]).pid

        except subprocess.CalledProcessError as process_error:
            logging.error(_("Couldn't execute auto mirror selection"))
            logging.error(process_error)

        # Check arch mirrorlist against mirror status data, remove any bad mirrors.
        if os.path.exists(self.arch_mirrorlist):
            # Use session to avoid silly warning
            # See https://github.com/kennethreitz/requests/issues/1882
            with requests.Session() as session:
                status = session.get(self.arch_mirror_status).json()
                mirrors = status['urls']

            with open(self.arch_mirrorlist) as arch_mirrors:
                lines = [x.strip() for x in arch_mirrors.readlines()]

            for i in range(len(lines)):
                server_uncommented = lines[i].startswith("Server")
                server_commented = lines[i].startswith("#Server")
                if server_commented or server_uncommented:
                    url = lines[i].split('=')[1].strip()
                    check = self.check_mirror_status(mirrors, url)
                    if not check and server_uncommented:
                        # Bad mirror, comment it
                        logging.debug('Removing bad mirror: %s', lines[i])
                        lines[i] = "#" + lines[i]
                    if check and server_commented:
                        # It's a good mirror, uncomment it
                        lines[i] = lines[i].lstrip("#")

            with misc.raised_privileges():
                # Backup original file
                shutil.copy(self.arch_mirrorlist, self.arch_mirrorlist + ".cnchi_backup")
                # Write new one
                with open(self.arch_mirrorlist, 'w') as arch_mirrors:
                    arch_mirrors.write("\n".join(lines) + "\n")

        logging.debug(_("Auto mirror selection has been run successfully"))
Exemplo n.º 18
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
Exemplo n.º 19
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
Exemplo n.º 20
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)

        # Mount needed partitions (in automatic it's already done)
        if self.method == 'alongside' or self.method == 'advanced':
            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")

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

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

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

        self.running = False

        # Installation finished successfully
        self.queue_event('finished', _("Installation finished"))
        self.error = False
        return True
Exemplo n.º 21
0
    def run(self):
        """ Calculates download package list and then calls run_format and
        run_install. Takes care of the exceptions, too. """

        try:
            # Before formatting, let's try to calculate package download list
            # this way, if something fails (a missing package, mostly) we have
            # not formatted anything yet.

            pkg = pack.SelectPackages(self.settings, self.callback_queue)
            pkg.create_package_list()

            if not pkg.packages or len(pkg.packages) == 0:
                txt = _(
                    "Cannot create package list. Check log output for details."
                )
                raise misc.InstallError(txt)

            down = download.DownloadPackages(
                package_names=pkg.packages,
                download_module='requests',
                pacman_conf_file="/etc/pacman.conf",
                pacman_cache_dir="/var/cache/pacman/pkg",
                cache_dir="/var/cache/pacman/pkg",
                settings=self.settings,
                callback_queue=self.callback_queue)

            down.create_metalinks_list()

            if not down.metalinks or len(down.metalinks) == 0:
                txt = _(
                    "Cannot create download package list (metalinks). Check log output for details."
                )
                raise misc.InstallError(txt)

            # try except if pkg.packages is empty or down.metalinks is empty

            with misc.raised_privileges():
                self.install_screen.run_format()
                self.install_screen.run_install(pkg.packages, down.metalinks)
        except subprocess.CalledProcessError as process_error:
            txt = "Error running command {0}: {1}".format(
                process_error.cmd, process_error.output)
            logging.error(txt)
            exc_type, exc_value, exc_traceback = sys.exc_info()
            trace = traceback.format_exception(exc_type, exc_value,
                                               exc_traceback)
            for line in trace:
                logging.error(line.rstrip())
            txt = _("Error running command {0}: {1}").format(
                process_error.cmd, process_error.output)
            self.queue_fatal_event(txt)
        except (misc.InstallError, pyalpm.error, KeyboardInterrupt, TypeError,
                AttributeError, OSError, IOError) as install_error:
            logging.error(install_error)
            exc_type, exc_value, exc_traceback = sys.exc_info()
            trace = traceback.format_exception(exc_type, exc_value,
                                               exc_traceback)
            for line in trace:
                logging.error(line.rstrip())
            self.queue_fatal_event(install_error)