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 + '\'')
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)
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 __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]
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
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
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())
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()
def handle_interrupt_immediate(signum, frame): ai_call('reboot') while True: time.sleep(1000)
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())
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