示例#1
0
    def update_mirrorlist(self):
        l = []
        fn = '/mnt/etc/pacman.d/mirrorlist'

        with open(fn, 'r') as f:
            for x in f:
                x = x.strip('\n')

                if x == '':
                    l.append('')
                    continue
                elif x.startswith('#Server'):
                    x = x[1:]
                elif x.startswith('#'):
                    l.append(x)
                    continue

                is_mirror = True
                for y in self.mirror_kw:
                    if y not in x:
                        is_mirror = False
                        break

                if is_mirror:
                    l = [x] * self.mirror_multiply + [''] + l

                x = '#' + x
                l.append(x)

        with open('/tmp/mirrorlist', 'w') as f:
            for x in l:
                f.write(x + '\n')

        ai_call('mv /tmp/mirrorlist \'' + fn + '\'')
示例#2
0
 def handle_interrupt(signum, frame):
     signal.signal(signal.SIGINT, lambda signum, frame: None)
     print('\nToo late.\n')
     time.sleep(2)
     signal.signal(signal.SIGINT, handle_interrupt_immediate)
     ai_call('reboot')
     while True:
         time.sleep(1000)
示例#3
0
 def _scan_for_all_disks(self):
     ret, p = ai_call('lsblk -b -J -O -p')
     if ret != 0:
         raise Exception('lsblk failed')
     p = json.loads(p)['blockdevices']
     self._remove_toplevel_mounted(p)
     self._scan_for_details(p)
     self._sort_parts(p)
     self.parts = p
     self.scanned = True
示例#4
0
    def __init__(self):
        self._log = ''
        self._log_lock = threading.Lock()
        self._percent = 0
        self._percent_lock = threading.Lock()
        self._progress = ''
        self._progress_lock = threading.Lock()

        gui.builder.get_object('button_install').connect(
            'clicked', lambda x: self._install())
        gui.builder.get_object('button_install_restart').connect(
            'clicked', lambda x: ai_call('reboot'))

        textview = gui.builder.get_object('textview_install_log')
        adjustment = gui.builder.get_object('scrolledwindow_install_log') \
            .get_vadjustment()
        textview.connect(
            'size-allocate',
            lambda x, y: adjustment.set_value(adjustment.get_upper()))
    def _scan_for_details(self, p):
        for x in p:
            if 'children' in x:
                self._scan_for_details(x['children'])

            __, layout = ai_call('parted -m -s \'' + x['name'] +
                                 '\' unit B print')
            # sometimes parted returns error, but with useful information

            layout = layout.decode('utf-8').split('\n')

            if len(layout) <= 1:
                continue
            info = layout[1].split(':')
            if len(info) >= 6:
                x['parttable'] = info[5]

            if 'children' not in x or (not x['children']):
                continue

            if len(layout) <= 2:
                continue
            layout = layout[2:]

            part_map = {}
            for y in layout:
                if not y:
                    continue
                info = y[:-1].split(':')
                if len(info) < 7:
                    continue
                if (not info[1]) or (not info[2]):
                    continue
                part = self.get_part_from_disk_num(x['name'], info[0])
                info[1] = info[1][:-1]
                info[2] = info[2][:-1]
                part_map[part] = (info[1], info[2], info[6])

            for y in x['children']:
                name = y['name']
                if name in part_map:
                    y['start'], y['end'], y['flags'] = part_map[name]
