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 time
|
||||||
import yaml
|
import yaml
|
||||||
import shutil
|
import shutil
|
||||||
|
import filecmp
|
||||||
import argparse
|
import argparse
|
||||||
import requests
|
import requests
|
||||||
import platform
|
import platform
|
||||||
|
@ -71,8 +72,6 @@ class colors:
|
||||||
cyan = '\033[46m'
|
cyan = '\033[46m'
|
||||||
lightgrey = '\033[47m'
|
lightgrey = '\033[47m'
|
||||||
|
|
||||||
# END
|
|
||||||
|
|
||||||
|
|
||||||
def exec(*cmd, **kwargs):
|
def exec(*cmd, **kwargs):
|
||||||
return subprocess.call(cmd, shell=False, stdout=sys.stdout, stderr=sys.stderr, **kwargs)
|
return subprocess.call(cmd, shell=False, stdout=sys.stdout, stderr=sys.stderr, **kwargs)
|
||||||
|
@ -197,6 +196,10 @@ def update_system():
|
||||||
'blend-files'
|
'blend-files'
|
||||||
]
|
]
|
||||||
|
|
||||||
|
keep = [
|
||||||
|
'/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'):
|
||||||
res = interpret_track(blend_release)
|
res = interpret_track(blend_release)
|
||||||
|
@ -292,21 +295,22 @@ Server = {package_repo["repo-url"]}
|
||||||
break
|
break
|
||||||
|
|
||||||
counter = 0
|
counter = 0
|
||||||
while True:
|
if aur_packages != []:
|
||||||
exec_chroot('useradd', '-m', '-G', 'wheel', '-s', '/bin/bash', 'aur')
|
while True:
|
||||||
exec_chroot('bash', '-c', 'echo "aur ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/aur')
|
exec_chroot('useradd', '-m', '-G', 'wheel', '-s', '/bin/bash', 'aur')
|
||||||
return_val = exec_chroot(
|
exec_chroot('bash', '-c', 'echo "aur ALL=(ALL) NOPASSWD: ALL" > /etc/sudoers.d/aur')
|
||||||
'runuser', '-u', 'aur', '--', 'paru', '-Sy', '--noconfirm', '--needed',
|
return_val = exec_chroot(
|
||||||
'--noprogressbar', '--skipreview', '--removemake', '--cleanafter', '--ask=4',
|
'runuser', '-u', 'aur', '--', 'paru', '-Sy', '--noconfirm', '--needed',
|
||||||
*blend_release.get('aur-packages'))
|
'--noprogressbar', '--skipreview', '--removemake', '--cleanafter', '--ask=4',
|
||||||
exec_chroot('userdel', '-r', 'aur')
|
*aur_packages)
|
||||||
exec_chroot('rm', '-f', '/etc/sudoers.d/aur')
|
exec_chroot('userdel', '-r', 'aur')
|
||||||
counter += 1
|
exec_chroot('rm', '-f', '/etc/sudoers.d/aur')
|
||||||
if counter > 30:
|
counter += 1
|
||||||
error('failed to download AUR packages')
|
if counter > 30:
|
||||||
exit(50)
|
error('failed to download AUR packages')
|
||||||
if return_val == 0:
|
exit(50)
|
||||||
break
|
if return_val == 0:
|
||||||
|
break
|
||||||
|
|
||||||
for service in services:
|
for service in services:
|
||||||
if type(service) is str:
|
if type(service) is str:
|
||||||
|
@ -344,6 +348,35 @@ Server = {package_repo["repo-url"]}
|
||||||
|
|
||||||
exec_chroot('mkinitcpio', '-P')
|
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')
|
exec('mv', '.new_rootfs', '.update_rootfs')
|
||||||
|
|
||||||
new_boot_files = []
|
new_boot_files = []
|
||||||
|
|
46
akshara.hook
46
akshara.hook
|
@ -12,42 +12,20 @@ run_latehook() {
|
||||||
mv /new_root/usr /new_root/.old.usr
|
mv /new_root/usr /new_root/.old.usr
|
||||||
mv /new_root/.update_rootfs/usr /new_root/usr
|
mv /new_root/.update_rootfs/usr /new_root/usr
|
||||||
|
|
||||||
# Same for /var/cache/pacman.
|
# Same for /etc.
|
||||||
mv /new_root/var/cache/pacman /new_root/.old.pacmancache
|
if [[ -d /new_root/.update_rootfs/etc ]]; then
|
||||||
mv /new_root/.update_rootfs/var/cache/pacman /new_root/var/cache
|
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.
|
# Same for /var/lib/pacman.
|
||||||
mv /new_root/var/lib/pacman /new_root/.old.var.lib.pacman
|
if [[ -d /new_root/.new.var.lib ]]; then
|
||||||
mv /new_root/.update_rootfs/var/lib/pacman /new_root/var/lib
|
mv /new_root/var/lib /new_root/.old.var.lib
|
||||||
|
mv /new_root/.new.var.lib /new_root/var/lib
|
||||||
# Move to /etc stage.
|
fi
|
||||||
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
|
|
||||||
|
|
||||||
mv /new_root/.update_rootfs /new_root/.old.update_rootfs
|
mv /new_root/.update_rootfs /new_root/.old.update_rootfs
|
||||||
touch /new_root/.successful-update
|
touch /new_root/.successful-update
|
||||||
|
|
Loading…
Reference in a new issue