Compare commits

...

10 commits

Author SHA1 Message Date
278b3ef2a8 remove broken and useless line 2024-11-27 22:25:24 -06:00
askiiart
541589ca19
oops i forgot to remove the dir 2024-11-21 11:56:50 -06:00
askiiart
c968609b60
tmp: add benchmarking for package building and installation 2024-11-11 10:48:05 -06:00
askiiart
08c7a4d235
i give up (on rate-mirrors, for now) 2024-11-08 20:15:50 -06:00
askiiart
4e1977087e
oops we need another backslash 2024-11-08 20:12:07 -06:00
askiiart
efa4c78976
remove /.new_rootfs/ properly 2024-11-08 20:06:56 -06:00
askiiart
2d1b46aa40
fix rate-mirrors 2024-11-08 20:00:05 -06:00
b08d876b53 un-sudo tee it 2024-10-15 10:10:54 -05:00
askiiart
73d9f01926
add /opt 2024-10-09 09:39:45 -05:00
askiiart
ed115df979
initial commit - switches to rate-mirrors, some minor updates, etc 2024-10-01 12:24:46 -05:00
2 changed files with 68 additions and 26 deletions

88
akshara
View file

@ -19,17 +19,13 @@
import os import os
import sys import sys
import time
import yaml import yaml
import shutil
import filecmp import filecmp
import argparse import argparse
import requests import requests
import platform
import fasteners import fasteners
from threading import Event
import subprocess import subprocess
from datetime import datetime
__version = '1.0.0' __version = '1.0.0'
@ -118,6 +114,8 @@ def interpret_track(blend_release):
def update_system(): def update_system():
benchmark = True
if os.path.isdir('/.update_rootfs'): if os.path.isdir('/.update_rootfs'):
error('update already downloaded, you must reboot first') error('update already downloaded, you must reboot first')
sys.exit(75) sys.exit(75)
@ -136,34 +134,44 @@ def update_system():
with open('/system.yaml') as blend_release_file: with open('/system.yaml') as blend_release_file:
blend_release = yaml.load( blend_release = yaml.load(
blend_release_file, Loader=yaml.FullLoader) blend_release_file, Loader=yaml.FullLoader)
# TODO: Add check that all packages actually exist
info('downloading Arch tarball...') info('downloading Arch tarball...')
# TODO: currently it errors if it doesn't have arch-repo anyways, so this doesn't need any extra checking, maybe add a check for that later though
# The mirror to use for downloading the bootstrap image
# For example, for the Arch mirror at mirrors.acm.wpi.edu, you'd use https://mirrors.acm.wpi.edu/archlinux
# Not sure why this wouldn't just use `arch-repo` but whatever
bootstrap_mirror = blend_release.get("arch-repo")
if not os.path.isfile('/.update.tar.zst'): if not os.path.isfile('/.update.tar.zst'):
if exec('wget', '-q', '--show-progress', 'https://geo.mirror.pkgbuild.com/iso/latest/archlinux-bootstrap-x86_64.tar.zst', '-O', '/.update.tar.zst') != 0: if exec('wget', '-q', '--show-progress', f'{bootstrap_mirror}/iso/latest/archlinux-bootstrap-x86_64.tar.zst', '-O', '/.update.tar.zst') != 0:
warn('failed download') warn('failed download')
print() print()
info('trying download again...') info('trying download again...')
print() print()
exec('rm', '-f', '/.update.tar.zst') exec('rm', '-f', '/.update.tar.zst')
if exec('wget', '-q', '--show-progress', 'https://geo.mirror.pkgbuild.com/iso/latest/archlinux-bootstrap-x86_64.tar.zst', '-O', '/.update.tar.zst') != 0: if exec('wget', '-q', '--show-progress', f'{bootstrap_mirror}/iso/latest/archlinux-bootstrap-x86_64.tar.zst', '-O', '/.update.tar.zst') != 0:
error('failed download') error('failed download')
print() print()
error('update failed') error('update failed')
sys.exit(50) sys.exit(50)
if exec('bash', '-c', 'sha256sum -c --ignore-missing <(wget -qO- https://geo.mirror.pkgbuild.com/iso/latest/sha256sums.txt | sed "s/archlinux-bootstrap-x86_64\\.tar\\.zst/.update.tar.zst/g") 2>/dev/null') != 0: if exec('bash', '-c', f'sha256sum -c --ignore-missing <(wget -qO- {bootstrap_mirror}/iso/latest/sha256sums.txt | sed "s/archlinux-bootstrap-x86_64\\.tar\\.zst/.update.tar.zst/g") 2>/dev/null') != 0:
error('failed checksum verification') error('failed checksum verification')
print() print()
info('trying download again...') info('trying download again...')
exec('rm', '-f', '/.update.tar.zst') exec('rm', '-f', '/.update.tar.zst')
if exec('wget', '-q', '--show-progress', 'https://geo.mirror.pkgbuild.com/iso/latest/archlinux-bootstrap-x86_64.tar.zst', '-O', '/.update.tar.zst') != 0: if exec('wget', '-q', '--show-progress', f'{bootstrap_mirror}/iso/latest/archlinux-bootstrap-x86_64.tar.zst', '-O', '/.update.tar.zst') != 0:
error('failed download') error('failed download')
print() print()
error('update failed') error('update failed')
sys.exit(50) sys.exit(50)
return return
if exec('bash', '-c', 'sha256sum -c --ignore-missing <(wget -qO- https://geo.mirror.pkgbuild.com/iso/latest/sha256sums.txt | sed "s/archlinux-bootstrap-x86_64\\.tar\\.zst/.update.tar.zst/g") 2>/dev/null') != 0: if exec('bash', '-c', f'sha256sum -c --ignore-missing <(wget -qO- {bootstrap_mirror}/iso/latest/sha256sums.txt | sed "s/archlinux-bootstrap-x86_64\\.tar\\.zst/.update.tar.zst/g") 2>/dev/null') != 0:
error('failed checksum verification') error('failed checksum verification')
print() print()
error('update failed') error('update failed')
@ -176,7 +184,11 @@ def update_system():
info('generating new system...') info('generating new system...')
before = datetime.now()
exec('tar', '--acls', '--xattrs', '-xf', '.update.tar.zst') exec('tar', '--acls', '--xattrs', '-xf', '.update.tar.zst')
after = datetime.now()
if benchmark:
print(f'[BENCH]: {(before - after).seconds} seconds to extract tarball')
exec('mv', 'root.x86_64', '.new_rootfs') exec('mv', 'root.x86_64', '.new_rootfs')
exec('rm', '-f', '/.new_rootfs/pkglist.x86_64.txt') exec('rm', '-f', '/.new_rootfs/pkglist.x86_64.txt')
exec('rm', '-f', '/.new_rootfs/version') exec('rm', '-f', '/.new_rootfs/version')
@ -196,9 +208,7 @@ def update_system():
'blend-files' 'blend-files'
] ]
keep = [ persistent_files = []
'/usr/share'
]
if (type(blend_release.get('impl')) == str and if (type(blend_release.get('impl')) == str and
type(blend_release.get('track')) != 'custom'): type(blend_release.get('track')) != 'custom'):
@ -224,6 +234,9 @@ def update_system():
if type(blend_release.get('user-services')) == list: if type(blend_release.get('user-services')) == list:
user_services += blend_release.get('user-services') user_services += blend_release.get('user-services')
if type(blend_release.get('persistent-files')) == list:
persistent_files += blend_release.get('persistent-files')
exec_chroot('rm', '-f', '/.new_rootfs/etc/resolv.conf') exec_chroot('rm', '-f', '/.new_rootfs/etc/resolv.conf')
with open('/.new_rootfs/etc/resolv.conf', 'w') as pacman_mirrorlist_conf: with open('/.new_rootfs/etc/resolv.conf', 'w') as pacman_mirrorlist_conf:
@ -243,17 +256,11 @@ def update_system():
exec_chroot('pacman-key', '--init') exec_chroot('pacman-key', '--init')
exec_chroot('pacman-key', '--populate') exec_chroot('pacman-key', '--populate')
counter = 0 # If the GitHub API is down or something, this completely breaks
while True: # also it's broken currently and reflector is working now anyways soooooo
return_val = exec_chroot('pacman', '-Sy', '--ask=4', 'reflector') # commented out
counter += 1 #exec_chroot('sh', '-c', 'mkdir /tmp/rate-mirrors/; cd /tmp/rate-mirrors/; curl -LO $(curl -s https://api.github.com/repos/westandskif/rate-mirrors/releases/latest | grep "browser_download_url.*rate-mirrors-v.*-x86_64-unknown-linux-musl.tar.gz" | cut -d : -f 2,3 | tr -d \\" | tr -d " ")')
if counter > 30: #exec_chroot('bash', '-c', 'cd /tmp/rate-mirrors/; tar -xzf rate-mirrors*; cd $(find /tmp/rate-mirrors/ -mindepth 1 -maxdepth 1 -type d); ./rate_mirrors --disable-comments-in-file --entry-country=US --protocol=https arch --max-delay 7200 > /etc/pacman.d/mirrorlist')
error('failed to download packages')
exit(50)
if return_val == 0:
break
exec_chroot('reflector', '--latest', '5', '--protocol', 'https', '--sort', 'rate', '--save', '/etc/pacman.d/mirrorlist')
#exec_chroot('sed', 's/#//g', '-i', '/etc/pacman.d/mirrorlist') #exec_chroot('sed', 's/#//g', '-i', '/etc/pacman.d/mirrorlist')
#exec_chroot('bash', '-c', 'grep "^Server =" /etc/pacman.d/mirrorlist > /etc/pacman.d/mirrorlist.tmp; mv /etc/pacman.d/mirrorlist.tmp /etc/pacman.d/mirrorlist') #exec_chroot('bash', '-c', 'grep "^Server =" /etc/pacman.d/mirrorlist > /etc/pacman.d/mirrorlist.tmp; mv /etc/pacman.d/mirrorlist.tmp /etc/pacman.d/mirrorlist')
@ -279,6 +286,7 @@ SigLevel = Never
Server = {package_repo["repo-url"]} Server = {package_repo["repo-url"]}
''') ''')
before = datetime.now()
counter = 0 counter = 0
while True: while True:
return_val = exec_chroot('pacman', '-Syu', '--noconfirm') return_val = exec_chroot('pacman', '-Syu', '--noconfirm')
@ -288,11 +296,16 @@ Server = {package_repo["repo-url"]}
exit(50) exit(50)
if return_val == 0: if return_val == 0:
break break
after = datetime.now()
if benchmark:
print(f'[BENCH]: {(before - after).seconds} seconds to update packages')
exec('cp', '/etc/mkinitcpio.conf', '/.new_rootfs/etc/mkinitcpio.conf') exec('cp', '/etc/mkinitcpio.conf', '/.new_rootfs/etc/mkinitcpio.conf')
before = datetime.now()
counter = 0 counter = 0
while True: while True:
print('running packages again')
return_val = exec_chroot('pacman', '-S', '--ask=4', *packages) return_val = exec_chroot('pacman', '-S', '--ask=4', *packages)
counter += 1 counter += 1
if counter > 30: if counter > 30:
@ -300,16 +313,24 @@ Server = {package_repo["repo-url"]}
exit(50) exit(50)
if return_val == 0: if return_val == 0:
break break
after = datetime.now()
if benchmark:
print(f'[BENCH]: {(before - after).seconds} seconds to install packages')
counter = 0 counter = 0
if aur_packages != []: if aur_packages != []:
while True: while True:
print('running aur_packages again')
exec_chroot('useradd', '-m', '-G', 'wheel', '-s', '/bin/bash', 'aur') exec_chroot('useradd', '-m', '-G', 'wheel', '-s', '/bin/bash', 'aur')
exec_chroot('bash', '-c', 'echo "aur ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/aur') exec_chroot('bash', '-c', 'echo "aur ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/aur')
before = datetime.now()
return_val = exec_chroot( return_val = exec_chroot(
'runuser', '-u', 'aur', '--', 'paru', '-Sy', '--noconfirm', '--needed', 'runuser', '-u', 'aur', '--', 'paru', '-Sy', '--noconfirm', '--needed',
'--noprogressbar', '--skipreview', '--removemake', '--cleanafter', '--ask=4', '--noprogressbar', '--skipreview', '--removemake', '--cleanafter', '--ask=4',
*aur_packages) *aur_packages)
after = datetime.now()
if benchmark:
print(f'[BENCH]: {(before - after).seconds} seconds to install AUR packages')
exec_chroot('userdel', '-r', 'aur') exec_chroot('userdel', '-r', 'aur')
exec_chroot('rm', '-f', '/etc/sudoers.d/aur') exec_chroot('rm', '-f', '/etc/sudoers.d/aur')
counter += 1 counter += 1
@ -318,6 +339,7 @@ Server = {package_repo["repo-url"]}
exit(50) exit(50)
if return_val == 0: if return_val == 0:
break break
for service in services: for service in services:
if type(service) is str: if type(service) is str:
@ -327,6 +349,12 @@ Server = {package_repo["repo-url"]}
if type(user_service) is str: if type(user_service) is str:
exec_chroot('systemctl', 'enable', '--global', user_service) exec_chroot('systemctl', 'enable', '--global', user_service)
for persistent_file in persistent_files:
if type(persistent_file) is str:
if os.path.exists(persistent_file):
exec('mkdir', '-p', '/.new_rootfs/'+ os.path.dirname(persistent_file))
exec('cp', persistent_file, '/.new_rootfs/'+ persistent_file)
if type(blend_release.get('commands')) == list: if type(blend_release.get('commands')) == list:
for command in blend_release.get('commands'): for command in blend_release.get('commands'):
if type(command) == str: if type(command) == str:
@ -403,7 +431,6 @@ Server = {package_repo["repo-url"]}
exec('cp', '-ax', '/.new_rootfs/var/lib/pacman', '/.new.var.lib/pacman') exec('cp', '-ax', '/.new_rootfs/var/lib/pacman', '/.new.var.lib/pacman')
exec('mv', '.new_rootfs', '.update_rootfs') exec('mv', '.new_rootfs', '.update_rootfs')
exec('cp', '-ax', '/.update_rootfs/etc', '/.update_rootfs/usr/etc')
new_boot_files = [] new_boot_files = []
@ -490,5 +517,14 @@ try:
command() command()
else: else:
command() command()
except KeyboardInterrupt: except:
error('aborting') error('aborting')
# remove update and akshara stuff if the program is exited
exec('umount', '-rf', '/.new_rootfs/')
exec('rmdir', '/.new_rootfs/')
exec('rm', '-rf', '/.new_rootfs')
exec('rm', '-rf', '/.update_rootfs')
# it's basically impossible to ^C before akshara has exited but after it's created this file
# and i don't *think* that "update" would be destructive at all (unless it failed to run and would't boot), but i don't quite understand it soooo just to be on the safe side
exec('rm', '-f', '/.update')
# TODO: add similar handling for errors, and an option to not delete stuff on error/early exit

View file

@ -23,6 +23,12 @@ run_latehook() {
mv /new_root/.new.etc /new_root/etc mv /new_root/.new.etc /new_root/etc
fi fi
# Same for /opt
if [[ -d /new_root/.update_rootfs/opt ]]; then
mv /new_root/opt /new_root/.old.opt
mv /new_root/.update_rootfs/opt /new_root/opt
fi
# Same for /var. # Same for /var.
if [[ -d /new_root/.new.var.lib ]]; then if [[ -d /new_root/.new.var.lib ]]; then
mv /new_root/var/lib /new_root/.old.var.lib mv /new_root/var/lib /new_root/.old.var.lib