示例#6
0
    def get_configure_cmd(self):
        cmd = 'genfstab -U /mnt > /mnt/etc/fstab'

        cmd += ' && rm -r /mnt/etc/systemd/{journald.conf.d,logind.conf.d}'
        cmd += ' && rm -rf /mnt/etc/systemd/system/{pacman-init.service,etc-pacman.d-gnupg.mount,[email protected]}'
        cmd += ' && rm -rf /mnt/etc/systemd/system/multi-user.target.wants/pacman-init.service'
        cmd += ' && rm /mnt/etc/mkinitcpio.d/*'

        cmd += ' && echo \'\' >> /mnt/etc/sudoers'
        cmd += ' && echo \'%wheel ALL=(ALL) ALL\' >> /mnt/etc/sudoers'

        cmd += ' && echo \'' + \
            hostname_lib.hostname.replace('\'', '') + \
            '\' > /mnt/etc/hostname'

        cmd += ' && arch-chroot /mnt /bin/bash -c \''

        cmd += 'pacman-key --init'
        cmd += ' && pacman-key --populate archlinux'

        cmd += ' && chsh -s /bin/bash'

        cmd += ' && pacman -Rs --noconfirm --noprogressbar memtest86+ syslinux'
        cmd += ' && pacman -Rsc --noconfirm --noprogressbar zsh mkinitcpio-archiso'
        cmd += ' && rm -f /var/log/pacman.log'

        cmd += ' && echo LANG=en_US.UTF-8 > /etc/locale.conf'

        cmd += ' && true > /etc/vconsole.conf'
        if vconsole_lib.get_font_full() != '':
            cmd += ' && echo \"FONT=' + vconsole_lib.get_font_full(
            ) + '\" >> /etc/vconsole.conf'
        if vconsole_lib.get_keymap_full() != '':
            cmd += ' && echo \"KEYMAP=' + vconsole_lib.get_keymap_full(
            ) + '\" >> /etc/vconsole.conf'

        swap_uuid = ''
        if partition_lib.swap_target != '':
            __, swap_uuid = ai_call('blkid -s UUID -o value \'' +
                                    partition_lib.swap_target + '\'')
            swap_uuid = swap_uuid.decode('utf-8').strip('\n')
        crypt_uuid = ''
        if partition_lib.crypt_target != '':
            __, crypt_uuid = ai_call('blkid -s UUID -o value \'' +
                                     partition_lib.crypt_target + '\'')
            crypt_uuid = crypt_uuid.decode('utf-8').strip('\n')
        swap_crypt_uuid = ''
        if partition_lib.swap_crypt_target != '':
            __, swap_crypt_uuid = ai_call('blkid -s UUID -o value \'' +
                                          partition_lib.swap_crypt_target +
                                          '\'')
            swap_crypt_uuid = swap_crypt_uuid.decode('utf-8').strip('\n')

        cmd += ' && sed -i \"s/^\\\\(GRUB_CMDLINE_LINUX_DEFAULT=\\\\).*/\\1\\\"loglevel=3 quiet'
        if swap_crypt_uuid != '':
            cmd += ' rd.luks.name=' + swap_crypt_uuid + '=swap'
        if swap_uuid != '':
            cmd += ' resume=UUID=' + swap_uuid
        if crypt_uuid != '':
            cmd += ' rd.luks.name=' + crypt_uuid + '=cryptroot' + \
                ' root=\\/dev\\/mapper\\/cryptroot'
        cmd += '\\\"/\" /etc/default/grub'

        cmd += ' && sed -i \"s/^\\\\(HOOKS=\\\\).*/\\1(base systemd' + \
            ' keyboard autodetect sd-vconsole modconf block sd-encrypt' + \
            ' filesystems fsck)/\" /etc/mkinitcpio.conf'
        cmd += ' && sed -i \"s/COMPRESSION=\\\"xz\\\"/#COMPRESSION=\\\"xz\\\"/\" /etc/mkinitcpio.conf'

        # Generate preset and mkinitcpio
        cmd += ' && for module in /usr/lib/modules/*; do echo $module/vmlinuz' + \
               ' | sudo /usr/share/libalpm/scripts/mkinitcpio-install; done'

        grub_i386_target = ''
        if partition_lib.boot_target != '':
            grub_i386_target = partition_lib.boot_target
        elif partition_lib.crypt_target != '':
            grub_i386_target = partition_lib.crypt_target
        else:
            grub_i386_target = partition_lib.install_target

        grub_i386_target = partition_lib.get_disk_from_part(grub_i386_target)

        cmd += ' && (grub-install --target=i386-pc \"' + grub_i386_target + \
            '\" || true)'

        cmd += ' && (grub-install --target=x86_64-efi --efi-directory=/boot' + \
            ' --bootloader-id=grub || true)'

        cmd += ' && grub-mkconfig -o /boot/grub/grub.cfg'

        cmd += ' && echo 127.0.0.1 localhost > /etc/hosts'
        cmd += ' && echo ::1 localhost >> /etc/hosts'

        cmd += ' && systemctl disable multi-user.target'
        cmd += ' && systemctl set-default graphical.target'
        cmd += ' && systemctl enable NetworkManager firewalld gdm'

        cmd += ' && (systemctl enable avahi-daemon || true)'
        cmd += ' && (systemctl enable bluetooth || true)'
        cmd += ' && (systemctl enable lvm2-monitor || true)'
        cmd += ' && (systemctl enable org.cups.cupsd || true)'
        cmd += ' && (systemctl enable spice-vdagentd || true)'
        cmd += ' && (systemctl enable systemd-resolved || true)'
        cmd += ' && (systemctl enable upower || true)'

        cmd += ' && (systemctl --global enable pipewire || true)'

        # reenable pacman CheckSpace
        cmd += ' && sed -i "/# We cannot check disk space from within a chroot environment/d" /etc/pacman.conf'
        cmd += ' && sed -i "s/^#CheckSpace$/CheckSpace/" /etc/pacman.conf'

        # disable root login
        cmd += ' && passwd -l root'

        cmd += '\''

        cmd += ' && umount -R /mnt'
        if partition_lib.swap_target != '':
            cmd += ' && swapoff \'' + partition_lib.swap_target + '\''
        if partition_lib.crypt_target != '':
            cmd += ' && cryptsetup close /dev/mapper/cryptroot'
        if partition_lib.swap_crypt_target != '':
            cmd += ' && cryptsetup close /dev/mapper/swap'

        cmd += ' && echo && echo Completed.'

        return cmd
