import os import shutil import subprocess from . import packie BASE_REQUIREMENTS = [ # Basic packages for running shell scripts "mksh", "coreutils", "findutils", "diffutils", # Packages for running `semios-packages` scripts "python", "packie", "zstd", "libarchive-tools", # Packages for building packages that require patching "patch", # Packages for downloading various formats of tarballs "libz-ng", "liblzma", "libbzip2", # Basic libraries "sqlite", "libgcc-compat", "libcxx", "semi-libc", # Networking "ca-certificates", "certutil", "aws-lc-libssl", "aws-lc-tools", ] def _prepare_build_env_base_files(root: str): # Create root directory os.makedirs(root, exist_ok=True) # Create var, run and tmp os.mkdir(f"{root}/var") os.mkdir(f"{root}/var/tmp") os.mkdir(f"{root}/var/run") os.mkdir(f"{root}/tmp") os.mkdir(f"{root}/run") # Copy repository config files os.makedirs(f"{root}/var/db/packie") shutil.copytree("/var/config/packie/repos.d", f"{root}/var/config/packie/repos.d") # Create directories for kernel pseudo filesystems os.mkdir(f"{root}/dev") os.mkdir(f"{root}/sys") os.mkdir(f"{root}/proc") # Create home directory of root (some scripts may require it) os.makedirs(f"{root}/home/root") # Copy DNS config os.makedirs(f"{root}/etc", exist_ok=True) shutil.copy2("/etc/resolv.conf", f"{root}/etc/resolv.conf") def prepare_build_env(root: str, extreq: list[str] = []): # Skip if the environment is already initialized if os.path.exists(f"{root}/.INIT"): return try: shutil.rmtree(root) except: pass # Prepare basic filesystem hierarchy _prepare_build_env_base_files(root) # Install packages packie.chroot_update(root) packie.chroot_install(root, BASE_REQUIREMENTS + extreq) # Refresh certificates enter_build_env(root, ["certutil", "refresh"]) # Create initialized tag with open(f"{root}/.INIT", "wt+") as file: file.write("OK") def enter_build_env(root: str, cmd: list[str], chdir: str = "/"): reserve_env = ["https_proxy", "http_proxy", "all_proxy"] reserve_env_args = [] for i in reserve_env: if os.environ.get(i): reserve_env_args += ["--setenv", i, os.environ[i]] subprocess.run( [ "bwrap", "--bind", root, "/", "--unshare-pid", "--unshare-user", "--uid", "0", "--gid", "0", "--dev", "/dev", "--bind", "/sys", "/sys", "--proc", "/proc", "--clearenv", "--setenv", "HOME", "/home/root", "--setenv", "PATH", "/bin", "--setenv", "SEMIOS_PKGBUILD_IN_ATOMIC", "1", "--setenv", "USER", "root", "--setenv", "LOGNAME", "root", "--chdir", chdir, ] + reserve_env_args + cmd ) def copy_pkgbuild_tree(repo_root: str, pkgname: str, build_env_root: str): build_dir = f"{build_env_root}/Atom" if os.path.exists(build_dir): return os.mkdir(build_dir) shutil.copytree(f"{repo_root}/hooks", f"{build_dir}/hooks") shutil.copytree(f"{repo_root}/lib", f"{build_dir}/lib") shutil.copy2(f"{repo_root}/x", f"{build_dir}/x") shutil.copy2(f"{repo_root}/x.py", f"{build_dir}/x.py") os.makedirs(f"{build_dir}/packages/{pkgname}") for i in os.listdir(f"{repo_root}/packages/{pkgname}"): srcpath = f"{repo_root}/packages/{pkgname}/{i}" dstpath = f"{build_dir}/packages/{pkgname}/{i}" if i in ["target", "__pycache__"]: continue if os.path.isdir(srcpath): shutil.copytree(srcpath, dstpath) elif os.path.isfile(srcpath): shutil.copy2(srcpath, dstpath)