From 1f89be3a234beb9657c9288a46cc16a04cd5aed7 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 19:20:44 +0200 Subject: Swapping the run() command for something a little more potent --- archinstall.py | 226 ++++++++++++++++++++++++++++++++++++--------------------- 1 file changed, 142 insertions(+), 84 deletions(-) diff --git a/archinstall.py b/archinstall.py index d2d0a1d6..578e532f 100644 --- a/archinstall.py +++ b/archinstall.py @@ -1,9 +1,9 @@ #!/usr/bin/python3 import traceback -import os, re, struct, sys, json +import os, re, struct, sys, json, pty, shlex import urllib.request, urllib.parse, ssl from glob import glob -#from select import epoll, EPOLLIN, EPOLLHUP +from select import epoll, EPOLLIN, EPOLLHUP from socket import socket, inet_ntoa, AF_INET, AF_INET6, AF_PACKET from collections import OrderedDict as oDict from subprocess import Popen, STDOUT, PIPE @@ -110,28 +110,85 @@ def get_local_MACs(): def gen_yubikey_password(): return None #TODO: Implement -def run(cmd, echo=False, opts=None, *args, **kwargs): - if not opts: opts = {} - if echo or 'debug' in opts: - print('[!] {}'.format(cmd)) - handle = Popen(cmd, shell='True', stdout=PIPE, stderr=STDOUT, stdin=PIPE, **kwargs) - output = b'' - while handle.poll() is None: - data = handle.stdout.read() - if b'or press Control-D' in data: - handle.stdin.write(b'') - if len(data): - if echo or 'debug' in opts: - print(data.decode('UTF-8'), end='') - # print(data.decode('UTF-8'), end='') - output += data - data = handle.stdout.read() - if echo or 'debug' in opts: - print(data.decode('UTF-8'), end='') - output += data - handle.stdin.close() - handle.stdout.close() - return output +def pid_exists(pid): + """Check whether pid exists in the current process table.""" + if pid < 0: + return False + try: + os.kill(pid, 0) + except (OSError, e): + return e.errno == errno.EPERMRM + else: + return True + +class sys_command(): + def __init__(self, cmd, opts={}): + self.cmd = shlex.split(cmd) + self.opts = opts + self.pid = -1 + + def __enter__(self, *args, **kwargs): + ## Prep for context management (still block calls) + return self.exec() + + def __leave__(self, *args, **kwargs): + os.waitpid(self.pid, 0) + + def exec(self): + # PID = 0 for child, and the PID of the child for the parent + self.pid, child_fd = pty.fork() + + if not self.pid: # Child process + # Replace child process with our main process + os.execv(self.cmd[0], self.cmd) + + poller = epoll() + poller.register(child_fd, EPOLLIN | EPOLLHUP) + + alive = True + while alive: + for fileno, event in poller.poll(0.1): + try: + output = os.read(child_fd, 1024).strip() + except OSError: + alive = False + break + + if 'debug' in self.opts and self.opts['debug']: + print(output) + + lower = output.lower() + if 'triggers' in self.opts: + for trigger in self.opts['triggers']: + if trigger.lower() in lower: + os.write(child_fd, self.opts['triggers'][trigger]) + + yield output + + os.waitpid(self.pid, 0) + +# def sys_command(cmd, echo=False, opts=None, *args, **kwargs): +# if not opts: opts = {} +# if echo or 'debug' in opts: +# print('[!] {}'.format(cmd)) +# handle = Popen(cmd, shell='True', stdout=PIPE, stderr=STDOUT, stdin=PIPE, **kwargs) +# output = b'' +# while handle.poll() is None: +# data = handle.stdout.read() +# if b'or press Control-D' in data: +# handle.stdin.write(b'') +# if len(data): +# if echo or 'debug' in opts: +# print(data.decode('UTF-8'), end='') +# # print(data.decode('UTF-8'), end='') +# output += data +# data = handle.stdout.read() +# if echo or 'debug' in opts: +# print(data.decode('UTF-8'), end='') +# output += data +# handle.stdin.close() +# handle.stdout.close() +# return output def update_git(): default_gw = get_default_gateway_linux() @@ -139,7 +196,8 @@ def update_git(): ## Not the most elegant way to make sure git conflicts doesn't occur (yea fml) #os.remove('/root/archinstall/archinstall.py') #os.remove('/root/archinstall/README.md') - output = run('(cd /root/archinstall; git fetch --all)') # git reset --hard origin/ + + output = sys_command('(cd /root/archinstall; git fetch --all)') # git reset --hard origin/ if b'error:' in output: print('[N] Could not update git source for some reason.') @@ -173,10 +231,10 @@ def device_state(name): def grab_partitions(dev): drive_name = os.path.basename(dev) parts = oDict() - o = run('lsblk -o name -J -b {dev}'.format(dev=dev)) - if b'not a block device' in o: - ## TODO: Replace o = run() with code, o = run() - ## and make run() return the exit-code, way safer than checking output strings :P + o = sys_command('lsblk -o name -J -b {dev}'.format(dev=dev)) + if b'not a block device' in b''.join(o): + ## TODO: Replace o = sys_command() with code, o = sys_command() + ## and make sys_command() return the exit-code, way safer than checking output strings :P return {} r = json.loads(o) if len(r['blockdevices']) and 'children' in r['blockdevices'][0]: @@ -366,12 +424,12 @@ if __name__ == '__main__': print('[N] Setting up {drive}.'.format(**args)) # dd if=/dev/random of=args['drive'] bs=4096 status=progress # https://github.com/dcantrell/pyparted would be nice, but isn't officially in the repo's #SadPanda - o = run('parted -s {drive} mklabel gpt'.format(**args)) - o = run('parted -s {drive} mkpart primary FAT32 1MiB {start}'.format(**args)) - o = run('parted -s {drive} name 1 "EFI"'.format(**args)) - o = run('parted -s {drive} set 1 esp on'.format(**args)) - o = run('parted -s {drive} set 1 boot on'.format(**args)) - o = run('parted -s {drive} mkpart primary {start} {size}'.format(**args)) + o = sys_command('parted -s {drive} mklabel gpt'.format(**args)).exec() + o = sys_command('parted -s {drive} mkpart primary FAT32 1MiB {start}'.format(**args)).exec() + o = sys_command('parted -s {drive} name 1 "EFI"'.format(**args)).exec() + o = sys_command('parted -s {drive} set 1 esp on'.format(**args)).exec() + o = sys_command('parted -s {drive} set 1 boot on'.format(**args)).exec() + o = sys_command('parted -s {drive} mkpart primary {start} {size}'.format(**args)).exec() args['paritions'] = grab_partitions(args['drive']) if len(args['paritions']) <= 0: @@ -380,7 +438,7 @@ if __name__ == '__main__': for index, part_name in enumerate(args['paritions']): args['partition_{}'.format(index+1)] = part_name - o = run('mkfs.vfat -F32 {drive}{partition_1}'.format(**args)) + o = b''.join(sys_command('mkfs.vfat -F32 {drive}{partition_1}'.format(**args)).exec()) if (b'mkfs.fat' not in o and b'mkfs.vfat' not in o) or b'command not found' in o: print('[E] Could not setup {drive}{partition_1}'.format(**args), o) exit(1) @@ -388,32 +446,32 @@ if __name__ == '__main__': # "--cipher sha512" breaks the shit. # TODO: --use-random instead of --use-urandom print('[N] Adding encryption to {drive}{partition_2}.'.format(**args)) - o = run('cryptsetup -q -v --type luks2 --pbkdf argon2i --hash sha512 --key-size 512 --iter-time 10000 --key-file {pwfile} --use-urandom luksFormat {drive}{partition_2}'.format(**args)) + o = sys_command('cryptsetup -q -v --type luks2 --pbkdf argon2i --hash sha512 --key-size 512 --iter-time 10000 --key-file {pwfile} --use-urandom luksFormat {drive}{partition_2}'.format(**args)).exec() if not 'Command successful.' in o.decode('UTF-8').strip(): print('[E] Failed to setup disk encryption.', o) exit(1) - o = run('cryptsetup open {drive}{partition_2} luksdev --key-file {pwfile} --type luks2'.format(**args)) - o = run('file /dev/mapper/luksdev') # /dev/dm-0 + o = sys_command('cryptsetup open {drive}{partition_2} luksdev --key-file {pwfile} --type luks2'.format(**args)).exec() + o = sys_command('file /dev/mapper/luksdev').exec() # /dev/dm-0 if b'cannot open' in o: print('[E] Could not mount encrypted device.', o) exit(1) print('[N] Creating btrfs filesystem inside {drive}{partition_2}'.format(**args)) - o = run('mkfs.btrfs /dev/mapper/luksdev') + o = sys_command('mkfs.btrfs /dev/mapper/luksdev').exec() if not b'UUID' in o: print('[E] Could not setup btrfs filesystem.', o) exit(1) - o = run('mount /dev/mapper/luksdev /mnt') + o = sys_command('mount /dev/mapper/luksdev /mnt').exec() os.makedirs('/mnt/boot') - o = run('mount {drive}{partition_1} /mnt/boot'.format(**args)) + o = sys_command('mount {drive}{partition_1} /mnt/boot'.format(**args)).exec() print('[N] Reordering mirrors.') if 'mirrors' in args and args['mirrors'] and get_default_gateway_linux(): - o = run("wget 'https://www.archlinux.org/mirrorlist/?country={country}&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on' -O /root/mirrorlist".format(**args)) - o = run("sed -i 's/#Server/Server/' /root/mirrorlist") - o = run('rankmirrors -n 6 /root/mirrorlist > /etc/pacman.d/mirrorlist') + o = sys_command("wget 'https://www.archlinux.org/mirrorlist/?country={country}&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on' -O /root/mirrorlist".format(**args)).exec() + o = sys_command("sed -i 's/#Server/Server/' /root/mirrorlist").exec() + o = sys_command('rankmirrors -n 6 /root/mirrorlist > /etc/pacman.d/mirrorlist').exec() pre_conf = {} if 'pre' in instructions: @@ -446,33 +504,33 @@ if __name__ == '__main__': print('[-] Options: {}'.format(opts)) #print('[N] Command: {} ({})'.format(raw_command, opts)) - o = run('{c}'.format(c=command), opts) - if type(conf[title][raw_command]) == bytes and len(conf[title][raw_command]) and not conf[title][raw_command] in o: - print('[W] Prerequisit step failed: {}'.format(o.decode('UTF-8'))) + o = sys_command('{c}'.format(c=command), opts).exec() + if type(conf[title][raw_command]) == bytes and len(conf[title][raw_command]) and not conf[title][raw_command] in b''.join(o): + print('[W] Prerequisit step failed: {}'.format(b''.join(o).decode('UTF-8'))) #print(o) print('[N] Straping in packages.') - o = run('pacman -Syy') - o = run('pacstrap /mnt base base-devel btrfs-progs efibootmgr nano wpa_supplicant dialog {packages}'.format(**args)) + o = sys_command('pacman -Syy').exec() + o = sys_command('pacstrap /mnt base base-devel btrfs-progs efibootmgr nano wpa_supplicant dialog {packages}'.format(**args)).exec() if not os.path.isdir('/mnt/etc'): print('[E] Failed to strap in packages', o) exit(1) - o = run('genfstab -pU /mnt >> /mnt/etc/fstab') + o = sys_command('genfstab -pU /mnt >> /mnt/etc/fstab').exec() with open('/mnt/etc/fstab', 'a') as fstab: fstab.write('\ntmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0\n') # Redundant \n at the start? who knoes? - o = run('arch-chroot /mnt rm /etc/localtime') - o = run('arch-chroot /mnt ln -s /usr/share/zoneinfo/Europe/Stockholm /etc/localtime') - o = run('arch-chroot /mnt hwclock --hctosys --localtime') - #o = run('arch-chroot /mnt echo "{hostname}" > /etc/hostname'.format(**args)) - #o = run("arch-chroot /mnt sed -i 's/#\(en_US\.UTF-8\)/\1/' /etc/locale.gen") - o = run("arch-chroot /mnt sh -c \"echo '{hostname}' > /etc/hostname\"".format(**args)) - o = run("arch-chroot /mnt sh -c \"echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen\"") - o = run("arch-chroot /mnt sh -c \"echo 'LANG=en_US.UTF-8' > /etc/locale.conf\"") - o = run('arch-chroot /mnt locale-gen') - o = run('arch-chroot /mnt chmod 700 /root') + o = sys_command('arch-chroot /mnt rm /etc/localtime').exec() + o = sys_command('arch-chroot /mnt ln -s /usr/share/zoneinfo/Europe/Stockholm /etc/localtime').exec() + o = sys_command('arch-chroot /mnt hwclock --hctosys --localtime').exec() + #o = sys_command('arch-chroot /mnt echo "{hostname}" > /etc/hostname'.format(**args)).exec() + #o = sys_command("arch-chroot /mnt sed -i 's/#\(en_US\.UTF-8\)/\1/' /etc/locale.gen").exec() + o = sys_command("arch-chroot /mnt sh -c \"echo '{hostname}' > /etc/hostname\"".format(**args)).exec() + o = sys_command("arch-chroot /mnt sh -c \"echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen\"").exec() + o = sys_command("arch-chroot /mnt sh -c \"echo 'LANG=en_US.UTF-8' > /etc/locale.conf\"").exec() + o = sys_command('arch-chroot /mnt locale-gen').exec() + o = sys_command('arch-chroot /mnt chmod 700 /root').exec() with open('/mnt/etc/mkinitcpio.conf', 'w') as mkinit: ## TODO: Don't replace it, in case some update in the future actually adds something. @@ -480,8 +538,8 @@ if __name__ == '__main__': mkinit.write('BINARIES=(/usr/bin/btrfs)\n') mkinit.write('FILES=()\n') mkinit.write('HOOKS=(base udev autodetect modconf block encrypt filesystems keyboard fsck)\n') - o = run('arch-chroot /mnt mkinitcpio -p linux') - o = run('arch-chroot /mnt bootctl --path=/boot install') + o = sys_command('arch-chroot /mnt mkinitcpio -p linux').exec() + o = sys_command('arch-chroot /mnt bootctl --path=/boot install').exec() with open('/mnt/boot/loader/loader.conf', 'w') as loader: loader.write('default arch\n') @@ -489,8 +547,8 @@ if __name__ == '__main__': ## For some reason, blkid and /dev/disk/by-uuid are not getting along well. ## And blkid is wrong in terms of LUKS. - #UUID = run('blkid -s PARTUUID -o value {drive}{partition_2}'.format(**args)).decode('UTF-8').strip() - UUID = run("ls -l /dev/disk/by-uuid/ | grep {basename}{partition_2} | awk '{{print $9}}'".format(basename=os.path.basename(args['drive']), **args)).decode('UTF-8').strip() + #UUID = sys_command('blkid -s PARTUUID -o value {drive}{partition_2}'.format(**args)).decode('UTF-8').exec().strip() + UUID = b''.join(sys_command("ls -l /dev/disk/by-uuid/ | grep {basename}{partition_2} | awk '{{print $9}}'".format(basename=os.path.basename(args['drive']), **args)).exec()).decode('UTF-8').strip() with open('/mnt/boot/loader/entries/arch.conf', 'w') as entry: entry.write('title Arch Linux\n') entry.write('linux /vmlinuz-linux\n') @@ -532,39 +590,39 @@ if __name__ == '__main__': ## Either skipping mounting /run and using traditional chroot is an option, but using ## `systemd-nspawn -D /mnt --machine temporary` might be a more flexible solution in case of file structure changes. if 'no-chroot' in opts and opts['no-chroot']: - o = run(command, opts) + o = sys_command(command, opts).exec() elif 'chroot' in opts and opts['chroot']: ## Run in a manually set up version of arch-chroot (arch-chroot will break namespaces). ## This is a bit risky in case the file systems changes over the years, but we'll probably be safe adding this as an option. ## **> Prefer if possible to use 'no-chroot' instead which "live boots" the OS and runs the command. - o = run("mount /dev/mapper/luksdev /mnt") - o = run("cd /mnt; cp /etc/resolv.conf etc") - o = run("cd /mnt; mount -t proc /proc proc") - o = run("cd /mnt; mount --make-rslave --rbind /sys sys") - o = run("cd /mnt; mount --make-rslave --rbind /dev dev") - o = run('chroot /mnt /bin/bash -c "{c}"'.format(c=command), opts=opts) - o = run("cd /mnt; umount -R dev") - o = run("cd /mnt; umount -R sys") - o = run("cd /mnt; umount -R proc") + o = sys_command("mount /dev/mapper/luksdev /mnt").exec() + o = sys_command("cd /mnt; cp /etc/resolv.conf etc").exec() + o = sys_command("cd /mnt; mount -t proc /proc proc").exec() + o = sys_command("cd /mnt; mount --make-rslave --rbind /sys sys").exec() + o = sys_command("cd /mnt; mount --make-rslave --rbind /dev dev").exec() + o = sys_command('chroot /mnt /bin/bash -c "{c}"'.format(c=command), opts=opts).exec() + o = sys_command("cd /mnt; umount -R dev").exec() + o = sys_command("cd /mnt; umount -R sys").exec() + o = sys_command("cd /mnt; umount -R proc").exec() else: if 'boot' in opts and opts['boot']: - o = run('systemd-nspawn -D /mnt -b --machine temporary {c}'.format(c=command), opts=opts) + o = sys_command('systemd-nspawn -D /mnt -b --machine temporary {c}'.format(c=command), opts=opts).exec() else: - o = run('systemd-nspawn -D /mnt --machine temporary {c}'.format(c=command), opts=opts) + o = sys_command('systemd-nspawn -D /mnt --machine temporary {c}'.format(c=command), opts=opts).exec() if type(conf[title][raw_command]) == bytes and len(conf[title][raw_command]) and not conf[title][raw_command] in o: print('[W] Post install command failed: {}'.format(o.decode('UTF-8'))) #print(o) ## == Passwords - # o = run('arch-chroot /mnt usermod --password {} root'.format(args['password'])) - # o = run("arch-chroot /mnt sh -c 'echo {pin} | passwd --stdin root'".format(pin='"{pin}"'.format(**args, pin=args['password'])), echo=True) - o = run("arch-chroot /mnt sh -c \"echo 'root:{pin}' | chpasswd\"".format(**args, pin=args['password'])) + # o = sys_command('arch-chroot /mnt usermod --password {} root'.format(args['password'])) + # o = sys_command("arch-chroot /mnt sh -c 'echo {pin} | passwd --stdin root'".format(pin='"{pin}"'.format(**args, pin=args['password'])), echo=True) + o = sys_command("arch-chroot /mnt sh -c \"echo 'root:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec() if 'user' in args: - o = run('arch-chroot /mnt useradd -m -G wheel {user}'.format(**args)) - o = run("arch-chroot /mnt sh -c \"echo '{user}:{pin}' | chpasswd\"".format(**args, pin=args['password'])) + o = sys_command('arch-chroot /mnt useradd -m -G wheel {user}'.format(**args)).exec() + o = sys_command("arch-chroot /mnt sh -c \"echo '{user}:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec() if args['post'] == 'reboot': - o = run('umount -R /mnt') - o = run('reboot now') + o = sys_command('umount -R /mnt').exec() + o = sys_command('reboot now').exec() else: print('Done. "umount -R /mnt; reboot" when you\'re done tinkering.') -- cgit v1.2.3-70-g09d2 From 72b04d929196ef73ac9c2f340de5acbc28812e87 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 19:30:07 +0200 Subject: Forgot to join the iterator in some places --- archinstall.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/archinstall.py b/archinstall.py index 578e532f..bed81f37 100644 --- a/archinstall.py +++ b/archinstall.py @@ -194,12 +194,12 @@ def update_git(): default_gw = get_default_gateway_linux() if(default_gw): ## Not the most elegant way to make sure git conflicts doesn't occur (yea fml) - #os.remove('/root/archinstall/archinstall.py') - #os.remove('/root/archinstall/README.md') + os.remove('/root/archinstall/archinstall.py') + os.remove('/root/archinstall/README.md') output = sys_command('(cd /root/archinstall; git fetch --all)') # git reset --hard origin/ - if b'error:' in output: + if b'error:' in b''.join(output): print('[N] Could not update git source for some reason.') return @@ -447,19 +447,19 @@ if __name__ == '__main__': # TODO: --use-random instead of --use-urandom print('[N] Adding encryption to {drive}{partition_2}.'.format(**args)) o = sys_command('cryptsetup -q -v --type luks2 --pbkdf argon2i --hash sha512 --key-size 512 --iter-time 10000 --key-file {pwfile} --use-urandom luksFormat {drive}{partition_2}'.format(**args)).exec() - if not 'Command successful.' in o.decode('UTF-8').strip(): + if not 'Command successful.' in b''.join(o).decode('UTF-8').strip(): print('[E] Failed to setup disk encryption.', o) exit(1) o = sys_command('cryptsetup open {drive}{partition_2} luksdev --key-file {pwfile} --type luks2'.format(**args)).exec() o = sys_command('file /dev/mapper/luksdev').exec() # /dev/dm-0 - if b'cannot open' in o: + if b'cannot open' in b''.join(o): print('[E] Could not mount encrypted device.', o) exit(1) print('[N] Creating btrfs filesystem inside {drive}{partition_2}'.format(**args)) o = sys_command('mkfs.btrfs /dev/mapper/luksdev').exec() - if not b'UUID' in o: + if not b'UUID' in b''.join(o): print('[E] Could not setup btrfs filesystem.', o) exit(1) o = sys_command('mount /dev/mapper/luksdev /mnt').exec() -- cgit v1.2.3-70-g09d2 From 47e788c557bc7268ec533aa686b9557cb48321a8 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 19:36:43 +0200 Subject: Forgot to .exec() --- archinstall.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index bed81f37..91383233 100644 --- a/archinstall.py +++ b/archinstall.py @@ -197,7 +197,7 @@ def update_git(): os.remove('/root/archinstall/archinstall.py') os.remove('/root/archinstall/README.md') - output = sys_command('(cd /root/archinstall; git fetch --all)') # git reset --hard origin/ + output = sys_command('(cd /root/archinstall; git fetch --all)').exec() # git reset --hard origin/ if b'error:' in b''.join(output): print('[N] Could not update git source for some reason.') @@ -231,7 +231,7 @@ def device_state(name): def grab_partitions(dev): drive_name = os.path.basename(dev) parts = oDict() - o = sys_command('lsblk -o name -J -b {dev}'.format(dev=dev)) + o = sys_command('lsblk -o name -J -b {dev}'.format(dev=dev)).exec() if b'not a block device' in b''.join(o): ## TODO: Replace o = sys_command() with code, o = sys_command() ## and make sys_command() return the exit-code, way safer than checking output strings :P -- cgit v1.2.3-70-g09d2 From 58b9442569ca349cdd92e1ddf720e0ac7847aa9a Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 19:44:02 +0200 Subject: Missed another join() --- archinstall.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index 91383233..dfe44133 100644 --- a/archinstall.py +++ b/archinstall.py @@ -197,9 +197,9 @@ def update_git(): os.remove('/root/archinstall/archinstall.py') os.remove('/root/archinstall/README.md') - output = sys_command('(cd /root/archinstall; git fetch --all)').exec() # git reset --hard origin/ + output = b''.join(sys_command('(cd /root/archinstall; git fetch --all)').exec()) # git reset --hard origin/ - if b'error:' in b''.join(output): + if b'error:' in output: print('[N] Could not update git source for some reason.') return -- cgit v1.2.3-70-g09d2 From 6e3e94d284c14fe9235d83cf1347e6e16b43be69 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 19:52:50 +0200 Subject: Failed to convert one more iterator --- archinstall.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index dfe44133..11b2e025 100644 --- a/archinstall.py +++ b/archinstall.py @@ -231,8 +231,8 @@ def device_state(name): def grab_partitions(dev): drive_name = os.path.basename(dev) parts = oDict() - o = sys_command('lsblk -o name -J -b {dev}'.format(dev=dev)).exec() - if b'not a block device' in b''.join(o): + o = b''.join(sys_command('lsblk -o name -J -b {dev}'.format(dev=dev)).exec()) + if b'not a block device' in o: ## TODO: Replace o = sys_command() with code, o = sys_command() ## and make sys_command() return the exit-code, way safer than checking output strings :P return {} -- cgit v1.2.3-70-g09d2 From 3863691b49ebf296eafbb1bf47487d9366dbb671 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 20:07:32 +0200 Subject: Forgot to decode the bytes data --- archinstall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index 11b2e025..cc97328a 100644 --- a/archinstall.py +++ b/archinstall.py @@ -236,7 +236,7 @@ def grab_partitions(dev): ## TODO: Replace o = sys_command() with code, o = sys_command() ## and make sys_command() return the exit-code, way safer than checking output strings :P return {} - r = json.loads(o) + r = json.loads(o.decode('UTF-8')) if len(r['blockdevices']) and 'children' in r['blockdevices'][0]: for part in r['blockdevices'][0]['children']: parts[part['name'][len(drive_name):]] = { -- cgit v1.2.3-70-g09d2 From e932d6fe886709312eea732d3fa3de3cb93786ba Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 20:31:32 +0200 Subject: Trying to fix auto-git-update --- archinstall.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index cc97328a..23d39d02 100644 --- a/archinstall.py +++ b/archinstall.py @@ -193,11 +193,12 @@ class sys_command(): def update_git(): default_gw = get_default_gateway_linux() if(default_gw): + print('[N] Updating git!') ## Not the most elegant way to make sure git conflicts doesn't occur (yea fml) os.remove('/root/archinstall/archinstall.py') os.remove('/root/archinstall/README.md') - output = b''.join(sys_command('(cd /root/archinstall; git fetch --all)').exec()) # git reset --hard origin/ + output = b''.join(sys_command('(cd /root/archinstall; git update)').exec()) # git reset --hard origin/ if b'error:' in output: print('[N] Could not update git source for some reason.') @@ -209,7 +210,8 @@ def update_git(): num_changes = int(tmp[0].split(b' ',1)[0]) if(num_changes): ## Reboot the script (in same context) - os.execv('/usr/bin/python3', ['archinstall.py', 'archinstall.py'] + sys.argv[1:]) + print('[N] Rebooting the script') + os.execv('/usr/bin/python3', ['archinstall.py'] + sys.argv) def device_state(name): # Based out of: https://askubuntu.com/questions/528690/how-to-get-list-of-all-non-removable-disk-device-names-ssd-hdd-and-sata-ide-onl/528709#528709 @@ -236,6 +238,8 @@ def grab_partitions(dev): ## TODO: Replace o = sys_command() with code, o = sys_command() ## and make sys_command() return the exit-code, way safer than checking output strings :P return {} + + print(o) r = json.loads(o.decode('UTF-8')) if len(r['blockdevices']) and 'children' in r['blockdevices'][0]: for part in r['blockdevices'][0]['children']: -- cgit v1.2.3-70-g09d2 From 416971160ec60750304a3a11c7e3de1cf5503bfd Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 20:40:26 +0200 Subject: Doing live tests --- archinstall.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index 23d39d02..a4d36a5a 100644 --- a/archinstall.py +++ b/archinstall.py @@ -165,7 +165,8 @@ class sys_command(): yield output - os.waitpid(self.pid, 0) + x = os.waitpid(self.pid, 0) + print('Exited with:', x) # def sys_command(cmd, echo=False, opts=None, *args, **kwargs): # if not opts: opts = {} @@ -198,7 +199,7 @@ def update_git(): os.remove('/root/archinstall/archinstall.py') os.remove('/root/archinstall/README.md') - output = b''.join(sys_command('(cd /root/archinstall; git update)').exec()) # git reset --hard origin/ + output = b''.join(sys_command('(cd /root/archinstall; git update)').exec()) # git reset --hard origin/ / git fetch --all if b'error:' in output: print('[N] Could not update git source for some reason.') @@ -206,6 +207,7 @@ def update_git(): # b'From github.com:Torxed/archinstall\n 339d687..80b97f3 master -> origin/master\nUpdating 339d687..80b97f3\nFast-forward\n README.md | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n' tmp = re.findall(b'[0-9]+ file changed', output) + print(tmp) if len(tmp): num_changes = int(tmp[0].split(b' ',1)[0]) if(num_changes): -- cgit v1.2.3-70-g09d2 From ef489a0cb5c73a0a3d93d48212eac52e0146f8d0 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 20:45:52 +0200 Subject: Improving on the git update --- archinstall.py | 95 ++++++++++++++++++++++++++++++---------------------------- 1 file changed, 50 insertions(+), 45 deletions(-) diff --git a/archinstall.py b/archinstall.py index a4d36a5a..974d1968 100644 --- a/archinstall.py +++ b/archinstall.py @@ -135,6 +135,11 @@ class sys_command(): os.waitpid(self.pid, 0) def exec(self): + if not self.cmd[0][0] == '/': + print('[N] Command is not executed with absolute path, trying to find it..') + o = b''.join(sys_command('/usr/bin/whereis {}'.format(self.cmd[0]))) + self.cmd[0] = o.split(b' ', 1)[0].decode('UTF-8') + print('[N] This is what I\'m going with: {}'.format(self.cmd[0])) # PID = 0 for child, and the PID of the child for the parent self.pid, child_fd = pty.fork() @@ -235,7 +240,7 @@ def device_state(name): def grab_partitions(dev): drive_name = os.path.basename(dev) parts = oDict() - o = b''.join(sys_command('lsblk -o name -J -b {dev}'.format(dev=dev)).exec()) + o = b''.join(sys_command('/usr/bin/lsblk -o name -J -b {dev}'.format(dev=dev)).exec()) if b'not a block device' in o: ## TODO: Replace o = sys_command() with code, o = sys_command() ## and make sys_command() return the exit-code, way safer than checking output strings :P @@ -430,12 +435,12 @@ if __name__ == '__main__': print('[N] Setting up {drive}.'.format(**args)) # dd if=/dev/random of=args['drive'] bs=4096 status=progress # https://github.com/dcantrell/pyparted would be nice, but isn't officially in the repo's #SadPanda - o = sys_command('parted -s {drive} mklabel gpt'.format(**args)).exec() - o = sys_command('parted -s {drive} mkpart primary FAT32 1MiB {start}'.format(**args)).exec() - o = sys_command('parted -s {drive} name 1 "EFI"'.format(**args)).exec() - o = sys_command('parted -s {drive} set 1 esp on'.format(**args)).exec() - o = sys_command('parted -s {drive} set 1 boot on'.format(**args)).exec() - o = sys_command('parted -s {drive} mkpart primary {start} {size}'.format(**args)).exec() + o = sys_command('/usr/bin/parted -s {drive} mklabel gpt'.format(**args)).exec() + o = sys_command('/usr/bin/parted -s {drive} mkpart primary FAT32 1MiB {start}'.format(**args)).exec() + o = sys_command('/usr/bin/parted -s {drive} name 1 "EFI"'.format(**args)).exec() + o = sys_command('/usr/bin/parted -s {drive} set 1 esp on'.format(**args)).exec() + o = sys_command('/usr/bin/parted -s {drive} set 1 boot on'.format(**args)).exec() + o = sys_command('/usr/bin/parted -s {drive} mkpart primary {start} {size}'.format(**args)).exec() args['paritions'] = grab_partitions(args['drive']) if len(args['paritions']) <= 0: @@ -444,7 +449,7 @@ if __name__ == '__main__': for index, part_name in enumerate(args['paritions']): args['partition_{}'.format(index+1)] = part_name - o = b''.join(sys_command('mkfs.vfat -F32 {drive}{partition_1}'.format(**args)).exec()) + o = b''.join(sys_command('/usr/bin/mkfs.vfat -F32 {drive}{partition_1}'.format(**args)).exec()) if (b'mkfs.fat' not in o and b'mkfs.vfat' not in o) or b'command not found' in o: print('[E] Could not setup {drive}{partition_1}'.format(**args), o) exit(1) @@ -452,32 +457,32 @@ if __name__ == '__main__': # "--cipher sha512" breaks the shit. # TODO: --use-random instead of --use-urandom print('[N] Adding encryption to {drive}{partition_2}.'.format(**args)) - o = sys_command('cryptsetup -q -v --type luks2 --pbkdf argon2i --hash sha512 --key-size 512 --iter-time 10000 --key-file {pwfile} --use-urandom luksFormat {drive}{partition_2}'.format(**args)).exec() + o = sys_command('/usr/bin/cryptsetup -q -v --type luks2 --pbkdf argon2i --hash sha512 --key-size 512 --iter-time 10000 --key-file {pwfile} --use-urandom luksFormat {drive}{partition_2}'.format(**args)).exec() if not 'Command successful.' in b''.join(o).decode('UTF-8').strip(): print('[E] Failed to setup disk encryption.', o) exit(1) - o = sys_command('cryptsetup open {drive}{partition_2} luksdev --key-file {pwfile} --type luks2'.format(**args)).exec() - o = sys_command('file /dev/mapper/luksdev').exec() # /dev/dm-0 + o = sys_command('/usr/bin/cryptsetup open {drive}{partition_2} luksdev --key-file {pwfile} --type luks2'.format(**args)).exec() + o = sys_command('/usr/bin/file /dev/mapper/luksdev').exec() # /dev/dm-0 if b'cannot open' in b''.join(o): print('[E] Could not mount encrypted device.', o) exit(1) print('[N] Creating btrfs filesystem inside {drive}{partition_2}'.format(**args)) - o = sys_command('mkfs.btrfs /dev/mapper/luksdev').exec() + o = sys_command('/usr/bin/mkfs.btrfs /dev/mapper/luksdev').exec() if not b'UUID' in b''.join(o): print('[E] Could not setup btrfs filesystem.', o) exit(1) - o = sys_command('mount /dev/mapper/luksdev /mnt').exec() + o = sys_command('/usr/bin/mount /dev/mapper/luksdev /mnt').exec() os.makedirs('/mnt/boot') - o = sys_command('mount {drive}{partition_1} /mnt/boot'.format(**args)).exec() + o = sys_command('/usr/bin/mount {drive}{partition_1} /mnt/boot'.format(**args)).exec() print('[N] Reordering mirrors.') if 'mirrors' in args and args['mirrors'] and get_default_gateway_linux(): - o = sys_command("wget 'https://www.archlinux.org/mirrorlist/?country={country}&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on' -O /root/mirrorlist".format(**args)).exec() - o = sys_command("sed -i 's/#Server/Server/' /root/mirrorlist").exec() - o = sys_command('rankmirrors -n 6 /root/mirrorlist > /etc/pacman.d/mirrorlist').exec() + o = sys_command("/usr/bin/wget 'https://www.archlinux.org/mirrorlist/?country={country}&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on' -O /root/mirrorlist".format(**args)).exec() + o = sys_command("/usr/bin/sed -i 's/#Server/Server/' /root/mirrorlist").exec() + o = sys_command('/usr/bin/rankmirrors -n 6 /root/mirrorlist > /etc/pacman.d/mirrorlist').exec() pre_conf = {} if 'pre' in instructions: @@ -516,27 +521,27 @@ if __name__ == '__main__': #print(o) print('[N] Straping in packages.') - o = sys_command('pacman -Syy').exec() - o = sys_command('pacstrap /mnt base base-devel btrfs-progs efibootmgr nano wpa_supplicant dialog {packages}'.format(**args)).exec() + o = sys_command('/usr/bin/pacman -Syy').exec() + o = sys_command('/usr/bin/pacstrap /mnt base base-devel btrfs-progs efibootmgr nano wpa_supplicant dialog {packages}'.format(**args)).exec() if not os.path.isdir('/mnt/etc'): print('[E] Failed to strap in packages', o) exit(1) - o = sys_command('genfstab -pU /mnt >> /mnt/etc/fstab').exec() + o = sys_command('/usr/bin/genfstab -pU /mnt >> /mnt/etc/fstab').exec() with open('/mnt/etc/fstab', 'a') as fstab: fstab.write('\ntmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0\n') # Redundant \n at the start? who knoes? - o = sys_command('arch-chroot /mnt rm /etc/localtime').exec() - o = sys_command('arch-chroot /mnt ln -s /usr/share/zoneinfo/Europe/Stockholm /etc/localtime').exec() - o = sys_command('arch-chroot /mnt hwclock --hctosys --localtime').exec() + o = sys_command('/usr/bin/arch-chroot /mnt rm /etc/localtime').exec() + o = sys_command('/usr/bin/arch-chroot /mnt ln -s /usr/share/zoneinfo/Europe/Stockholm /etc/localtime').exec() + o = sys_command('/usr/bin/arch-chroot /mnt hwclock --hctosys --localtime').exec() #o = sys_command('arch-chroot /mnt echo "{hostname}" > /etc/hostname'.format(**args)).exec() #o = sys_command("arch-chroot /mnt sed -i 's/#\(en_US\.UTF-8\)/\1/' /etc/locale.gen").exec() - o = sys_command("arch-chroot /mnt sh -c \"echo '{hostname}' > /etc/hostname\"".format(**args)).exec() - o = sys_command("arch-chroot /mnt sh -c \"echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen\"").exec() - o = sys_command("arch-chroot /mnt sh -c \"echo 'LANG=en_US.UTF-8' > /etc/locale.conf\"").exec() - o = sys_command('arch-chroot /mnt locale-gen').exec() - o = sys_command('arch-chroot /mnt chmod 700 /root').exec() + o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo '{hostname}' > /etc/hostname\"".format(**args)).exec() + o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen\"").exec() + o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'LANG=en_US.UTF-8' > /etc/locale.conf\"").exec() + o = sys_command('/usr/bin/arch-chroot /mnt locale-gen').exec() + o = sys_command('/usr/bin/arch-chroot /mnt chmod 700 /root').exec() with open('/mnt/etc/mkinitcpio.conf', 'w') as mkinit: ## TODO: Don't replace it, in case some update in the future actually adds something. @@ -544,8 +549,8 @@ if __name__ == '__main__': mkinit.write('BINARIES=(/usr/bin/btrfs)\n') mkinit.write('FILES=()\n') mkinit.write('HOOKS=(base udev autodetect modconf block encrypt filesystems keyboard fsck)\n') - o = sys_command('arch-chroot /mnt mkinitcpio -p linux').exec() - o = sys_command('arch-chroot /mnt bootctl --path=/boot install').exec() + o = sys_command('/usr/bin/arch-chroot /mnt mkinitcpio -p linux').exec() + o = sys_command('/usr/bin/arch-chroot /mnt bootctl --path=/boot install').exec() with open('/mnt/boot/loader/loader.conf', 'w') as loader: loader.write('default arch\n') @@ -601,20 +606,20 @@ if __name__ == '__main__': ## Run in a manually set up version of arch-chroot (arch-chroot will break namespaces). ## This is a bit risky in case the file systems changes over the years, but we'll probably be safe adding this as an option. ## **> Prefer if possible to use 'no-chroot' instead which "live boots" the OS and runs the command. - o = sys_command("mount /dev/mapper/luksdev /mnt").exec() + o = sys_command("/usr/bin/mount /dev/mapper/luksdev /mnt").exec() o = sys_command("cd /mnt; cp /etc/resolv.conf etc").exec() - o = sys_command("cd /mnt; mount -t proc /proc proc").exec() - o = sys_command("cd /mnt; mount --make-rslave --rbind /sys sys").exec() - o = sys_command("cd /mnt; mount --make-rslave --rbind /dev dev").exec() - o = sys_command('chroot /mnt /bin/bash -c "{c}"'.format(c=command), opts=opts).exec() - o = sys_command("cd /mnt; umount -R dev").exec() - o = sys_command("cd /mnt; umount -R sys").exec() - o = sys_command("cd /mnt; umount -R proc").exec() + o = sys_command("cd /mnt; /usr/bin/mount -t proc /proc proc").exec() + o = sys_command("cd /mnt; /usr/bin/mount --make-rslave --rbind /sys sys").exec() + o = sys_command("cd /mnt; /usr/bin/mount --make-rslave --rbind /dev dev").exec() + o = sys_command('/usr/bin/chroot /mnt /bin/bash -c "{c}"'.format(c=command), opts=opts).exec() + o = sys_command("cd /mnt; /usr/bin/umount -R dev").exec() + o = sys_command("cd /mnt; /usr/bin/umount -R sys").exec() + o = sys_command("cd /mnt; /usr/bin/umount -R proc").exec() else: if 'boot' in opts and opts['boot']: - o = sys_command('systemd-nspawn -D /mnt -b --machine temporary {c}'.format(c=command), opts=opts).exec() + o = sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary {c}'.format(c=command), opts=opts).exec() else: - o = sys_command('systemd-nspawn -D /mnt --machine temporary {c}'.format(c=command), opts=opts).exec() + o = sys_command('/usr/bin/systemd-nspawn -D /mnt --machine temporary {c}'.format(c=command), opts=opts).exec() if type(conf[title][raw_command]) == bytes and len(conf[title][raw_command]) and not conf[title][raw_command] in o: print('[W] Post install command failed: {}'.format(o.decode('UTF-8'))) #print(o) @@ -622,13 +627,13 @@ if __name__ == '__main__': ## == Passwords # o = sys_command('arch-chroot /mnt usermod --password {} root'.format(args['password'])) # o = sys_command("arch-chroot /mnt sh -c 'echo {pin} | passwd --stdin root'".format(pin='"{pin}"'.format(**args, pin=args['password'])), echo=True) - o = sys_command("arch-chroot /mnt sh -c \"echo 'root:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec() + o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'root:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec() if 'user' in args: - o = sys_command('arch-chroot /mnt useradd -m -G wheel {user}'.format(**args)).exec() - o = sys_command("arch-chroot /mnt sh -c \"echo '{user}:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec() + o = sys_command('/usr/bin/arch-chroot /mnt useradd -m -G wheel {user}'.format(**args)).exec() + o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo '{user}:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec() if args['post'] == 'reboot': - o = sys_command('umount -R /mnt').exec() - o = sys_command('reboot now').exec() + o = sys_command('/usr/bin/umount -R /mnt').exec() + o = sys_command('/usr/bin/reboot now').exec() else: print('Done. "umount -R /mnt; reboot" when you\'re done tinkering.') -- cgit v1.2.3-70-g09d2 From c33d382220ba1c2b2a4b42b9412fa094a7eef03a Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 20:50:17 +0200 Subject: More status output --- archinstall.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index 974d1968..bd0a4f27 100644 --- a/archinstall.py +++ b/archinstall.py @@ -205,7 +205,8 @@ def update_git(): os.remove('/root/archinstall/README.md') output = b''.join(sys_command('(cd /root/archinstall; git update)').exec()) # git reset --hard origin/ / git fetch --all - + print(output) + if b'error:' in output: print('[N] Could not update git source for some reason.') return -- cgit v1.2.3-70-g09d2 From f11d93e255a9e0a9b5d16a6385ed74bf8be35b06 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:05:36 +0200 Subject: More git update experiments --- archinstall.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index bd0a4f27..d48d50e7 100644 --- a/archinstall.py +++ b/archinstall.py @@ -137,7 +137,7 @@ class sys_command(): def exec(self): if not self.cmd[0][0] == '/': print('[N] Command is not executed with absolute path, trying to find it..') - o = b''.join(sys_command('/usr/bin/whereis {}'.format(self.cmd[0]))) + o = b''.join(sys_command('/usr/bin/whereis {}'.format(self.cmd[0])).exec()) self.cmd[0] = o.split(b' ', 1)[0].decode('UTF-8') print('[N] This is what I\'m going with: {}'.format(self.cmd[0])) # PID = 0 for child, and the PID of the child for the parent @@ -204,7 +204,7 @@ def update_git(): os.remove('/root/archinstall/archinstall.py') os.remove('/root/archinstall/README.md') - output = b''.join(sys_command('(cd /root/archinstall; git update)').exec()) # git reset --hard origin/ / git fetch --all + output = b''.join(sys_command('(cd /root/archinstall; git reset --hard origin/$(git branch | grep "*" | cut -d\' \' -f 2))').exec()) # git reset --hard origin/ / git fetch --all print(output) if b'error:' in output: @@ -220,6 +220,7 @@ def update_git(): ## Reboot the script (in same context) print('[N] Rebooting the script') os.execv('/usr/bin/python3', ['archinstall.py'] + sys.argv) + extit(1) def device_state(name): # Based out of: https://askubuntu.com/questions/528690/how-to-get-list-of-all-non-removable-disk-device-names-ssd-hdd-and-sata-ide-onl/528709#528709 -- cgit v1.2.3-70-g09d2 From 2d4ae2745485890d333f5b08bb7e484b5abfce85 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:11:20 +0200 Subject: Added back a simple_command() where path changes and stuff had to be done. For now.. this surely must work by doing os.chdir() or something --- archinstall.py | 51 +++++++++++++++++++++++++-------------------------- 1 file changed, 25 insertions(+), 26 deletions(-) diff --git a/archinstall.py b/archinstall.py index d48d50e7..413ce171 100644 --- a/archinstall.py +++ b/archinstall.py @@ -170,31 +170,30 @@ class sys_command(): yield output - x = os.waitpid(self.pid, 0) - print('Exited with:', x) - -# def sys_command(cmd, echo=False, opts=None, *args, **kwargs): -# if not opts: opts = {} -# if echo or 'debug' in opts: -# print('[!] {}'.format(cmd)) -# handle = Popen(cmd, shell='True', stdout=PIPE, stderr=STDOUT, stdin=PIPE, **kwargs) -# output = b'' -# while handle.poll() is None: -# data = handle.stdout.read() -# if b'or press Control-D' in data: -# handle.stdin.write(b'') -# if len(data): -# if echo or 'debug' in opts: -# print(data.decode('UTF-8'), end='') -# # print(data.decode('UTF-8'), end='') -# output += data -# data = handle.stdout.read() -# if echo or 'debug' in opts: -# print(data.decode('UTF-8'), end='') -# output += data -# handle.stdin.close() -# handle.stdout.close() -# return output + exit_code = os.waitpid(self.pid, 0)[1] + if exit_code != 0: + print('[E] Command "{}" exited with status code:'.format(self.cmd[0]), exit_code) + +def simple_command(cmd, opts=None, *args, **kwargs): + if not opts: opts = {} + if echo or 'debug' in opts: + print('[!] {}'.format(cmd)) + handle = Popen(cmd, shell='True', stdout=PIPE, stderr=STDOUT, stdin=PIPE, **kwargs) + output = b'' + while handle.poll() is None: + data = handle.stdout.read() + if len(data): + if echo or 'debug' in opts: + print(data.decode('UTF-8'), end='') + # print(data.decode('UTF-8'), end='') + output += data + data = handle.stdout.read() + if echo or 'debug' in opts: + print(data.decode('UTF-8'), end='') + output += data + handle.stdin.close() + handle.stdout.close() + return output def update_git(): default_gw = get_default_gateway_linux() @@ -204,7 +203,7 @@ def update_git(): os.remove('/root/archinstall/archinstall.py') os.remove('/root/archinstall/README.md') - output = b''.join(sys_command('(cd /root/archinstall; git reset --hard origin/$(git branch | grep "*" | cut -d\' \' -f 2))').exec()) # git reset --hard origin/ / git fetch --all + simple_command('(cd /root/archinstall; git reset --hard origin/$(git branch | grep "*" | cut -d\' \' -f 2))') # git reset --hard origin/ / git fetch --all print(output) if b'error:' in output: -- cgit v1.2.3-70-g09d2 From 15cdae12cc094d37763938c9021d06550a746a2d Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:11:57 +0200 Subject: erm, echo was removed.. since it's part of the opts now --- archinstall.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/archinstall.py b/archinstall.py index 413ce171..26b1757e 100644 --- a/archinstall.py +++ b/archinstall.py @@ -176,19 +176,19 @@ class sys_command(): def simple_command(cmd, opts=None, *args, **kwargs): if not opts: opts = {} - if echo or 'debug' in opts: + if 'debug' in opts: print('[!] {}'.format(cmd)) handle = Popen(cmd, shell='True', stdout=PIPE, stderr=STDOUT, stdin=PIPE, **kwargs) output = b'' while handle.poll() is None: data = handle.stdout.read() if len(data): - if echo or 'debug' in opts: + if 'debug' in opts: print(data.decode('UTF-8'), end='') # print(data.decode('UTF-8'), end='') output += data data = handle.stdout.read() - if echo or 'debug' in opts: + if 'debug' in opts: print(data.decode('UTF-8'), end='') output += data handle.stdin.close() -- cgit v1.2.3-70-g09d2 From 687685809af694ffeb3cc04570c51c2f500b1208 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:12:59 +0200 Subject: Error when removing a non-existing file.. duh.. --- archinstall.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index 26b1757e..020f9790 100644 --- a/archinstall.py +++ b/archinstall.py @@ -200,8 +200,10 @@ def update_git(): if(default_gw): print('[N] Updating git!') ## Not the most elegant way to make sure git conflicts doesn't occur (yea fml) - os.remove('/root/archinstall/archinstall.py') - os.remove('/root/archinstall/README.md') + if os.path.isfile('/root/archinstall/archinstall.py'): + os.remove('/root/archinstall/archinstall.py') + if os.path.isfile('/root/archinstall/README.md'): + os.remove('/root/archinstall/README.md') simple_command('(cd /root/archinstall; git reset --hard origin/$(git branch | grep "*" | cut -d\' \' -f 2))') # git reset --hard origin/ / git fetch --all print(output) -- cgit v1.2.3-70-g09d2 From 3fb42df1626b6328864620c577b1e2b7e1b0c278 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:13:25 +0200 Subject: Forgot to place the output some where.. oh i know.. in output... --- archinstall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index 020f9790..7bfac35d 100644 --- a/archinstall.py +++ b/archinstall.py @@ -205,7 +205,7 @@ def update_git(): if os.path.isfile('/root/archinstall/README.md'): os.remove('/root/archinstall/README.md') - simple_command('(cd /root/archinstall; git reset --hard origin/$(git branch | grep "*" | cut -d\' \' -f 2))') # git reset --hard origin/ / git fetch --all + output = simple_command('(cd /root/archinstall; git reset --hard origin/$(git branch | grep "*" | cut -d\' \' -f 2))') # git reset --hard origin/ / git fetch --all print(output) if b'error:' in output: -- cgit v1.2.3-70-g09d2 From 80d7fca43d73bde4576f239c95e94388cc2b1a23 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:15:17 +0200 Subject: Fixed a output message --- archinstall.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/archinstall.py b/archinstall.py index 7bfac35d..f76911a8 100644 --- a/archinstall.py +++ b/archinstall.py @@ -205,7 +205,7 @@ def update_git(): if os.path.isfile('/root/archinstall/README.md'): os.remove('/root/archinstall/README.md') - output = simple_command('(cd /root/archinstall; git reset --hard origin/$(git branch | grep "*" | cut -d\' \' -f 2))') # git reset --hard origin/ / git fetch --all + output = simple_command('(cd /root/archinstall; git reset --hard origin/$(git branch | grep "*" | cut -d\' \' -f 2); git pull)') print(output) if b'error:' in output: @@ -466,8 +466,8 @@ if __name__ == '__main__': exit(1) o = sys_command('/usr/bin/cryptsetup open {drive}{partition_2} luksdev --key-file {pwfile} --type luks2'.format(**args)).exec() - o = sys_command('/usr/bin/file /dev/mapper/luksdev').exec() # /dev/dm-0 - if b'cannot open' in b''.join(o): + o = b''.join(sys_command('/usr/bin/file /dev/mapper/luksdev').exec()) # /dev/dm-0 + if b'cannot open' in o: print('[E] Could not mount encrypted device.', o) exit(1) -- cgit v1.2.3-70-g09d2 From 5b44456a55f30ca554cb94040e9da3814d8c7dc7 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:18:16 +0200 Subject: Editing more outputs --- archinstall.py | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/archinstall.py b/archinstall.py index f76911a8..af86ed37 100644 --- a/archinstall.py +++ b/archinstall.py @@ -249,7 +249,10 @@ def grab_partitions(dev): ## and make sys_command() return the exit-code, way safer than checking output strings :P return {} - print(o) + if not o[:1] == b'{': + print('[E] Error in getting blk devices:', o) + exit(1) + r = json.loads(o.decode('UTF-8')) if len(r['blockdevices']) and 'children' in r['blockdevices'][0]: for part in r['blockdevices'][0]['children']: @@ -460,8 +463,9 @@ if __name__ == '__main__': # "--cipher sha512" breaks the shit. # TODO: --use-random instead of --use-urandom print('[N] Adding encryption to {drive}{partition_2}.'.format(**args)) - o = sys_command('/usr/bin/cryptsetup -q -v --type luks2 --pbkdf argon2i --hash sha512 --key-size 512 --iter-time 10000 --key-file {pwfile} --use-urandom luksFormat {drive}{partition_2}'.format(**args)).exec() - if not 'Command successful.' in b''.join(o).decode('UTF-8').strip(): + o = b''.join(sys_command('/usr/bin/cryptsetup -q -v --type luks2 --pbkdf argon2i --hash sha512 --key-size 512 --iter-time 10000 --key-file {pwfile} --use-urandom luksFormat {drive}{partition_2}'.format(**args)).exec()) + print(o) + if not b'Command successful.' in o: print('[E] Failed to setup disk encryption.', o) exit(1) -- cgit v1.2.3-70-g09d2 From dd0f2f9d565d3567371485d36299b39fac97d579 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:24:45 +0200 Subject: Forgot that iterators don't actually do anything unless you **try** to work with the output result. Optimizations ftw --- archinstall.py | 95 +++++++++++++++++++++++++++++----------------------------- 1 file changed, 47 insertions(+), 48 deletions(-) diff --git a/archinstall.py b/archinstall.py index af86ed37..4fc31fe2 100644 --- a/archinstall.py +++ b/archinstall.py @@ -138,7 +138,7 @@ class sys_command(): if not self.cmd[0][0] == '/': print('[N] Command is not executed with absolute path, trying to find it..') o = b''.join(sys_command('/usr/bin/whereis {}'.format(self.cmd[0])).exec()) - self.cmd[0] = o.split(b' ', 1)[0].decode('UTF-8') + self.cmd[0] = o.split(b' ')[1].decode('UTF-8') print('[N] This is what I\'m going with: {}'.format(self.cmd[0])) # PID = 0 for child, and the PID of the child for the parent self.pid, child_fd = pty.fork() @@ -441,19 +441,19 @@ if __name__ == '__main__': print('[N] Setting up {drive}.'.format(**args)) # dd if=/dev/random of=args['drive'] bs=4096 status=progress # https://github.com/dcantrell/pyparted would be nice, but isn't officially in the repo's #SadPanda - o = sys_command('/usr/bin/parted -s {drive} mklabel gpt'.format(**args)).exec() - o = sys_command('/usr/bin/parted -s {drive} mkpart primary FAT32 1MiB {start}'.format(**args)).exec() - o = sys_command('/usr/bin/parted -s {drive} name 1 "EFI"'.format(**args)).exec() - o = sys_command('/usr/bin/parted -s {drive} set 1 esp on'.format(**args)).exec() - o = sys_command('/usr/bin/parted -s {drive} set 1 boot on'.format(**args)).exec() - o = sys_command('/usr/bin/parted -s {drive} mkpart primary {start} {size}'.format(**args)).exec() + o = b''.join(sys_command('/usr/bin/parted -s {drive} mklabel gpt'.format(**args)).exec()) + o = b''.join(sys_command('/usr/bin/parted -s {drive} mkpart primary FAT32 1MiB {start}'.format(**args)).exec()) + o = b''.join(sys_command('/usr/bin/parted -s {drive} name 1 "EFI"'.format(**args)).exec()) + o = b''.join(sys_command('/usr/bin/parted -s {drive} set 1 esp on'.format(**args)).exec()) + o = b''.join(sys_command('/usr/bin/parted -s {drive} set 1 boot on'.format(**args)).exec()) + o = b''.join(sys_command('/usr/bin/parted -s {drive} mkpart primary {start} {size}'.format(**args)).exec()) args['paritions'] = grab_partitions(args['drive']) if len(args['paritions']) <= 0: print('[E] No paritions were created on {drive}'.format(**args), o) exit(1) for index, part_name in enumerate(args['paritions']): - args['partition_{}'.format(index+1)] = part_name + args['partition_{}'.format(index+1)] = part_name o = b''.join(sys_command('/usr/bin/mkfs.vfat -F32 {drive}{partition_1}'.format(**args)).exec()) if (b'mkfs.fat' not in o and b'mkfs.vfat' not in o) or b'command not found' in o: @@ -464,32 +464,31 @@ if __name__ == '__main__': # TODO: --use-random instead of --use-urandom print('[N] Adding encryption to {drive}{partition_2}.'.format(**args)) o = b''.join(sys_command('/usr/bin/cryptsetup -q -v --type luks2 --pbkdf argon2i --hash sha512 --key-size 512 --iter-time 10000 --key-file {pwfile} --use-urandom luksFormat {drive}{partition_2}'.format(**args)).exec()) - print(o) if not b'Command successful.' in o: print('[E] Failed to setup disk encryption.', o) exit(1) - o = sys_command('/usr/bin/cryptsetup open {drive}{partition_2} luksdev --key-file {pwfile} --type luks2'.format(**args)).exec() + o = b''.join(sys_command('/usr/bin/cryptsetup open {drive}{partition_2} luksdev --key-file {pwfile} --type luks2'.format(**args)).exec()) o = b''.join(sys_command('/usr/bin/file /dev/mapper/luksdev').exec()) # /dev/dm-0 if b'cannot open' in o: print('[E] Could not mount encrypted device.', o) exit(1) print('[N] Creating btrfs filesystem inside {drive}{partition_2}'.format(**args)) - o = sys_command('/usr/bin/mkfs.btrfs /dev/mapper/luksdev').exec() - if not b'UUID' in b''.join(o): + o = b''.join(sys_command('/usr/bin/mkfs.btrfs /dev/mapper/luksdev').exec()) + if not b'UUID' in o: print('[E] Could not setup btrfs filesystem.', o) exit(1) - o = sys_command('/usr/bin/mount /dev/mapper/luksdev /mnt').exec() + o = b''.join(sys_command('/usr/bin/mount /dev/mapper/luksdev /mnt').exec()) os.makedirs('/mnt/boot') - o = sys_command('/usr/bin/mount {drive}{partition_1} /mnt/boot'.format(**args)).exec() + o = b''.join(sys_command('/usr/bin/mount {drive}{partition_1} /mnt/boot'.format(**args)).exec()) print('[N] Reordering mirrors.') if 'mirrors' in args and args['mirrors'] and get_default_gateway_linux(): - o = sys_command("/usr/bin/wget 'https://www.archlinux.org/mirrorlist/?country={country}&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on' -O /root/mirrorlist".format(**args)).exec() - o = sys_command("/usr/bin/sed -i 's/#Server/Server/' /root/mirrorlist").exec() - o = sys_command('/usr/bin/rankmirrors -n 6 /root/mirrorlist > /etc/pacman.d/mirrorlist').exec() + o = b''.join(sys_command("/usr/bin/wget 'https://www.archlinux.org/mirrorlist/?country={country}&protocol=https&ip_version=4&ip_version=6&use_mirror_status=on' -O /root/mirrorlist".format(**args)).exec()) + o = b''.join(sys_command("/usr/bin/sed -i 's/#Server/Server/' /root/mirrorlist").exec()) + o = b''.join(sys_command('/usr/bin/rankmirrors -n 6 /root/mirrorlist > /etc/pacman.d/mirrorlist').exec()) pre_conf = {} if 'pre' in instructions: @@ -522,33 +521,33 @@ if __name__ == '__main__': print('[-] Options: {}'.format(opts)) #print('[N] Command: {} ({})'.format(raw_command, opts)) - o = sys_command('{c}'.format(c=command), opts).exec() + o = b''.join(sys_command('{c}'.format(c=command), opts).exec()) if type(conf[title][raw_command]) == bytes and len(conf[title][raw_command]) and not conf[title][raw_command] in b''.join(o): print('[W] Prerequisit step failed: {}'.format(b''.join(o).decode('UTF-8'))) #print(o) print('[N] Straping in packages.') - o = sys_command('/usr/bin/pacman -Syy').exec() - o = sys_command('/usr/bin/pacstrap /mnt base base-devel btrfs-progs efibootmgr nano wpa_supplicant dialog {packages}'.format(**args)).exec() + o = b''.join(sys_command('/usr/bin/pacman -Syy').exec()) + o = b''.join(sys_command('/usr/bin/pacstrap /mnt base base-devel btrfs-progs efibootmgr nano wpa_supplicant dialog {packages}'.format(**args)).exec()) if not os.path.isdir('/mnt/etc'): print('[E] Failed to strap in packages', o) exit(1) - o = sys_command('/usr/bin/genfstab -pU /mnt >> /mnt/etc/fstab').exec() + o = b''.join(sys_command('/usr/bin/genfstab -pU /mnt >> /mnt/etc/fstab').exec()) with open('/mnt/etc/fstab', 'a') as fstab: fstab.write('\ntmpfs /tmp tmpfs defaults,noatime,mode=1777 0 0\n') # Redundant \n at the start? who knoes? - o = sys_command('/usr/bin/arch-chroot /mnt rm /etc/localtime').exec() - o = sys_command('/usr/bin/arch-chroot /mnt ln -s /usr/share/zoneinfo/Europe/Stockholm /etc/localtime').exec() - o = sys_command('/usr/bin/arch-chroot /mnt hwclock --hctosys --localtime').exec() + o = b''.join(sys_command('/usr/bin/arch-chroot /mnt rm /etc/localtime').exec()) + o = b''.join(sys_command('/usr/bin/arch-chroot /mnt ln -s /usr/share/zoneinfo/Europe/Stockholm /etc/localtime').exec()) + o = b''.join(sys_command('/usr/bin/arch-chroot /mnt hwclock --hctosys --localtime').exec()) #o = sys_command('arch-chroot /mnt echo "{hostname}" > /etc/hostname'.format(**args)).exec() #o = sys_command("arch-chroot /mnt sed -i 's/#\(en_US\.UTF-8\)/\1/' /etc/locale.gen").exec() - o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo '{hostname}' > /etc/hostname\"".format(**args)).exec() - o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen\"").exec() - o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'LANG=en_US.UTF-8' > /etc/locale.conf\"").exec() - o = sys_command('/usr/bin/arch-chroot /mnt locale-gen').exec() - o = sys_command('/usr/bin/arch-chroot /mnt chmod 700 /root').exec() + o = b''.join(sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo '{hostname}' > /etc/hostname\"".format(**args)).exec()) + o = b''.join(sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'en_US.UTF-8 UTF-8' > /etc/locale.gen\"").exec()) + o = b''.join(sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'LANG=en_US.UTF-8' > /etc/locale.conf\"").exec()) + o = b''.join(sys_command('/usr/bin/arch-chroot /mnt locale-gen').exec()) + o = b''.join(sys_command('/usr/bin/arch-chroot /mnt chmod 700 /root').exec()) with open('/mnt/etc/mkinitcpio.conf', 'w') as mkinit: ## TODO: Don't replace it, in case some update in the future actually adds something. @@ -556,8 +555,8 @@ if __name__ == '__main__': mkinit.write('BINARIES=(/usr/bin/btrfs)\n') mkinit.write('FILES=()\n') mkinit.write('HOOKS=(base udev autodetect modconf block encrypt filesystems keyboard fsck)\n') - o = sys_command('/usr/bin/arch-chroot /mnt mkinitcpio -p linux').exec() - o = sys_command('/usr/bin/arch-chroot /mnt bootctl --path=/boot install').exec() + o = b''.join(sys_command('/usr/bin/arch-chroot /mnt mkinitcpio -p linux').exec()) + o = b''.join(sys_command('/usr/bin/arch-chroot /mnt bootctl --path=/boot install').exec()) with open('/mnt/boot/loader/loader.conf', 'w') as loader: loader.write('default arch\n') @@ -608,25 +607,25 @@ if __name__ == '__main__': ## Either skipping mounting /run and using traditional chroot is an option, but using ## `systemd-nspawn -D /mnt --machine temporary` might be a more flexible solution in case of file structure changes. if 'no-chroot' in opts and opts['no-chroot']: - o = sys_command(command, opts).exec() + o = b''.join(sys_command(command, opts).exec()) elif 'chroot' in opts and opts['chroot']: ## Run in a manually set up version of arch-chroot (arch-chroot will break namespaces). ## This is a bit risky in case the file systems changes over the years, but we'll probably be safe adding this as an option. ## **> Prefer if possible to use 'no-chroot' instead which "live boots" the OS and runs the command. - o = sys_command("/usr/bin/mount /dev/mapper/luksdev /mnt").exec() - o = sys_command("cd /mnt; cp /etc/resolv.conf etc").exec() - o = sys_command("cd /mnt; /usr/bin/mount -t proc /proc proc").exec() - o = sys_command("cd /mnt; /usr/bin/mount --make-rslave --rbind /sys sys").exec() - o = sys_command("cd /mnt; /usr/bin/mount --make-rslave --rbind /dev dev").exec() - o = sys_command('/usr/bin/chroot /mnt /bin/bash -c "{c}"'.format(c=command), opts=opts).exec() - o = sys_command("cd /mnt; /usr/bin/umount -R dev").exec() - o = sys_command("cd /mnt; /usr/bin/umount -R sys").exec() - o = sys_command("cd /mnt; /usr/bin/umount -R proc").exec() + o = b''.join(sys_command("/usr/bin/mount /dev/mapper/luksdev /mnt").exec()) + o = b''.join(sys_command("cd /mnt; cp /etc/resolv.conf etc").exec()) + o = b''.join(sys_command("cd /mnt; /usr/bin/mount -t proc /proc proc").exec()) + o = b''.join(sys_command("cd /mnt; /usr/bin/mount --make-rslave --rbind /sys sys").exec()) + o = b''.join(sys_command("cd /mnt; /usr/bin/mount --make-rslave --rbind /dev dev").exec()) + o = b''.join(sys_command('/usr/bin/chroot /mnt /bin/bash -c "{c}"'.format(c=command), opts=opts).exec()) + o = b''.join(sys_command("cd /mnt; /usr/bin/umount -R dev").exec()) + o = b''.join(sys_command("cd /mnt; /usr/bin/umount -R sys").exec()) + o = b''.join(sys_command("cd /mnt; /usr/bin/umount -R proc").exec()) else: if 'boot' in opts and opts['boot']: - o = sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary {c}'.format(c=command), opts=opts).exec() + o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary {c}'.format(c=command), opts=opts).exec()) else: - o = sys_command('/usr/bin/systemd-nspawn -D /mnt --machine temporary {c}'.format(c=command), opts=opts).exec() + o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt --machine temporary {c}'.format(c=command), opts=opts).exec()) if type(conf[title][raw_command]) == bytes and len(conf[title][raw_command]) and not conf[title][raw_command] in o: print('[W] Post install command failed: {}'.format(o.decode('UTF-8'))) #print(o) @@ -634,13 +633,13 @@ if __name__ == '__main__': ## == Passwords # o = sys_command('arch-chroot /mnt usermod --password {} root'.format(args['password'])) # o = sys_command("arch-chroot /mnt sh -c 'echo {pin} | passwd --stdin root'".format(pin='"{pin}"'.format(**args, pin=args['password'])), echo=True) - o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'root:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec() + o = b''.join(sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'root:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec()) if 'user' in args: - o = sys_command('/usr/bin/arch-chroot /mnt useradd -m -G wheel {user}'.format(**args)).exec() - o = sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo '{user}:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec() + o = b''.join(sys_command('/usr/bin/arch-chroot /mnt useradd -m -G wheel {user}'.format(**args)).exec()) + o = b''.join(sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo '{user}:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec()) if args['post'] == 'reboot': - o = sys_command('/usr/bin/umount -R /mnt').exec() - o = sys_command('/usr/bin/reboot now').exec() + o = b''.join(sys_command('/usr/bin/umount -R /mnt').exec()) + o = b''.join(sys_command('/usr/bin/reboot now').exec()) else: print('Done. "umount -R /mnt; reboot" when you\'re done tinkering.') -- cgit v1.2.3-70-g09d2 From fdf01f0cf68081218993422885082ac2937f1608 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:26:43 +0200 Subject: Skipping re-exec for when git repo is already up to date --- archinstall.py | 21 +++++++++++---------- 1 file changed, 11 insertions(+), 10 deletions(-) diff --git a/archinstall.py b/archinstall.py index 4fc31fe2..27d415cc 100644 --- a/archinstall.py +++ b/archinstall.py @@ -173,6 +173,7 @@ class sys_command(): exit_code = os.waitpid(self.pid, 0)[1] if exit_code != 0: print('[E] Command "{}" exited with status code:'.format(self.cmd[0]), exit_code) + exit(1) def simple_command(cmd, opts=None, *args, **kwargs): if not opts: opts = {} @@ -206,22 +207,22 @@ def update_git(): os.remove('/root/archinstall/README.md') output = simple_command('(cd /root/archinstall; git reset --hard origin/$(git branch | grep "*" | cut -d\' \' -f 2); git pull)') - print(output) if b'error:' in output: print('[N] Could not update git source for some reason.') return # b'From github.com:Torxed/archinstall\n 339d687..80b97f3 master -> origin/master\nUpdating 339d687..80b97f3\nFast-forward\n README.md | 2 +-\n 1 file changed, 1 insertion(+), 1 deletion(-)\n' - tmp = re.findall(b'[0-9]+ file changed', output) - print(tmp) - if len(tmp): - num_changes = int(tmp[0].split(b' ',1)[0]) - if(num_changes): - ## Reboot the script (in same context) - print('[N] Rebooting the script') - os.execv('/usr/bin/python3', ['archinstall.py'] + sys.argv) - extit(1) + if not b'Already up to date' in output: + tmp = re.findall(b'[0-9]+ file changed', output) + print(tmp) + if len(tmp): + num_changes = int(tmp[0].split(b' ',1)[0]) + if(num_changes): + ## Reboot the script (in same context) + print('[N] Rebooting the script') + os.execv('/usr/bin/python3', ['archinstall.py'] + sys.argv) + extit(1) def device_state(name): # Based out of: https://askubuntu.com/questions/528690/how-to-get-list-of-all-non-removable-disk-device-names-ssd-hdd-and-sata-ide-onl/528709#528709 -- cgit v1.2.3-70-g09d2 From 47feba166eb75707882ed0e8a68589e26d76e835 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:33:34 +0200 Subject: Almost there --- archinstall.py | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index 27d415cc..56892d25 100644 --- a/archinstall.py +++ b/archinstall.py @@ -151,10 +151,12 @@ class sys_command(): poller.register(child_fd, EPOLLIN | EPOLLHUP) alive = True + trace_log = b'' while alive: for fileno, event in poller.poll(0.1): try: output = os.read(child_fd, 1024).strip() + trace_log += output except OSError: alive = False break @@ -173,6 +175,7 @@ class sys_command(): exit_code = os.waitpid(self.pid, 0)[1] if exit_code != 0: print('[E] Command "{}" exited with status code:'.format(self.cmd[0]), exit_code) + print(trace_log) exit(1) def simple_command(cmd, opts=None, *args, **kwargs): @@ -566,7 +569,7 @@ if __name__ == '__main__': ## For some reason, blkid and /dev/disk/by-uuid are not getting along well. ## And blkid is wrong in terms of LUKS. #UUID = sys_command('blkid -s PARTUUID -o value {drive}{partition_2}'.format(**args)).decode('UTF-8').exec().strip() - UUID = b''.join(sys_command("ls -l /dev/disk/by-uuid/ | grep {basename}{partition_2} | awk '{{print $9}}'".format(basename=os.path.basename(args['drive']), **args)).exec()).decode('UTF-8').strip() + UUID = b''.join(sys_command("/usr/bin/ls -l /dev/disk/by-uuid/ | grep {basename}{partition_2} | awk '{{print $9}}'".format(basename=os.path.basename(args['drive']), **args)).exec()).decode('UTF-8').strip() with open('/mnt/boot/loader/entries/arch.conf', 'w') as entry: entry.write('title Arch Linux\n') entry.write('linux /vmlinuz-linux\n') @@ -624,7 +627,21 @@ if __name__ == '__main__': o = b''.join(sys_command("cd /mnt; /usr/bin/umount -R proc").exec()) else: if 'boot' in opts and opts['boot']: + ## So, if we're going to boot this maddafakker up, we'll need to + ## be able to login. The quickest way is to just add automatic login.. so lessgo! + + if not os.path.isdir('/mnt/etc/systemd/system/console-getty.service.d/'): + os.makedirs('/mnt/etc/systemd/system/console-getty.service.d/') + with open('/mnt/etc/systemd/system/console-getty.service.d/override.conf', 'w') as fh: + fh.write('[Service]\n') + fh.write('ExecStart=\n') + fh.write('ExecStart=-/usr/bin/agetty --autologin root -s %I 115200,38400,9600 vt102\n') + + ## And then boot and execute: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary {c}'.format(c=command), opts=opts).exec()) + + ## And cleanup after out selves.. Don't want to leave any residue.. + os.remove('/mnt/etc/systemd/system/console-getty.service.d/override.conf') else: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt --machine temporary {c}'.format(c=command), opts=opts).exec()) if type(conf[title][raw_command]) == bytes and len(conf[title][raw_command]) and not conf[title][raw_command] in o: -- cgit v1.2.3-70-g09d2 From 69de48da7d2ef45cb388d808468d1a0e158b59e9 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:37:50 +0200 Subject: Swapped for simple_command on multiple pipe command.. it's to messy heh --- archinstall.py | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/archinstall.py b/archinstall.py index 56892d25..d04af178 100644 --- a/archinstall.py +++ b/archinstall.py @@ -9,6 +9,10 @@ from collections import OrderedDict as oDict from subprocess import Popen, STDOUT, PIPE from time import sleep +## == Profiles Path can be set via --profiles-path=/path +## This just sets the default path if the parameter is omitted. +profiles_path = 'https://raw.githubusercontent.com/Torxed/archinstall/master/deployments' + try: import psutil except: @@ -72,10 +76,6 @@ except: rootdir_pattern = re.compile('^.*?/devices') harddrives = oDict() -## == Profiles Path can be set via --profiles-path=/path -## This just sets the default path if the parameter is omitted. -profiles_path = 'https://raw.githubusercontent.com/Torxed/archinstall/master/deployments' - args = {} positionals = [] for arg in sys.argv[1:]: @@ -202,7 +202,7 @@ def simple_command(cmd, opts=None, *args, **kwargs): def update_git(): default_gw = get_default_gateway_linux() if(default_gw): - print('[N] Updating git!') + print('[N] Checking for updates...') ## Not the most elegant way to make sure git conflicts doesn't occur (yea fml) if os.path.isfile('/root/archinstall/archinstall.py'): os.remove('/root/archinstall/archinstall.py') @@ -569,7 +569,7 @@ if __name__ == '__main__': ## For some reason, blkid and /dev/disk/by-uuid are not getting along well. ## And blkid is wrong in terms of LUKS. #UUID = sys_command('blkid -s PARTUUID -o value {drive}{partition_2}'.format(**args)).decode('UTF-8').exec().strip() - UUID = b''.join(sys_command("/usr/bin/ls -l /dev/disk/by-uuid/ | grep {basename}{partition_2} | awk '{{print $9}}'".format(basename=os.path.basename(args['drive']), **args)).exec()).decode('UTF-8').strip() + UUID = simple_command("ls -l /dev/disk/by-uuid/ | grep {basename}{partition_2} | awk '{{print $9}}'".format(basename=os.path.basename(args['drive']), **args)).decode('UTF-8').strip() with open('/mnt/boot/loader/entries/arch.conf', 'w') as entry: entry.write('title Arch Linux\n') entry.write('linux /vmlinuz-linux\n') -- cgit v1.2.3-70-g09d2 From cc917661611d2439d84dd259e0dbfad470806a51 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:46:14 +0200 Subject: Increased read buffer from 1024 to 8192. Also added the command as a trigger --- archinstall.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index d04af178..ec356021 100644 --- a/archinstall.py +++ b/archinstall.py @@ -155,7 +155,7 @@ class sys_command(): while alive: for fileno, event in poller.poll(0.1): try: - output = os.read(child_fd, 1024).strip() + output = os.read(child_fd, 8192).strip() trace_log += output except OSError: alive = False @@ -638,7 +638,7 @@ if __name__ == '__main__': fh.write('ExecStart=-/usr/bin/agetty --autologin root -s %I 115200,38400,9600 vt102\n') ## And then boot and execute: - o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary {c}'.format(c=command), opts=opts).exec()) + o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : {b'Graphical Interface' : command}, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. os.remove('/mnt/etc/systemd/system/console-getty.service.d/override.conf') -- cgit v1.2.3-70-g09d2 From 4c37e916f8293696a0ef04a06775b4e7e7fad665 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:51:48 +0200 Subject: Writing needs to be bytes --- archinstall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index ec356021..4d6f5e48 100644 --- a/archinstall.py +++ b/archinstall.py @@ -638,7 +638,7 @@ if __name__ == '__main__': fh.write('ExecStart=-/usr/bin/agetty --autologin root -s %I 115200,38400,9600 vt102\n') ## And then boot and execute: - o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : {b'Graphical Interface' : command}, **opts}).exec()) + o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : {b'Graphical Interface' : bytes(command, 'UTF-8')}, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. os.remove('/mnt/etc/systemd/system/console-getty.service.d/override.conf') -- cgit v1.2.3-70-g09d2 From 53c95fc1b8c431f420aec2cc0e924e557907d651 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 21:57:53 +0200 Subject: Trying something else --- archinstall.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/archinstall.py b/archinstall.py index 4d6f5e48..f2d23b5b 100644 --- a/archinstall.py +++ b/archinstall.py @@ -630,18 +630,18 @@ if __name__ == '__main__': ## So, if we're going to boot this maddafakker up, we'll need to ## be able to login. The quickest way is to just add automatic login.. so lessgo! - if not os.path.isdir('/mnt/etc/systemd/system/console-getty.service.d/'): - os.makedirs('/mnt/etc/systemd/system/console-getty.service.d/') - with open('/mnt/etc/systemd/system/console-getty.service.d/override.conf', 'w') as fh: - fh.write('[Service]\n') - fh.write('ExecStart=\n') - fh.write('ExecStart=-/usr/bin/agetty --autologin root -s %I 115200,38400,9600 vt102\n') + # if not os.path.isdir('/mnt/etc/systemd/system/console-getty.service.d/'): + # os.makedirs('/mnt/etc/systemd/system/console-getty.service.d/') + # with open('/mnt/etc/systemd/system/console-getty.service.d/override.conf', 'w') as fh: + # fh.write('[Service]\n') + # fh.write('ExecStart=\n') + # fh.write('ExecStart=-/usr/bin/agetty --autologin root -s %I 115200,38400,9600 vt102\n') ## And then boot and execute: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : {b'Graphical Interface' : bytes(command, 'UTF-8')}, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. - os.remove('/mnt/etc/systemd/system/console-getty.service.d/override.conf') + # os.remove('/mnt/etc/systemd/system/console-getty.service.d/override.conf') else: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt --machine temporary {c}'.format(c=command), opts=opts).exec()) if type(conf[title][raw_command]) == bytes and len(conf[title][raw_command]) and not conf[title][raw_command] in o: -- cgit v1.2.3-70-g09d2 From efc7f0cc48ecbe9870af69e3c47191bbd60380b1 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:06:22 +0200 Subject: Handling login during pseudo-boot --- archinstall.py | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index f2d23b5b..8d99cfdc 100644 --- a/archinstall.py +++ b/archinstall.py @@ -638,7 +638,11 @@ if __name__ == '__main__': # fh.write('ExecStart=-/usr/bin/agetty --autologin root -s %I 115200,38400,9600 vt102\n') ## And then boot and execute: - o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : {b'Graphical Interface' : bytes(command, 'UTF-8')}, **opts}).exec()) + o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { + b'Archinstall login:' : b'root', + b'Password' : bytes(args['password'], 'UTF-8'), + b'root#' : bytes(command, 'UTF-8'), + }, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. # os.remove('/mnt/etc/systemd/system/console-getty.service.d/override.conf') -- cgit v1.2.3-70-g09d2 From 1e35a8b096cc45f9da2a5e72e7fdd2f2e64aa33a Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:13:09 +0200 Subject: live testing --- archinstall.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index 8d99cfdc..0b602863 100644 --- a/archinstall.py +++ b/archinstall.py @@ -162,11 +162,13 @@ class sys_command(): break if 'debug' in self.opts and self.opts['debug']: - print(output) + if len(output): + print(output) lower = output.lower() if 'triggers' in self.opts: for trigger in self.opts['triggers']: + print(trigger.lower(),'vs', lower) if trigger.lower() in lower: os.write(child_fd, self.opts['triggers'][trigger]) @@ -639,7 +641,7 @@ if __name__ == '__main__': ## And then boot and execute: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { - b'Archinstall login:' : b'root', + b'Archinstall login' : b'root', b'Password' : bytes(args['password'], 'UTF-8'), b'root#' : bytes(command, 'UTF-8'), }, **opts}).exec()) -- cgit v1.2.3-70-g09d2 From 074efd4c1c5ef5a4eb10fcf008a36886fb4e4587 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:18:50 +0200 Subject: Live testing --- archinstall.py | 1 + 1 file changed, 1 insertion(+) diff --git a/archinstall.py b/archinstall.py index 0b602863..2d361a88 100644 --- a/archinstall.py +++ b/archinstall.py @@ -170,6 +170,7 @@ class sys_command(): for trigger in self.opts['triggers']: print(trigger.lower(),'vs', lower) if trigger.lower() in lower: + print('[N] Writing to subsystem: {}'.format(trigger)) os.write(child_fd, self.opts['triggers'][trigger]) yield output -- cgit v1.2.3-70-g09d2 From fc4cad6c19eace1bb0c6d572bed56f02963f1f3a Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:22:42 +0200 Subject: Forgot ENTER (new line) after subsystem input --- archinstall.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/archinstall.py b/archinstall.py index 2d361a88..598eb091 100644 --- a/archinstall.py +++ b/archinstall.py @@ -642,9 +642,9 @@ if __name__ == '__main__': ## And then boot and execute: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { - b'Archinstall login' : b'root', - b'Password' : bytes(args['password'], 'UTF-8'), - b'root#' : bytes(command, 'UTF-8'), + b'Archinstall login' : b'root\n', + b'Password' : bytes(args['password']+'\n', 'UTF-8'), + b'root#' : bytes(command+'\n', 'UTF-8'), }, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. -- cgit v1.2.3-70-g09d2 From 4f3388f363204288aecbc8791c46a83b9462ec51 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:25:02 +0200 Subject: misspelling --- archinstall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index 598eb091..be5eb69c 100644 --- a/archinstall.py +++ b/archinstall.py @@ -642,7 +642,7 @@ if __name__ == '__main__': ## And then boot and execute: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { - b'Archinstall login' : b'root\n', + b'Arcinstall login' : b'root\n', b'Password' : bytes(args['password']+'\n', 'UTF-8'), b'root#' : bytes(command+'\n', 'UTF-8'), }, **opts}).exec()) -- cgit v1.2.3-70-g09d2 From b27c10907ff0c14c912a85377b5b879d19720e03 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:30:53 +0200 Subject: Testing live --- archinstall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index be5eb69c..0f911afd 100644 --- a/archinstall.py +++ b/archinstall.py @@ -644,7 +644,7 @@ if __name__ == '__main__': o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { b'Arcinstall login' : b'root\n', b'Password' : bytes(args['password']+'\n', 'UTF-8'), - b'root#' : bytes(command+'\n', 'UTF-8'), + b'[root@Archinstall ~]#' : bytes(command+'\n', 'UTF-8'), }, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. -- cgit v1.2.3-70-g09d2 From 21322ecadbe4b47b429cbdb66a1a8065200111e0 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:36:31 +0200 Subject: misspelling --- archinstall.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index 0f911afd..f1a33d4e 100644 --- a/archinstall.py +++ b/archinstall.py @@ -170,7 +170,7 @@ class sys_command(): for trigger in self.opts['triggers']: print(trigger.lower(),'vs', lower) if trigger.lower() in lower: - print('[N] Writing to subsystem: {}'.format(trigger)) + print('[N] Writing to subsystem: {}'.format(self.opts['triggers'][trigger])) os.write(child_fd, self.opts['triggers'][trigger]) yield output @@ -644,7 +644,7 @@ if __name__ == '__main__': o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { b'Arcinstall login' : b'root\n', b'Password' : bytes(args['password']+'\n', 'UTF-8'), - b'[root@Archinstall ~]#' : bytes(command+'\n', 'UTF-8'), + b'[root@Arcinstall ~]#' : bytes(command+'\n', 'UTF-8'), }, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. -- cgit v1.2.3-70-g09d2 From 90b6c5c8f78df7cbdcf0ffd89846f3d04be46bd4 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:43:05 +0200 Subject: Final touches on the new subsystem thing --- archinstall.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index f1a33d4e..665fcb21 100644 --- a/archinstall.py +++ b/archinstall.py @@ -168,13 +168,20 @@ class sys_command(): lower = output.lower() if 'triggers' in self.opts: for trigger in self.opts['triggers']: - print(trigger.lower(),'vs', lower) if trigger.lower() in lower: print('[N] Writing to subsystem: {}'.format(self.opts['triggers'][trigger])) os.write(child_fd, self.opts['triggers'][trigger]) + del(self.opts['triggers'][trigger]) + if len(self.opts['triggers']) == 0: + alive = False + break yield output + # Since we're in a subsystem, we gotta bail out! + # Bail bail bail! + os.write(child_fd, b'shutdown now') + exit_code = os.waitpid(self.pid, 0)[1] if exit_code != 0: print('[E] Command "{}" exited with status code:'.format(self.cmd[0]), exit_code) -- cgit v1.2.3-70-g09d2 From 5c3089e7f904bfd05d1add9189bff5847ca2c7b5 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:50:13 +0200 Subject: Frikin dicts and sizes.. fixed --- archinstall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index 665fcb21..43ebd669 100644 --- a/archinstall.py +++ b/archinstall.py @@ -167,7 +167,7 @@ class sys_command(): lower = output.lower() if 'triggers' in self.opts: - for trigger in self.opts['triggers']: + for trigger in list(self.opts['triggers']): if trigger.lower() in lower: print('[N] Writing to subsystem: {}'.format(self.opts['triggers'][trigger])) os.write(child_fd, self.opts['triggers'][trigger]) -- cgit v1.2.3-70-g09d2 From 9e8179d25b8404f30b884a2760d3410325719c63 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 22:56:24 +0200 Subject: Live testing --- archinstall.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/archinstall.py b/archinstall.py index 43ebd669..e8997391 100644 --- a/archinstall.py +++ b/archinstall.py @@ -172,15 +172,18 @@ class sys_command(): print('[N] Writing to subsystem: {}'.format(self.opts['triggers'][trigger])) os.write(child_fd, self.opts['triggers'][trigger]) del(self.opts['triggers'][trigger]) + + ## Adding a exit trigger: if len(self.opts['triggers']) == 0: - alive = False - break + if b'[root@arcinstall ~]#' in output: + alive = False + break yield output # Since we're in a subsystem, we gotta bail out! # Bail bail bail! - os.write(child_fd, b'shutdown now') + os.write(child_fd, b'shutdown now\n') exit_code = os.waitpid(self.pid, 0)[1] if exit_code != 0: -- cgit v1.2.3-70-g09d2 From 17de7d0ce4020050d1d74552cfb6cacfda23b5e2 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 23:01:22 +0200 Subject: Added a exit condition for the subsystem --- archinstall.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index e8997391..96283004 100644 --- a/archinstall.py +++ b/archinstall.py @@ -169,13 +169,18 @@ class sys_command(): if 'triggers' in self.opts: for trigger in list(self.opts['triggers']): if trigger.lower() in lower: - print('[N] Writing to subsystem: {}'.format(self.opts['triggers'][trigger])) + if 'debug' in self.opts and self.opts['debug']: + print('[N] Writing to subsystem: {}'.format(self.opts['triggers'][trigger])) os.write(child_fd, self.opts['triggers'][trigger]) del(self.opts['triggers'][trigger]) ## Adding a exit trigger: if len(self.opts['triggers']) == 0: + if 'debug' in self.opts and self.opts['debug']: + print('[N] Waiting for last command to finish...') if b'[root@arcinstall ~]#' in output: + if 'debug' in self.opts and self.opts['debug']: + print('[N] Last command finished, exiting subsystem.') alive = False break -- cgit v1.2.3-70-g09d2 From 0a4126d407c74e77a01893d4796d2615344c533a Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 23:03:32 +0200 Subject: Misspelled Archinstall :P --- archinstall.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/archinstall.py b/archinstall.py index 96283004..57afbfc6 100644 --- a/archinstall.py +++ b/archinstall.py @@ -178,7 +178,7 @@ class sys_command(): if len(self.opts['triggers']) == 0: if 'debug' in self.opts and self.opts['debug']: print('[N] Waiting for last command to finish...') - if b'[root@arcinstall ~]#' in output: + if b'[root@Archinstall ~]#' in output: if 'debug' in self.opts and self.opts['debug']: print('[N] Last command finished, exiting subsystem.') alive = False @@ -359,7 +359,7 @@ if __name__ == '__main__': if not 'size' in args: args['size'] = '100%' if not 'start' in args: args['start'] = '513MiB' if not 'pwfile' in args: args['pwfile'] = '/tmp/diskpw' - if not 'hostname' in args: args['hostname'] = 'Arcinstall' + if not 'hostname' in args: args['hostname'] = 'Archinstall' if not 'country' in args: args['country'] = 'SE' # 'all' if we don't want country specific mirrors. if not 'packages' in args: args['packages'] = '' # extra packages other than default if not 'post' in args: args['post'] = 'reboot' @@ -657,9 +657,9 @@ if __name__ == '__main__': ## And then boot and execute: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { - b'Arcinstall login' : b'root\n', + b'Archinstall login' : b'root\n', b'Password' : bytes(args['password']+'\n', 'UTF-8'), - b'[root@Arcinstall ~]#' : bytes(command+'\n', 'UTF-8'), + b'[root@Archinstall ~]#' : bytes(command+'\n', 'UTF-8'), }, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. -- cgit v1.2.3-70-g09d2 From a2731924cbe7d6ccb69ff60a894d7966f54aff83 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 23:06:34 +0200 Subject: Fixed some stuff --- archinstall.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/archinstall.py b/archinstall.py index 57afbfc6..dda5c347 100644 --- a/archinstall.py +++ b/archinstall.py @@ -178,7 +178,7 @@ class sys_command(): if len(self.opts['triggers']) == 0: if 'debug' in self.opts and self.opts['debug']: print('[N] Waiting for last command to finish...') - if b'[root@Archinstall ~]#' in output: + if bytes(f'[root@args["hostname"] ~]#'.lower(), 'UTF-8') in output.lower(): if 'debug' in self.opts and self.opts['debug']: print('[N] Last command finished, exiting subsystem.') alive = False @@ -657,9 +657,9 @@ if __name__ == '__main__': ## And then boot and execute: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { - b'Archinstall login' : b'root\n', + bytes(f'{args["hostname"]} login', 'UTF-8') : b'root\n', b'Password' : bytes(args['password']+'\n', 'UTF-8'), - b'[root@Archinstall ~]#' : bytes(command+'\n', 'UTF-8'), + bytes(f'[root@args["hostname"] ~]#', 'UTF-8') : bytes(command+'\n', 'UTF-8'), }, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. -- cgit v1.2.3-70-g09d2 From 5f51f1afadd142385ceaf2d4ba330dd397c521e3 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 23:11:53 +0200 Subject: Live testing --- archinstall.py | 1 + 1 file changed, 1 insertion(+) diff --git a/archinstall.py b/archinstall.py index dda5c347..2fdd7292 100644 --- a/archinstall.py +++ b/archinstall.py @@ -168,6 +168,7 @@ class sys_command(): lower = output.lower() if 'triggers' in self.opts: for trigger in list(self.opts['triggers']): + print(trigger.lower(), 'vs', lower) if trigger.lower() in lower: if 'debug' in self.opts and self.opts['debug']: print('[N] Writing to subsystem: {}'.format(self.opts['triggers'][trigger])) -- cgit v1.2.3-70-g09d2 From f76f692483e235397cc3987ef3636d0fc96ba050 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 23:16:57 +0200 Subject: Forgot formatting on hostname --- archinstall.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/archinstall.py b/archinstall.py index 2fdd7292..94d68edb 100644 --- a/archinstall.py +++ b/archinstall.py @@ -179,7 +179,7 @@ class sys_command(): if len(self.opts['triggers']) == 0: if 'debug' in self.opts and self.opts['debug']: print('[N] Waiting for last command to finish...') - if bytes(f'[root@args["hostname"] ~]#'.lower(), 'UTF-8') in output.lower(): + if bytes(f'[root@{args["hostname"]} ~]#'.lower(), 'UTF-8') in output.lower(): if 'debug' in self.opts and self.opts['debug']: print('[N] Last command finished, exiting subsystem.') alive = False @@ -660,7 +660,7 @@ if __name__ == '__main__': o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { bytes(f'{args["hostname"]} login', 'UTF-8') : b'root\n', b'Password' : bytes(args['password']+'\n', 'UTF-8'), - bytes(f'[root@args["hostname"] ~]#', 'UTF-8') : bytes(command+'\n', 'UTF-8'), + bytes(f'[root@{args["hostname"]} ~]#', 'UTF-8') : bytes(command+'\n', 'UTF-8'), }, **opts}).exec()) ## And cleanup after out selves.. Don't want to leave any residue.. -- cgit v1.2.3-70-g09d2 From b32657257813b7bfd8894c919fb05317e39dda9c Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 23:23:59 +0200 Subject: First working copy of the new subsystem / boot / hacks --- archinstall.py | 38 +++++++++++++++++++++----------------- 1 file changed, 21 insertions(+), 17 deletions(-) diff --git a/archinstall.py b/archinstall.py index 94d68edb..4f79da6a 100644 --- a/archinstall.py +++ b/archinstall.py @@ -168,7 +168,6 @@ class sys_command(): lower = output.lower() if 'triggers' in self.opts: for trigger in list(self.opts['triggers']): - print(trigger.lower(), 'vs', lower) if trigger.lower() in lower: if 'debug' in self.opts and self.opts['debug']: print('[N] Writing to subsystem: {}'.format(self.opts['triggers'][trigger])) @@ -635,20 +634,22 @@ if __name__ == '__main__': ## Run in a manually set up version of arch-chroot (arch-chroot will break namespaces). ## This is a bit risky in case the file systems changes over the years, but we'll probably be safe adding this as an option. ## **> Prefer if possible to use 'no-chroot' instead which "live boots" the OS and runs the command. - o = b''.join(sys_command("/usr/bin/mount /dev/mapper/luksdev /mnt").exec()) - o = b''.join(sys_command("cd /mnt; cp /etc/resolv.conf etc").exec()) - o = b''.join(sys_command("cd /mnt; /usr/bin/mount -t proc /proc proc").exec()) - o = b''.join(sys_command("cd /mnt; /usr/bin/mount --make-rslave --rbind /sys sys").exec()) - o = b''.join(sys_command("cd /mnt; /usr/bin/mount --make-rslave --rbind /dev dev").exec()) - o = b''.join(sys_command('/usr/bin/chroot /mnt /bin/bash -c "{c}"'.format(c=command), opts=opts).exec()) - o = b''.join(sys_command("cd /mnt; /usr/bin/umount -R dev").exec()) - o = b''.join(sys_command("cd /mnt; /usr/bin/umount -R sys").exec()) - o = b''.join(sys_command("cd /mnt; /usr/bin/umount -R proc").exec()) + o = simple_command("mount /dev/mapper/luksdev /mnt") + o = simple_command("cd /mnt; cp /etc/resolv.conf etc") + o = simple_command("cd /mnt; mount -t proc /proc proc") + o = simple_command("cd /mnt; mount --make-rslave --rbind /sys sys") + o = simple_command("cd /mnt; mount --make-rslave --rbind /dev dev") + o = simple_command('chroot /mnt /bin/bash -c "{c}"'.format(c=command), opts=opts) + o = simple_command("cd /mnt; umount -R dev") + o = simple_command("cd /mnt; umount -R sys") + o = simple_command("cd /mnt; umount -R proc") else: if 'boot' in opts and opts['boot']: ## So, if we're going to boot this maddafakker up, we'll need to ## be able to login. The quickest way is to just add automatic login.. so lessgo! + ## Turns out.. that didn't work exactly as planned.. + ## # if not os.path.isdir('/mnt/etc/systemd/system/console-getty.service.d/'): # os.makedirs('/mnt/etc/systemd/system/console-getty.service.d/') # with open('/mnt/etc/systemd/system/console-getty.service.d/override.conf', 'w') as fh: @@ -656,14 +657,17 @@ if __name__ == '__main__': # fh.write('ExecStart=\n') # fh.write('ExecStart=-/usr/bin/agetty --autologin root -s %I 115200,38400,9600 vt102\n') - ## And then boot and execute: + ## So we'll add a bunch of triggers instead and let the sys_command manually react to them. + ## " login" followed by "Passwodd" in case it's been set in a previous step.. usually this shouldn't be nessecary + ## since we set the password as the last step. And then the command itself which will be executed by looking for: + ## [root@ ~]# o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt -b --machine temporary', opts={'triggers' : { bytes(f'{args["hostname"]} login', 'UTF-8') : b'root\n', b'Password' : bytes(args['password']+'\n', 'UTF-8'), bytes(f'[root@{args["hostname"]} ~]#', 'UTF-8') : bytes(command+'\n', 'UTF-8'), }, **opts}).exec()) - ## And cleanup after out selves.. Don't want to leave any residue.. + ## Not needed anymore: And cleanup after out selves.. Don't want to leave any residue.. # os.remove('/mnt/etc/systemd/system/console-getty.service.d/override.conf') else: o = b''.join(sys_command('/usr/bin/systemd-nspawn -D /mnt --machine temporary {c}'.format(c=command), opts=opts).exec()) @@ -674,13 +678,13 @@ if __name__ == '__main__': ## == Passwords # o = sys_command('arch-chroot /mnt usermod --password {} root'.format(args['password'])) # o = sys_command("arch-chroot /mnt sh -c 'echo {pin} | passwd --stdin root'".format(pin='"{pin}"'.format(**args, pin=args['password'])), echo=True) - o = b''.join(sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'root:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec()) + o = simple_command("/usr/bin/arch-chroot /mnt sh -c \"echo 'root:{pin}' | chpasswd\"".format(**args, pin=args['password'])) if 'user' in args: - o = b''.join(sys_command('/usr/bin/arch-chroot /mnt useradd -m -G wheel {user}'.format(**args)).exec()) - o = b''.join(sys_command("/usr/bin/arch-chroot /mnt sh -c \"echo '{user}:{pin}' | chpasswd\"".format(**args, pin=args['password'])).exec()) + o = ('/usr/bin/arch-chroot /mnt useradd -m -G wheel {user}'.format(**args)) + o = ("/usr/bin/arch-chroot /mnt sh -c \"echo '{user}:{pin}' | chpasswd\"".format(**args, pin=args['password'])) if args['post'] == 'reboot': - o = b''.join(sys_command('/usr/bin/umount -R /mnt').exec()) - o = b''.join(sys_command('/usr/bin/reboot now').exec()) + o = simple_command('/usr/bin/umount -R /mnt') + o = simple_command('/usr/bin/reboot now') else: print('Done. "umount -R /mnt; reboot" when you\'re done tinkering.') -- cgit v1.2.3-70-g09d2 From a87b30d2f6fa878049e0f9cc77e0d79db10beaf7 Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 23:34:43 +0200 Subject: Swapped no-chroot to simple command. More expected behavior that way --- archinstall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index 4f79da6a..f3aacd19 100644 --- a/archinstall.py +++ b/archinstall.py @@ -629,7 +629,7 @@ if __name__ == '__main__': ## Either skipping mounting /run and using traditional chroot is an option, but using ## `systemd-nspawn -D /mnt --machine temporary` might be a more flexible solution in case of file structure changes. if 'no-chroot' in opts and opts['no-chroot']: - o = b''.join(sys_command(command, opts).exec()) + o = simple_command(command, opts) elif 'chroot' in opts and opts['chroot']: ## Run in a manually set up version of arch-chroot (arch-chroot will break namespaces). ## This is a bit risky in case the file systems changes over the years, but we'll probably be safe adding this as an option. -- cgit v1.2.3-70-g09d2 From 311aa08958ca77f2888a00fab8d9fd7d610fd14f Mon Sep 17 00:00:00 2001 From: Anton Hvornum Date: Thu, 11 Apr 2019 23:36:16 +0200 Subject: More debugging --- archinstall.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/archinstall.py b/archinstall.py index f3aacd19..0d909d0f 100644 --- a/archinstall.py +++ b/archinstall.py @@ -136,7 +136,7 @@ class sys_command(): def exec(self): if not self.cmd[0][0] == '/': - print('[N] Command is not executed with absolute path, trying to find it..') + print('[N] Command is not executed with absolute path, trying to find: {}'.format(self.cmd[0])) o = b''.join(sys_command('/usr/bin/whereis {}'.format(self.cmd[0])).exec()) self.cmd[0] = o.split(b' ')[1].decode('UTF-8') print('[N] This is what I\'m going with: {}'.format(self.cmd[0])) -- cgit v1.2.3-70-g09d2