示例#7
0
    def get_configure_cmd(self):
        cmd = 'genfstab -U /mnt > /mnt/etc/fstab'
        cmd += ' && sed -i \'s/Storage=volatile/#Storage=auto/\' /mnt/etc/systemd/journald.conf'
        cmd += ' && sed -i \'s/^\\(PermitRootLogin \\).\\+/#\\1prohibit-password/\' /mnt/etc/ssh/sshd_config'
        cmd += ' && sed -i \'s/\\(HandleSuspendKey=\\)ignore/#\\1suspend/\' /mnt/etc/systemd/logind.conf'
        cmd += ' && sed -i \'s/\\(HandleHibernateKey=\\)ignore/#\\1hibernate/\' /mnt/etc/systemd/logind.conf'
        cmd += ' && rm -f /mnt/etc/udev/rules.d/81-dhcpcd.rules'
        cmd += ' && echo >> /mnt/etc/sudoers'
        cmd += ' && echo \'%wheel ALL=(ALL) ALL\' >> /mnt/etc/sudoers'

        cmd += ' && echo \'' + \
            hostname_lib.hostname.replace('\'', '') + \
            '\' > /mnt/etc/hostname'

        cmd += ' && arch-chroot /mnt /bin/bash -c \''

        cmd += 'systemctl disable pacman-init.service choose-mirror.service'
        cmd += ' && rm -rf /etc/systemd/system/{choose-mirror.service,pacman-init.service,etc-pacman.d-gnupg.mount,[email protected]}'
        cmd += ' && rm -f /etc/systemd/scripts/choose-mirror'
        cmd += ' && rm -f /etc/systemd/system/archiso-start.service'
        cmd += ' && rm -f /etc/systemd/system/multi-user.target.wants/archiso-start.service'

        cmd += ' && rm -f /etc/systemd/system/[email protected]/autologin.conf'
        cmd += ' && rm -f /root/{.automated_script.sh,.zlogin}'
        cmd += ' && rm -f /etc/mkinitcpio-archiso.conf'
        cmd += ' && rm -rf /etc/initcpio'

        cmd += ' && pacman-key --init'
        cmd += ' && pacman-key --populate archlinux'

        cmd += ' && echo LANG=en_US.UTF-8 > /etc/locale.conf'

        swap_uuid = ''
        if partition_lib.swap_target != '':
            __, swap_uuid = ai_call('blkid -s UUID -o value \'' +
                                    partition_lib.swap_target + '\'')
            swap_uuid = swap_uuid.decode('utf-8').strip('\n')
        crypt_uuid = ''
        if partition_lib.crypt_target != '':
            __, crypt_uuid = ai_call('blkid -s UUID -o value \'' +
                                     partition_lib.crypt_target + '\'')
            crypt_uuid = crypt_uuid.decode('utf-8').strip('\n')

        cmd += ' && sed -i \"s/^\\\\(GRUB_CMDLINE_LINUX_DEFAULT=\\\\).*/\\1\\\"quiet'
        if swap_uuid != '':
            cmd += ' resume=UUID=' + swap_uuid
        if crypt_uuid != '':
            cmd += ' cryptdevice=UUID=' + crypt_uuid + \
                ':cryptroot root=\\/dev\\/mapper\\/cryptroot'
        cmd += '\\\"/\" /etc/default/grub'

        if partition_lib.crypt_target == '':
            cmd += ' && sed -i \"s/^\\\\(HOOKS=\\\\).*/\\1(base udev resume' + \
                ' autodetect modconf keyboard keymap block filesystems' + \
                ' keyboard fsck)/\" /etc/mkinitcpio.conf'
        else:
            cmd += ' && sed -i \"s/^\\\\(HOOKS=\\\\).*/\\1(base udev resume' + \
                ' autodetect modconf keyboard keymap block encrypt' + \
                ' filesystems keyboard fsck)/\" /etc/mkinitcpio.conf'

        cmd += ' && mkinitcpio -p linux'

        grub_i386_target = ''
        if partition_lib.boot_target != '':
            grub_i386_target = partition_lib.boot_target
        elif partition_lib.crypt_target != '':
            grub_i386_target = partition_lib.crypt_target
        else:
            grub_i386_target = partition_lib.install_target

        grub_i386_target = partition_lib.get_disk_from_part(grub_i386_target)

        cmd += ' && (grub-install --target=i386-pc \"' + grub_i386_target + \
            '\" || true)'

        cmd += ' && (grub-install --target=x86_64-efi --efi-directory=/boot' + \
            ' --bootloader-id=grub || true)'

        cmd += ' && grub-mkconfig -o /boot/grub/grub.cfg'

        cmd += ' && true > /etc/vconsole.conf'
        if vconsole_lib.get_font_full() != '':
            cmd += ' && echo \"FONT=' + vconsole_lib.get_font_full() + '\" >> /etc/vconsole.conf'
        if vconsole_lib.get_keymap_full() != '':
            cmd += ' && echo \"KEYMAP=' + vconsole_lib.get_keymap_full() + '\" >> /etc/vconsole.conf'

        cmd += ' && echo 127.0.0.1 localhost > /etc/hosts'
        cmd += ' && echo ::1 localhost >> /etc/hosts'

        cmd += ' && systemctl disable multi-user.target'
        cmd += ' && systemctl set-default graphical.target'
        cmd += ' && systemctl enable NetworkManager firewalld gdm'

        cmd += ' && (systemctl enable avahi-daemon || true)'
        cmd += ' && (systemctl enable bluetooth || true)'
        cmd += ' && (systemctl enable lvm2-monitor || true)'
        cmd += ' && (systemctl enable org.cups.cupsd || true)'
        cmd += ' && (systemctl enable spice-vdagentd || true)'
        cmd += ' && (systemctl enable systemd-resolved || true)'
        cmd += ' && (systemctl enable upower || true)'

        cmd += ' && (systemctl --global enable pipewire || true)'

        cmd += '\''

        cmd += ' && umount -R /mnt'
        if partition_lib.swap_target != '':
            cmd += ' && swapoff \'' + partition_lib.swap_target + '\''

        cmd += ' && echo && echo Completed.'

        return cmd
示例#8
0
def main():
    language_lib.install()

    GLib.set_prgname(gui_application.application_id)
    GLib.set_application_name(_('AL Installer'))

    enable_gui = False

    if len(sys.argv) >= 2:
        if sys.argv[1] in ['--help', '-h']:
            print(
                'Usage:\n\n' +
                '(no argument)       Run in CLI (must be run as root)\n' +
                '--gui               Run in GUI (must be run as a password-free sudoer user)\n'
                +
                '--setup-gui         Prompt and set up GUI (must be run as root)\n'
            )
            sys.exit(0)

        if sys.argv[1] == '--gui':
            enable_gui = True
            if getpass.getuser() == 'liveuser':
                cmd = 'gsettings set org.gnome.software download-updates false'
                os.system(cmd)

        elif sys.argv[1] == '--setup-gui':
            print(
                '\n\nTo use CLI instead of GUI, press Ctrl+C (once) in 3 seconds.'
            )
            try:
                time.sleep(3)
                enable_gui = True
            except KeyboardInterrupt:
                enable_gui = False

            if enable_gui:
                print('\nSetting up GUI...')

                ai_call(
                    'rm /etc/xdg/autostart/gnome-initial-setup-first-login.desktop'
                )
                ai_call('rm /etc/xdg/autostart/gnome-welcome-tour.desktop')
                ai_call(
                    'cp /usr/local/share/applications/*.desktop /etc/xdg/autostart'
                )

                ai_call('useradd -c \'Live User\' -G users,wheel -m liveuser')
                ai_call('passwd -d liveuser')

                ai_call(
                    'sed -i \'s/\\[daemon\\]/[daemon]\\nAutomaticLoginEnable='
                    + 'True\\nAutomaticLogin=liveuser/\' /etc/gdm/custom.conf')

                with open('/etc/sudoers', 'a') as f:
                    f.write('\n%wheel ALL=(ALL) ALL\n')

                ai_call('systemctl start firewalld')
                ai_call('systemctl start NetworkManager')
                ai_call('systemctl start avahi-daemon')
                ai_call('systemctl start systemd-resolved')
                ai_call('systemctl start spice-vdagentd')
                ai_call('systemctl start gdm')
                sys.exit(0)

    if enable_gui:
        gui_application.run(sys.argv)
    else:
        try:
            welcome_cli.run()
        except (Exception, KeyboardInterrupt):
            dialog.msgbox('Installation failed.\n\n' + traceback.format_exc())
