feat: implement three-way /etc merge
This commit is contained in:
parent
7c53002545
commit
deb302a20e
2 changed files with 63 additions and 52 deletions
67
akshara
67
akshara
|
@ -22,6 +22,7 @@ import sys
|
|||
import time
|
||||
import yaml
|
||||
import shutil
|
||||
import filecmp
|
||||
import argparse
|
||||
import requests
|
||||
import platform
|
||||
|
@ -71,8 +72,6 @@ class colors:
|
|||
cyan = '\033[46m'
|
||||
lightgrey = '\033[47m'
|
||||
|
||||
# END
|
||||
|
||||
|
||||
def exec(*cmd, **kwargs):
|
||||
return subprocess.call(cmd, shell=False, stdout=sys.stdout, stderr=sys.stderr, **kwargs)
|
||||
|
@ -197,6 +196,10 @@ def update_system():
|
|||
'blend-files'
|
||||
]
|
||||
|
||||
keep = [
|
||||
'/usr/share'
|
||||
]
|
||||
|
||||
if (type(blend_release.get('impl')) == str and
|
||||
type(blend_release.get('track')) != 'custom'):
|
||||
res = interpret_track(blend_release)
|
||||
|
@ -292,21 +295,22 @@ Server = {package_repo["repo-url"]}
|
|||
break
|
||||
|
||||
counter = 0
|
||||
while True:
|
||||
exec_chroot('useradd', '-m', '-G', 'wheel', '-s', '/bin/bash', 'aur')
|
||||
exec_chroot('bash', '-c', 'echo "aur ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/aur')
|
||||
return_val = exec_chroot(
|
||||
'runuser', '-u', 'aur', '--', 'paru', '-Sy', '--noconfirm', '--needed',
|
||||
'--noprogressbar', '--skipreview', '--removemake', '--cleanafter', '--ask=4',
|
||||
*blend_release.get('aur-packages'))
|
||||
exec_chroot('userdel', '-r', 'aur')
|
||||
exec_chroot('rm', '-f', '/etc/sudoers.d/aur')
|
||||
counter += 1
|
||||
if counter > 30:
|
||||
error('failed to download AUR packages')
|
||||
exit(50)
|
||||
if return_val == 0:
|
||||
break
|
||||
if aur_packages != []:
|
||||
while True:
|
||||
exec_chroot('useradd', '-m', '-G', 'wheel', '-s', '/bin/bash', 'aur')
|
||||
exec_chroot('bash', '-c', 'echo "aur ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/aur')
|
||||
return_val = exec_chroot(
|
||||
'runuser', '-u', 'aur', '--', 'paru', '-Sy', '--noconfirm', '--needed',
|
||||
'--noprogressbar', '--skipreview', '--removemake', '--cleanafter', '--ask=4',
|
||||
*aur_packages)
|
||||
exec_chroot('userdel', '-r', 'aur')
|
||||
exec_chroot('rm', '-f', '/etc/sudoers.d/aur')
|
||||
counter += 1
|
||||
if counter > 30:
|
||||
error('failed to download AUR packages')
|
||||
exit(50)
|
||||
if return_val == 0:
|
||||
break
|
||||
|
||||
for service in services:
|
||||
if type(service) is str:
|
||||
|
@ -344,6 +348,35 @@ Server = {package_repo["repo-url"]}
|
|||
|
||||
exec_chroot('mkinitcpio', '-P')
|
||||
|
||||
exec('cp', '-ax', '/.new_rootfs/etc', '/.new.etc')
|
||||
|
||||
etc_diff = filecmp.dircmp('/etc/', '/usr/etc/')
|
||||
|
||||
def get_diff_etc_files(dcmp):
|
||||
dir_name = dcmp.left.replace('/etc/', '/.new.etc/', 1)
|
||||
for name in dcmp.left_only:
|
||||
exec('mkdir', '-p', dir_name)
|
||||
exec('cp', '-ax', os.path.join(dcmp.left, name), dir_name)
|
||||
for name in dcmp.diff_files:
|
||||
exec('cp', '-ax', os.path.join(dcmp.left, name), dir_name)
|
||||
for sub_dcmp in dcmp.subdirs.values():
|
||||
get_diff_etc_files(sub_dcmp)
|
||||
|
||||
get_diff_etc_files(etc_diff)
|
||||
|
||||
exec('cp', '-ax', '/var/lib', '/.new.var.lib')
|
||||
|
||||
var_lib_diff = filecmp.dircmp('/.new_rootfs/var/lib/', '/.new.var.lib/')
|
||||
|
||||
dir_name = '/.new.var.lib/'
|
||||
for name in var_lib_diff.left_only:
|
||||
if os.path.isdir(os.path.join(var_lib_diff.left, name)):
|
||||
exec('cp', '-ax', os.path.join(var_lib_diff.left, name), dir_name)
|
||||
for name in var_lib_diff.right_only:
|
||||
exec('rm', '-rf', os.path.join(dir_name, name))
|
||||
|
||||
exec('cp', '/.new_rootfs/etc/pacman.conf', '/.new.etc')
|
||||
|
||||
exec('mv', '.new_rootfs', '.update_rootfs')
|
||||
|
||||
new_boot_files = []
|
||||
|
|
48
akshara.hook
48
akshara.hook
|
@ -12,47 +12,25 @@ run_latehook() {
|
|||
mv /new_root/usr /new_root/.old.usr
|
||||
mv /new_root/.update_rootfs/usr /new_root/usr
|
||||
|
||||
# Same for /var/cache/pacman.
|
||||
mv /new_root/var/cache/pacman /new_root/.old.pacmancache
|
||||
mv /new_root/.update_rootfs/var/cache/pacman /new_root/var/cache
|
||||
# Same for /etc.
|
||||
if [[ -d /new_root/.update_rootfs/etc ]]; then
|
||||
mv /new_root/.update_rootfs/etc /new_root/usr/etc
|
||||
fi
|
||||
if [[ -d /new_root/.new.etc ]]; then
|
||||
mv /new_root/etc /new_root/.old.etc
|
||||
mv /new_root/.new.etc /new_root/etc
|
||||
fi
|
||||
|
||||
# Same for /var/lib/pacman.
|
||||
mv /new_root/var/lib/pacman /new_root/.old.var.lib.pacman
|
||||
mv /new_root/.update_rootfs/var/lib/pacman /new_root/var/lib
|
||||
|
||||
# Move to /etc stage.
|
||||
touch /new_root/.etc-stage
|
||||
fi
|
||||
|
||||
# Detect if /etc stage is active.
|
||||
if [[ -f /new_root/.etc-stage ]]; then
|
||||
# Create new /etc.
|
||||
rm -rf /new_root/.new_etc; cp -a /new_root/etc /new_root/.new_etc
|
||||
(cd /new_root/.new_etc && find . -type f | grep -Fxv -f <(cd "/new_root/.update_rootfs/etc" && find . -type f) | xargs rm -f)
|
||||
(cd /new_root/.new_etc && find . -type l | grep -Fxv -f <(cd "/new_root/.update_rootfs/etc" && find . -type l) | grep -Fxv './localtime' | xargs rm -f)
|
||||
mkdir -p /.old.varlib
|
||||
(cd /new_root/var/lib && find . -maxdepth 1 -type d | grep -Fxv -f <(cd "/new_root/.update_rootfs/var/lib" && find . -maxdepth 1 -type d) | grep -Fxv './pacman' | xargs sh -c 'mv "$@" /new_root/.old.varlib' sh)
|
||||
(cd /new_root/.update_rootfs/var/lib && find . -maxdepth 1 -type d | grep -Fxv -f <(cd "/new_root/var/lib" && find . -maxdepth 1 -type d) | xargs sh -c 'cp -r "$@" /new_root/var/lib' sh)
|
||||
cp /new_root/.update_rootfs/etc/pacman.conf /new_root/.new_etc/pacman.conf
|
||||
rm -rf /new_root/.new_etc/pacman.d
|
||||
cp -a /new_root/.update_rootfs/etc/pacman.d /new_root/.new_etc/pacman.d
|
||||
rm -rf /new_root/.new_etc/sudoers.d
|
||||
cp -a /new_root/etc/sudoers.d /new_root/.new_etc
|
||||
(cd /new_root/.update_rootfs/etc && find . -type f | grep -Fxv -f <(cd "/new_root/.new_etc" && find . -type f) | xargs -n 1 sh -c 'mkdir -p "/new_root/.new_etc/$(dirname "$1")"; cp -a "$1" /new_root/.new_etc/$(dirname "$1")' sh)
|
||||
(cd /new_root/.update_rootfs/etc && find . -type l | grep -Fxv -f <(cd "/new_root/.new_etc" && find . -type l) | xargs -n 1 sh -c 'mkdir -p "/new_root/.new_etc/$(dirname "$1")"; cp -a "$1" /new_root/.new_etc/$(dirname "$1")' sh)
|
||||
mv /new_root/etc /new_root/.old.etc || :
|
||||
mv /new_root/.new_etc /new_root/etc
|
||||
|
||||
mv /new_root/etc/systemd/system /new_root/.old.etc.systemd.system
|
||||
mv /new_root/.update_rootfs/etc/systemd/system /new_root/etc/systemd
|
||||
|
||||
# Successful update.
|
||||
rm -f /new_root/.etc-stage
|
||||
if [[ -d /new_root/.new.var.lib ]]; then
|
||||
mv /new_root/var/lib /new_root/.old.var.lib
|
||||
mv /new_root/.new.var.lib /new_root/var/lib
|
||||
fi
|
||||
|
||||
mv /new_root/.update_rootfs /new_root/.old.update_rootfs
|
||||
touch /new_root/.successful-update
|
||||
fi
|
||||
|
||||
|
||||
rm -rf /new_root/.blend-overlays/usr.workdir /new_root/.blend-overlays/varlibpacman.workdir
|
||||
|
||||
for i in usr varlibpacman; do
|
||||
|
|
Loading…
Reference in a new issue