2025-06-11 23:57:04 +02:00

130 lines
4.5 KiB
Python

import subprocess, os, sys, datetime, getpass, shutil
from pathlib import Path
if __name__ != '__main__':
from . import *
class OS:
def __init__(self):
self.root_dir = f"{ROOT_DIR}/root"
self.actions = [
[ "chroot", self.chroot ],
[ "sync", self.sync_repo ],
[ "update", self.update_all ],
[ "reinstall", self.rebuild_all ],
[ "pack", self.pack ],
[ "sqh", self.sqh ]
]
def actions_list(self):
lst = []
for act in self.actions:
lst.append(act[0])
return lst
def set_board(self, board):
self.board = board
self.arch = board.parse_variables("%{ARCH}%")
def __sudo(self, args, cwd=None, env=None):
args.insert(0, "sudo")
p = subprocess.Popen(args, cwd=cwd, env=env)
if (p.wait() != 0):
Logger.error(f"Command '{args[1]}' finished with error code!")
def __prepare(self):
qemu_f = Path(f"/proc/sys/fs/binfmt_misc/qemu-{self.arch}")
if (not qemu_f.is_file()):
self.__sudo(["python", os.path.abspath(__file__), self.arch])
self.__sudo(["cp", f"{ROOT_DIR}/files/qemu/qemu-{self.arch}", f"{self.root_dir}/bin/"])
def __chroot(self, command):
self.__prepare()
Logger.os(f"Start chroot'ed command: '{command}'")
self.__sudo(["bash", f"{ROOT_DIR}/scripts/chroot.sh", self.root_dir, command])
def chroot(self):
self.__chroot("")
def sync_repo(self):
self.__chroot("eix-sync -v")
def update_all(self):
self.__chroot("emerge -avuDN1b world -j2 && ldconfig")
def rebuild_all(self):
self.__chroot("emerge -av1be world -j2 && ldconfig")
def __do_archive(self, excl_list, name):
Logger.os(f"Create '{name}' archive...")
my_env = os.environ.copy()
my_env["XZ_OPT"] = "-9 --extreme --threads=0"
date = datetime.datetime.today().strftime('%Y_%m_%d')
arch_path = self.board.parse_variables("%{out_dir}%/back_" + name + "_" + date + ".tar.xz")
self.__sudo(["tar", "-cJpf", arch_path,
f"--exclude-from={ROOT_DIR}/files/backups/{excl_list}.lst", "."],
cwd=self.root_dir, env=my_env)
if (p.wait() != 0):
Logger.error("Archive command finished with error code!")
return arch_path
def pack(self):
return self.__do_archive("excl_min", "FULL")
def __fix_xorg(self):
Logger.os("Fix Xorg permissions")
self.__sudo(["chmod", "u+s", f"{self.root_dir}/usr/bin/Xorg"])
def __tmp_clean(self, path):
Logger.os("Clean temporary directory...")
t_dir = Path(path)
if (t_dir.is_dir()):
self.__sudo(["rm", "-rf", path])
def __extract_tar(self, arch_fn, to_path):
Logger.os("Extract to temporary directory...")
os.makedirs(to_path, exist_ok=True)
self.__sudo(["tar", "xf", arch_fn], cwd=to_path)
def __make_sqh(self, root_path, to_file):
Logger.os("Create squashed archive...")
t_file = Path(to_file)
if (t_file.is_file()):
shutil.move(to_file, f"{to_file}.bak")
self.__sudo(["mksquashfs", root_path, to_file, "-comp", "xz", "-xattrs-exclude", "^system.nfs"])
user = getpass.getuser()
self.__sudo(["chown", user + ":" + user, to_file])
def sqh(self):
self.__fix_xorg()
arch_path = self.__do_archive("excl", "OS")
temp_dir = f"{ROOT_DIR}/out/tmp"
self.__tmp_clean(temp_dir)
self.__extract_tar(arch_path, temp_dir)
self.__make_sqh(temp_dir, f"{ROOT_DIR}/out/root.sqh")
def action(self, action):
for act in self.actions:
if (act[0] == action):
act[1]()
break
if __name__ == '__main__':
f = open("/proc/sys/fs/binfmt_misc/register","wb")
if (len(sys.argv) < 2) or (sys.argv[1] == "aarch64"):
name = "aarch64"
interp = f"/usr/bin/qemu-{name}"
magic = b"\\x7fELF\\x02\\x01\\x01\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x00\\x02\\x00\\xb7\\x00"
mask = b"\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\x00\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xff\\xfe\\xff\\xff\\xff"
else:
print("Invalid arguments!")
exit(1)
_REGISTER_FORMAT = b":%(name)s:M::%(magic)s:%(mask)s:%(interp)s:%(flags)s"
s = _REGISTER_FORMAT % {
b"name": name.encode("utf-8"),
b"magic": magic,
b"mask": mask,
b"interp": interp.encode("utf-8"),
b"flags": b"",
}
f.write(s)