示例#9
0
class PartitionLib():
    base = 1000
    boot_part_size = 1024 * 1024 * 512
    default_filesystem = 'ext4'
    default_luks_type = 'luks2'
    default_partitioning = 'gpt' if ai_call('efivar -l')[0] == 0 else 'msdos'
    part_granularity = 1024 * 1024
    part_granularity_unit = 'MiB'

    def __init__(self):
        self.boot_target = ''
        self.crypt_passphrase = ''
        self.crypt_target = ''
        self.install_target = ''
        self.swap_target = ''
        self.parts = []
        self.scanned = False

    def __str__(self):
        return str(json.dumps(self.parts, sort_keys=True))

    def _action_autosetup(self,
                          name,
                          size,
                          parttable,
                          crypt=False,
                          passphrase=''):
        boot_start = self.part_granularity
        boot_end = boot_start + self.boot_part_size - 1
        root_start = boot_end + 1
        root_end = size - psutil.virtual_memory().total - \
            self.part_granularity
        root_end = self._to_gran_end(root_end) * self.part_granularity - 1
        swap_start = root_end + 1

        boot_target = name + '1'
        crypt_passphrase = ''
        crypt_target = ''
        install_target = name + '2'
        swap_target = name + '3'
        if crypt:
            crypt_passphrase = passphrase
            crypt_target = install_target
            install_target = '/dev/mapper/cryptroot'

        if crypt:
            with open('/tmp/keyfile', 'w') as f:
                f.write(passphrase)

        cmd = 'parted -m -s \'' + name + '\' unit B mklabel \'' + \
            parttable + '\''
        if parttable == 'gpt':
            cmd += ' mkpart ESP fat32 ' + str(boot_start) + 'B ' + \
                str(boot_end) + 'B'
        else:
            cmd += ' mkpart primary fat32 ' + str(boot_start) + 'B ' + \
                str(boot_end) + 'B'
        cmd += ' mkpart primary ' + self.default_filesystem + ' ' + \
            str(root_start) + 'B ' + str(root_end) + 'B'
        cmd += ' set 1 boot on'
        cmd += ' mkpart primary linux-swap ' + str(swap_start) + 'B 100%'
        cmd += ' && mkfs.fat -F32 \'' + name + '1\''
        if not crypt:
            cmd += ' && mkfs.ext4 \'' + name + '2\''
        else:
            cmd += ' && cryptsetup -v -q --key-file /tmp/keyfile luksFormat ' + \
                '--type \'' + self.default_luks_type + '\' \'' + name + \
                '2\''
            cmd += ' && cryptsetup -q --key-file /tmp/keyfile open \'' + name + \
                '2\' cryptroot'
            cmd += ' && mkfs.ext4 /dev/mapper/cryptroot'
        cmd += ' && mkswap \'' + name + '3\''

        cmd += ' && echo Completed.'

        self._exec(cmd, linger=True, msg='Automatically setting up disk...')

        try:
            os.remove('/tmp/keyfile')
        except Exception:
            pass

        self.boot_target = boot_target
        self.crypt_passphrase = crypt_passphrase
        self.crypt_target = crypt_target
        self.install_target = install_target
        self.swap_target = swap_target

    def _action_boot(self, name):
        disk = self.get_disk_from_part(name)
        num = self.get_num_from_part(name)
        cmd = 'parted -m -s \'' + disk + '\' unit B toggle \'' + \
            str(num) + '\' boot && echo Completed.'

        self._exec(cmd, linger=True, msg='Toggling boot flag...')

    def _action_boot_target(self, name):
        self.boot_target = name
        self._msgbox(_('Successful.'))

    def _action_clear_boot_target(self, name):
        self.boot_target = ''
        self._msgbox(_('Successful.'))

    def _action_clear_crypt_target(self, name):
        self.crypt_passphrase = ''
        self.crypt_target = ''
        self._msgbox(_('Successful.'))

    def _action_clear_install_target(self, name):
        self.install_target = ''
        self._msgbox(_('Successful.'))

    def _action_clear_swap_target(self, name):
        self.swap_target = ''
        self._msgbox(_('Successful.'))

    def _action_cryptsetup(self, name, passphrase):
        with open('/tmp/keyfile', 'w') as f:
            f.write(passphrase)
        self._exec(
            'cryptsetup -v -q --key-file /tmp/keyfile luksFormat --type \'' +
            self.default_luks_type + '\' \'' + name + '\' && echo Completed.',
            linger=True,
            msg='Setting up encryption...')
        os.remove('/tmp/keyfile')

    def _action_cryptopen(self, name, passphrase):
        with open('/tmp/keyfile', 'w') as f:
            f.write(passphrase)
        self._exec('cryptsetup -q --key-file /tmp/keyfile open \'' + name +
                   '\' cryptroot && echo Completed.',
                   linger=True,
                   msg='Opening encrypted partition...')
        self.crypt_passphrase = passphrase
        self.crypt_target = name
        os.remove('/tmp/keyfile')

    def _action_cryptclose(self, name):
        self._exec('cryptsetup close cryptroot && echo Completed.',
                   linger=True,
                   msg='Closing encrypted block...')
        self.crypt_passphrase = ''
        self.crypt_target = ''

    def _action_format(self, name, fstype):
        cmd = ''
        if fstype == 'swap':
            cmd = 'mkswap \'' + name + '\''
        else:
            cmd = 'mkfs -t \'' + fstype + '\' \'' + name + '\''
        cmd += ' && echo Completed.'
        self._exec(cmd, linger=True, msg='Formatting partition...')

    def _action_install_target(self, name):
        self.install_target = name
        self._msgbox(_('Successful.'))

    def _action_parttable(self, name, parttable):
        self._exec('parted -m -s \'' + name + '\' unit B mklabel \'' +
                   parttable + '\' && echo Completed.',
                   linger=True,
                   msg='Creating partition table...')

    def _action_part(self, name, start, end, fstype):
        self._exec('parted -m -s \'' + name.split('*')[1] + '\' unit \'' +
                   self.part_granularity_unit + '\' mkpart primary \'' +
                   fstype + '\' \'' + str(start) + '\' \'' + str(end) + '\' ' +
                   '&& echo Completed.',
                   linger=True,
                   msg='Creating new partition...')

    def _action_refresh(self, name):
        pass

    def _action_remove(self, name):
        disk = self.get_disk_from_part(name)
        num = self.get_num_from_part(name)
        self._exec('parted -m -s \'' + disk + '\' unit B rm \'' + str(num) +
                   '\' && echo Completed.',
                   linger=True,
                   msg='Removing partition...')

    def _action_swap_target(self, name):
        self.swap_target = name
        self._msgbox(_('Successful.'))

    def _add_disk_to_menu(self, menu, pref, name, item, size, *args, **kwargs):
        menu.append(
            PartitionMenuItem(
                name=name,
                size=size,
                text=pref + name,
                size_text=self._format_size(size),
                details_text=_('Size: ') + self._format_size(size) + '\n' +
                _('Partitioning: ') +
                (item['parttable'] if 'parttable' in item
                 and item['parttable'] is not None else _('unknown')),
                ops=['autosetup', 'parttable']))

    def _add_free_space_to_menu(self, menu, pref, parent_name, start, end,
                                *args, **kwargs):

        gran_start = self._to_gran_start(start)
        gran_end = self._to_gran_end(end)
        if gran_start <= 0:
            gran_start = 1
        if gran_end < gran_start:
            return

        start_str = str(gran_start) + self.part_granularity_unit
        end_str = str(gran_end) + self.part_granularity_unit

        menu.append(
            PartitionMenuItem(
                name='*' + parent_name + '*' + start_str + '*' + end_str,
                size=end - start + 1,
                text=pref + _('Free Space'),
                size_text=self._format_size(end - start + 1),
                details_text=_('Size: ') + self._format_size(end - start + 1) +
                '\n' + _('Start: ') + str(start) + '\n' + _('End: ') +
                str(end),
                ops=['part']))

    def _add_other_to_menu(self, menu, pref, name, item, size, *args,
                           **kwargs):
        menu.append(
            PartitionMenuItem(
                name=name,
                size=size,
                text=pref + name,
                size_text=self._format_size(size),
                details_text=_('Size: ') + self._format_size(size) + '\n' +
                _('Filesystem: ') +
                (item['fstype'] if 'fstype' in item
                 and item['fstype'] is not None else _('unknown')),
                ops=[
                    'format', 'boot-target', 'install-target', 'swap-target',
                    'cryptclose'
                ]))

    def _add_options_to_menu(self, menu, *args, **kwargs):
        menu.append(
            PartitionMenuItem(
                name='*show-targets',
                text=_('Show Configured Targets'),
                details_text=_('Boot target: ') + self.boot_target + '\n' +
                _('Encryption target: ') + self.crypt_target + '\n' +
                _('Installation target: ') + self.install_target + '\n' +
                _('Swap target: ') + self.swap_target,
                ops=[
                    'clear-boot-target', 'clear-crypt-target',
                    'clear-install-target', 'clear-swap-target'
                ]))
        menu.append(
            PartitionMenuItem(name='*refresh',
                              text=_('Refresh'),
                              ops=['refresh']))

    def _add_part_to_menu(self, menu, pref, name, item, size, *args, **kwargs):
        menu.append(
            PartitionMenuItem(
                name=name,
                size=size,
                text=pref + name,
                size_text=self._format_size(size),
                details_text=_('Size: ') + self._format_size(size) + '\n' +
                _('Filesystem: ') +
                (item['fstype'] if 'fstype' in item
                 and item['fstype'] is not None else _('unknown')) + '\n' +
                _('Flags: ') + (item['flags'] if 'flags' in item
                                and item['flags'] is not None else '') + '\n' +
                _('Start: ') +
                (item['start'] if 'start' in item and item['start'] is not None
                 else _('unknown')) + '\n' + _('End: ') +
                (item['end'] if 'end' in item and item['end'] is not None else
                 _('unknown')),
                ops=[
                    'boot', 'format', 'boot-target', 'install-target',
                    'swap-target', 'remove', 'cryptsetup', 'cryptopen'
                ]))

    def _exec(self, cmd, msg='', **kwargs):
        if not gui.started:
            ai_dialog_exec(cmd, msg=msg, **kwargs)
        else:
            from partition_gui import partition_gui
            p = ai_popen(cmd,
                         stdin=subprocess.DEVNULL,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.STDOUT,
                         universal_newlines=True)
            partition_gui.add_log_lib(msg)
            partition_gui.add_log_lib('- ' + cmd)
            for x in p.stdout:
                partition_gui.add_log_lib(x.rstrip('\n'))

    def _format_size(self, size):
        units = ['B', 'KB', 'MB', 'GB', 'TB', 'PB']
        for x in units[:-1]:
            if size < self.base:
                return str(size) + ' ' + x
            size //= self.base
        return str(size) + ' ' + units[-1]

    def _get_layout_menu_noscan(self, parts=None, parent=None, level=0):
        if parts is None:
            parts = self.parts

        l = []
        last = -1
        pref = '    ' * level
        has_special_type = False

        for x in parts:
            start = 0
            if 'start' in x:
                start = int(x['start'])

            if start > last + 1:
                self._add_free_space_to_menu(menu=l,
                                             pref=pref,
                                             parent_name=parent['name'],
                                             start=last + 1,
                                             end=start - 1)

            add_to_menu_func = self._add_other_to_menu
            if x['type'] == 'disk':
                add_to_menu_func = self._add_disk_to_menu
            elif x['type'] == 'part':
                add_to_menu_func = self._add_part_to_menu
            else:
                has_special_type = True

            add_to_menu_func(menu=l,
                             pref=pref,
                             name=x['name'],
                             item=x,
                             size=int(x['size']) if 'size' in x else 0)

            if 'children' in x:
                l += self._get_layout_menu_noscan(parts=x['children'],
                                                  parent=x,
                                                  level=level + 1)
            elif level == 0 and 'parttable' in x and x['parttable'] is not None \
                    and x['parttable'] != 'unknown':
                # always consider a toplevel with a known partition table
                # to possibly have free space
                l += self._get_layout_menu_noscan(parts=[],
                                                  parent=x,
                                                  level=level + 1)

            if 'end' in x:
                last = max(last, int(x['end']))

        if parent is not None and 'size' in parent and not has_special_type:
            parent_size = int(parent['size'])
            if parent_size > last + 1:
                self._add_free_space_to_menu(menu=l,
                                             pref=pref,
                                             parent_name=parent['name'],
                                             start=last + 1,
                                             end=parent_size - 1)

        if level == 0:
            self._add_options_to_menu(menu=l)

        return l

    def _msgbox(self, text):
        if not gui.started:
            dialog.msgbox(text)
        else:
            event = threading.Event()

            def show():
                from gi.repository import Gtk
                dialog2 = Gtk.MessageDialog(
                    gui.window, Gtk.DialogFlags.DESTROY_WITH_PARENT,
                    Gtk.MessageType.INFO, Gtk.ButtonsType.CLOSE, text)
                dialog2.run()
                dialog2.destroy()
                event.set()

            gui.idle_add(show)
            event.wait()

    def _to_gran_end(self, x):
        return x // self.part_granularity

    def _to_gran_start(self, x):
        return (x + self.part_granularity - 1) // self.part_granularity

    def _remove_toplevel_mounted(self, p):
        rm = []
        for x in p:
            if 'mountpoint' in x and x['mountpoint'] is not None:
                rm.append(x)
        for x in rm:
            p.remove(x)

    def _scan_for_details(self, p):
        for x in p:
            if 'children' in x:
                self._scan_for_details(x['children'])

            __, layout = ai_call('parted -m -s \'' + x['name'] +
                                 '\' unit B print')
            # sometimes parted returns error, but with useful information

            layout = layout.decode('utf-8').split('\n')

            if len(layout) <= 1:
                continue
            info = layout[1].split(':')
            if len(info) >= 6:
                x['parttable'] = info[5]

            if 'children' not in x or (not x['children']):
                continue

            if len(layout) <= 2:
                continue
            layout = layout[2:]

            part_map = {}
            for y in layout:
                if not y:
                    continue
                info = y[:-1].split(':')
                if len(info) < 7:
                    continue
                if (not info[1]) or (not info[2]):
                    continue
                info[1] = info[1][:-1]
                info[2] = info[2][:-1]
                part_map[x['name'] + info[0]] = (info[1], info[2], info[6])

            for y in x['children']:
                name = y['name']
                if name in part_map:
                    y['start'], y['end'], y['flags'] = part_map[name]

    def _sort_parts(self, parts):
        parts.sort(key=lambda x: 0 if 'start' not in x else int(x['start']))

        for x in parts:
            if 'children' in x:
                self._sort_parts(x['children'])

    def _scan_for_all_disks(self):
        ret, p = ai_call('lsblk -b -J -O -p')
        if ret != 0:
            raise Exception('lsblk failed')
        p = json.loads(p)['blockdevices']
        self._remove_toplevel_mounted(p)
        self._scan_for_details(p)
        self._sort_parts(p)
        self.parts = p
        self.scanned = True

    def action(self, op, name, *args, **kwargs):
        if op == 'autosetup':
            self._action_autosetup(name, *args, **kwargs)
        elif op == 'parttable':
            self._action_parttable(name, *args, **kwargs)
        elif op == 'part':
            self._action_part(name, *args, **kwargs)
        elif op == 'format':
            self._action_format(name, *args, **kwargs)
        elif op == 'boot':
            self._action_boot(name, *args, **kwargs)
        elif op == 'boot-target':
            self._action_boot_target(name, *args, **kwargs)
        elif op == 'install-target':
            self._action_install_target(name, *args, **kwargs)
        elif op == 'swap-target':
            self._action_swap_target(name, *args, **kwargs)
        elif op == 'remove':
            self._action_remove(name, *args, **kwargs)
        elif op == 'cryptsetup':
            self._action_cryptsetup(name, *args, **kwargs)
        elif op == 'cryptopen':
            self._action_cryptopen(name, *args, **kwargs)
        elif op == 'cryptclose':
            self._action_cryptclose(name, *args, **kwargs)
        elif op == 'clear-boot-target':
            self._action_clear_boot_target(name, *args, **kwargs)
        elif op == 'clear-crypt-target':
            self._action_clear_crypt_target(name, *args, **kwargs)
        elif op == 'clear-install-target':
            self._action_clear_install_target(name, *args, **kwargs)
        elif op == 'clear-swap-target':
            self._action_clear_swap_target(name, *args, **kwargs)
        elif op == 'refresh':
            self._action_refresh(name, *args, **kwargs)

    def get_disk_from_part(self, name):
        i = len(name)
        if i == 0:
            return ''
        i -= 1
        while i >= 0 and name[i].isdigit():
            i -= 1
        return name[:i + 1]

    def get_layout_menu(self, scan=False):
        if scan:
            self.scan()
        return self._get_layout_menu_noscan()

    def get_num_from_part(self, name):
        i = len(name)
        if i == 0:
            return 0
        i -= 1
        if not name[i].isdigit():
            return 0
        while i >= 0 and name[i].isdigit():
            i -= 1
        return int(name[i + 1:])

    def get_text_for_op(self, op):
        if op == 'autosetup':
            return _('Automatically Set Up This Disk')
        if op == 'parttable':
            return _('Create/Rewrite Partition Table')
        if op == 'part':
            return _('Create New Partition')
        if op == 'format':
            return _('Format Selected Partition')
        if op == 'boot':
            return _('Toggle Boot Flag')
        if op == 'boot-target':
            return _('Select as Boot Target')
        if op == 'install-target':
            return _('Select as Installation Target')
        if op == 'swap-target':
            return _('Select as Swap Target')
        if op == 'remove':
            return _('Remove Selected Partition')
        if op == 'cryptsetup':
            return _('Set Up Encryption')
        if op == 'cryptopen':
            return _('Open Encrypted Partition')
        if op == 'cryptclose':
            return _('Close Encrypted Block')
        if op == 'clear-boot-target':
            return _('Clear Boot Target')
        if op == 'clear-crypt-target':
            return _('Clear Encryption Target')
        if op == 'clear-install-target':
            return _('Clear Installation Target')
        if op == 'clear-swap-target':
            return _('Clear Swap Target')
        if op == 'refresh':
            return _('Refresh Partition List')
        return op

    def scan(self):
        self._scan_for_all_disks()
示例#10
0
 def handle_interrupt_immediate(signum, frame):
     ai_call('reboot')
     while True:
         time.sleep(1000)
示例#11
0
def main():
    language_lib.install()

    GLib.set_prgname(gui_application.application_id)
    GLib.set_application_name(_('AL Installer'))

    enable_gui = False

    if len(sys.argv) >= 2:
        if sys.argv[1] in ['--help', '-h']:
            print(
                'Usage:\n\n' +
                '(no argument)       Run in CLI (must be run as root)\n' +
                '--gui               Run in GUI (must be run as a password-free sudoer user)\n'
                +
                '--setup-gui         Prompt and set up GUI (must be run as root)\n'
            )
            sys.exit(0)

        if sys.argv[1] == '--gui':
            enable_gui = True
        elif sys.argv[1] == '--setup-gui':
            print(
                '\n\nTo use CLI instead of GUI, press Ctrl+C (once) in 3 seconds.'
            )
            try:
                time.sleep(3)
                enable_gui = True

                def handle_interrupt_immediate(signum, frame):
                    ai_call('reboot')
                    while True:
                        time.sleep(1000)

                def handle_interrupt(signum, frame):
                    signal.signal(signal.SIGINT, lambda signum, frame: None)
                    print('\nToo late.\n')
                    time.sleep(2)
                    signal.signal(signal.SIGINT, handle_interrupt_immediate)
                    ai_call('reboot')
                    while True:
                        time.sleep(1000)

                signal.signal(signal.SIGINT, handle_interrupt)
            except KeyboardInterrupt:
                enable_gui = False

            if enable_gui:
                print('\nSetting up GUI...')

                ai_call(
                    'pacman -R --noconfirm --noprogressbar gnome-initial-setup && '
                    + 'rm -f /var/log/pacman.log')

                ai_call(
                    'cp /usr/local/share/applications/*.desktop /etc/xdg/autostart'
                )

                ai_call('useradd -c \'Live User\' -G users,wheel -m liveuser')
                ai_call('passwd -d liveuser')

                ai_call(
                    'sed -i \'s/\\[daemon\\]/[daemon]\\nAutomaticLoginEnable='
                    + 'True\\nAutomaticLogin=liveuser/\' /etc/gdm/custom.conf')

                with open('/etc/sudoers', 'a') as f:
                    f.write('\n%wheel ALL=(ALL) ALL\n')

                ai_call(
                    'sudo -u liveuser dbus-launch bash -c \'' +
                    'gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-ac-type nothing && '
                    +
                    'gsettings set org.gnome.settings-daemon.plugins.power sleep-inactive-battery-type nothing && '
                    +
                    'gsettings set org.gnome.software allow-updates false && '
                    +
                    'gsettings set org.gnome.software download-updates false' +
                    '\'')

                ai_call('systemctl start firewalld')
                ai_call('systemctl start NetworkManager')
                ai_call('systemctl start avahi-daemon')
                ai_call('systemctl start systemd-resolved')
                ai_call('systemctl start spice-vdagentd')
                ai_call('systemctl start gdm')
                sys.exit(0)

    if enable_gui:
        gui_application.run(sys.argv)
    else:
        try:
            welcome_cli.run()
        except (Exception, KeyboardInterrupt):
            dialog.msgbox('Installation failed.\n\n' + traceback.format_exc())
示例#12
0
    def get_configure_cmd(self):
        cmd = 'genfstab -U /mnt > /mnt/etc/fstab'

        cmd += ' && sed -i \'s/Storage=volatile/#Storage=auto/\' /mnt/etc/systemd/journald.conf'
        cmd += ' && sed -i \'s/^\\(PermitRootLogin \\).\\+/#\\1prohibit-password/\' /mnt/etc/ssh/sshd_config'
        cmd += ' && sed -i \'s/\\(HandleSuspendKey=\\)ignore/#\\1suspend/\' /mnt/etc/systemd/logind.conf'
        cmd += ' && sed -i \'s/\\(HandleHibernateKey=\\)ignore/#\\1hibernate/\' /mnt/etc/systemd/logind.conf'
        cmd += ' && sed -i \'s/\\(HandleLidSwitch=\\)ignore/#\\1suspend/\' /mnt/etc/systemd/logind.conf'

        cmd += ' && echo \'\' >> /mnt/etc/sudoers'
        cmd += ' && echo \'%wheel ALL=(ALL) ALL\' >> /mnt/etc/sudoers'

        cmd += ' && echo \'' + \
            hostname_lib.hostname.replace('\'', '') + \
            '\' > /mnt/etc/hostname'

        cmd += ' && arch-chroot /mnt /bin/bash -c \''

        cmd += 'systemctl disable pacman-init.service choose-mirror.service'
        cmd += ' && rm -rf /etc/systemd/system/{choose-mirror.service,pacman-init.service,etc-pacman.d-gnupg.mount,[email protected]}'
        cmd += ' && rm -f /etc/systemd/scripts/choose-mirror'
        cmd += ' && rm -f /etc/systemd/system/archiso-start.service'
        cmd += ' && rm -f /etc/systemd/system/multi-user.target.wants/archiso-start.service'

        cmd += ' && rm -f /etc/systemd/system/[email protected]/autologin.conf'
        cmd += ' && rm -f /root/{.automated_script.sh,.zlogin,.zshrc}'
        cmd += ' && rm -f /etc/mkinitcpio-archiso.conf'
        cmd += ' && rm -rf /etc/initcpio'

        cmd += ' && pacman-key --init'
        cmd += ' && pacman-key --populate archlinux'

        cmd += ' && chsh -s /bin/bash'

        cmd += ' && pacman -Rs --noconfirm --noprogressbar memtest86+ syslinux xorg-server-xvfb'
        cmd += ' && pacman -Rsc --noconfirm --noprogressbar zsh'
        cmd += ' && rm -f /var/log/pacman.log'

        cmd += ' && echo LANG=en_US.UTF-8 > /etc/locale.conf'

        cmd += ' && true > /etc/vconsole.conf'
        if vconsole_lib.get_font_full() != '':
            cmd += ' && echo \"FONT=' + vconsole_lib.get_font_full(
            ) + '\" >> /etc/vconsole.conf'
        if vconsole_lib.get_keymap_full() != '':
            cmd += ' && echo \"KEYMAP=' + vconsole_lib.get_keymap_full(
            ) + '\" >> /etc/vconsole.conf'

        swap_uuid = ''
        if partition_lib.swap_target != '':
            __, swap_uuid = ai_call('blkid -s UUID -o value \'' +
                                    partition_lib.swap_target + '\'')
            swap_uuid = swap_uuid.decode('utf-8').strip('\n')
        crypt_uuid = ''
        if partition_lib.crypt_target != '':
            __, crypt_uuid = ai_call('blkid -s UUID -o value \'' +
                                     partition_lib.crypt_target + '\'')
            crypt_uuid = crypt_uuid.decode('utf-8').strip('\n')
        swap_crypt_uuid = ''
        if partition_lib.swap_crypt_target != '':
            __, swap_crypt_uuid = ai_call('blkid -s UUID -o value \'' +
                                          partition_lib.swap_crypt_target +
                                          '\'')
            swap_crypt_uuid = swap_crypt_uuid.decode('utf-8').strip('\n')

        cmd += ' && sed -i \"s/^\\\\(GRUB_CMDLINE_LINUX_DEFAULT=\\\\).*/\\1\\\"loglevel=3 quiet'
        if swap_crypt_uuid != '':
            cmd += ' rd.luks.name=' + swap_crypt_uuid + '=swap'
        if swap_uuid != '':
            cmd += ' resume=UUID=' + swap_uuid
        if crypt_uuid != '':
            cmd += ' rd.luks.name=' + crypt_uuid + '=cryptroot' + \
                ' root=\\/dev\\/mapper\\/cryptroot'
        cmd += '\\\"/\" /etc/default/grub'

        cmd += ' && sed -i \"s/^\\\\(HOOKS=\\\\).*/\\1(base systemd' + \
            ' keyboard autodetect sd-vconsole modconf block sd-encrypt' + \
            ' filesystems fsck)/\" /etc/mkinitcpio.conf'

        cmd += ' && mkinitcpio -P'

        grub_i386_target = ''
        if partition_lib.boot_target != '':
            grub_i386_target = partition_lib.boot_target
        elif partition_lib.crypt_target != '':
            grub_i386_target = partition_lib.crypt_target
        else:
            grub_i386_target = partition_lib.install_target

        grub_i386_target = partition_lib.get_disk_from_part(grub_i386_target)

        cmd += ' && (grub-install --target=i386-pc \"' + grub_i386_target + \
            '\" || true)'

        cmd += ' && (grub-install --target=x86_64-efi --efi-directory=/boot' + \
            ' --bootloader-id=grub || true)'

        cmd += ' && grub-mkconfig -o /boot/grub/grub.cfg'

        cmd += ' && echo 127.0.0.1 localhost > /etc/hosts'
        cmd += ' && echo ::1 localhost >> /etc/hosts'

        cmd += ' && systemctl disable multi-user.target'
        cmd += ' && systemctl set-default graphical.target'
        cmd += ' && systemctl enable NetworkManager firewalld gdm'

        cmd += ' && (systemctl enable avahi-daemon || true)'
        cmd += ' && (systemctl enable bluetooth || true)'
        cmd += ' && (systemctl enable lvm2-monitor || true)'
        cmd += ' && (systemctl enable org.cups.cupsd || true)'
        cmd += ' && (systemctl enable spice-vdagentd || true)'
        cmd += ' && (systemctl enable systemd-resolved || true)'
        cmd += ' && (systemctl enable upower || true)'

        cmd += ' && (systemctl --global enable pipewire || true)'

        # reenable pacman CheckSpace
        cmd += ' && sed -i "/# We cannot check disk space from within a chroot environment/d" /etc/pacman.conf'
        cmd += ' && sed -i "s/^#CheckSpace$/CheckSpace/" /etc/pacman.conf'

        # disable root login
        cmd += ' && passwd -l root'

        cmd += '\''

        cmd += ' && umount -R /mnt'
        if partition_lib.swap_target != '':
            cmd += ' && swapoff \'' + partition_lib.swap_target + '\''
        if partition_lib.crypt_target != '':
            cmd += ' && cryptsetup close /dev/mapper/cryptroot'
        if partition_lib.swap_crypt_target != '':
            cmd += ' && cryptsetup close /dev/mapper/swap'

        cmd += ' && echo && echo Completed.'

        return cmd