diff --git a/README.md b/README.md index 2678ff8..403ffca 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ Currently only support Arch based distros Install required packages ```commandline -pacman -S rsync pyalpm python-yaml python-libarchive-c +pacman -S p7zip rsync pyalpm python-yaml python-libarchive-c ``` For cross build (UNTESTED) @@ -28,13 +28,14 @@ python build.py -c target/ayn-odin2-sdcard,locale/zh-cn,desktop/gnome ## Options -| Option | Description | -|-------------------------------------|---------------------------| -| -c CONFIG, --config CONFIG | Select configs to build | -| -o WORKSPACE, --workspace WORKSPACE | Set workspace for builder | -| -d, --debug | Enable debug logging | -| -G, --no-gpgcheck | Disable GPG check | -| -r, --repack | Repack rootfs only | +| Option | Description | +|-------------------------------------|----------------------------------| +| -p PRESET, --preset PRESET | Select preset to create package | +| -c CONFIG, --config CONFIG | Select configs to build | +| -o WORKSPACE, --workspace WORKSPACE | Set workspace for builder | +| -d, --debug | Enable debug logging | +| -G, --no-gpgcheck | Disable GPG check | +| -r, --repack | Repack rootfs only | ## License diff --git a/builder/lib/config.py b/builder/lib/config.py index 9a51bf4..19c1573 100644 --- a/builder/lib/config.py +++ b/builder/lib/config.py @@ -105,3 +105,14 @@ def load_configs(ctx: ArchBuilderContext, configs: list[str]): if ctx.config is None: raise ArchBuilderConfigError("no any config loaded") log.debug(f"loaded {loaded} configs") + + +def load_preset(ctx: ArchBuilderContext, preset: str): + file = preset + if not preset.startswith("/"): + file = "presets/" + preset + ctx.preset = True + load_configs(ctx, [file]) + if "package" not in ctx.config: + raise ArchBuilderConfigError("bad preset config") + log.info(f"loaded preset {preset}") diff --git a/builder/lib/context.py b/builder/lib/context.py index c842a93..b0df777 100644 --- a/builder/lib/context.py +++ b/builder/lib/context.py @@ -1,5 +1,6 @@ import os from copy import deepcopy +from datetime import datetime from subprocess import Popen, PIPE from logging import getLogger from builder.lib.cpu import cpu_arch_get @@ -88,6 +89,16 @@ class ArchBuilderContext: passwd: PasswdFile = PasswdFile() group: GroupFile = GroupFile() + """ + Use a preset to build package + """ + preset: bool = False + + """ + Package version + """ + version: str = datetime.now().strftime('%Y%m%d%H%M%S') + def get(self, key: str, default=None): """ Get config value @@ -101,7 +112,9 @@ class ArchBuilderContext: def __init__(self): self.cgroup = CGroup("arch-image-builder") - self.cgroup.create() + self.config["version"] = self.version + try: self.cgroup.create() + except: log.warning("failed to create cgroup", exc_info=1) def __deinit__(self): self.cleanup() diff --git a/builder/main.py b/builder/main.py index b9585a0..090618c 100644 --- a/builder/main.py +++ b/builder/main.py @@ -6,6 +6,7 @@ from argparse import ArgumentParser from builder.build import bootstrap from builder.lib import config, utils from builder.lib.context import ArchBuilderContext +from builder.lib.config import ArchBuilderConfigError log = logging.getLogger(__name__) @@ -14,7 +15,8 @@ def parse_arguments(ctx: ArchBuilderContext): prog="arch-image-builder", description="Build flashable image for Arch Linux", ) - parser.add_argument("-c", "--config", help="Select config to build", required=True, action='append') + parser.add_argument("-p", "--preset", help="Select preset to create package") + parser.add_argument("-c", "--config", help="Select config to build", action='append') parser.add_argument("-o", "--workspace", help="Set workspace for builder", default=ctx.work) parser.add_argument("-d", "--debug", help="Enable debug logging", default=False, action='store_true') parser.add_argument("-G", "--no-gpgcheck", help="Disable GPG check", default=False, action='store_true') @@ -31,8 +33,15 @@ def parse_arguments(ctx: ArchBuilderContext): # collect configs path configs = [] - for conf in args.config: - configs.extend(conf.split(",")) + if args.config: + for conf in args.config: + configs.extend(conf.split(",")) + + # load preset config for build package + if args.preset: + config.load_preset(ctx, args.preset) + pcfgs = ctx.get("package.configs", []) + configs.extend(pcfgs) # load and populate configs config.load_configs(ctx, configs) @@ -63,6 +72,20 @@ def check_system(): raise FileNotFoundError("pacman not found") +def done_package(ctx: ArchBuilderContext): + file: str = ctx.get("package.file", "") + out = file + if not out.startswith("/"): + out = os.path.join(ctx.work, file) + if not out.endswith(".7z"): + raise ArchBuilderConfigError("current only supports 7z") + log.info(f"creating package {file}") + args = ["7z", "a", "-ms=on", "-mx=9", out, "."] + ret = ctx.run_external(args, cwd=ctx.get_output()) + if ret != 0: raise OSError("create package failed") + log.info(f"created package at {out}") + + def main(): logging.basicConfig(stream=stdout, level=logging.INFO) check_system() @@ -71,7 +94,10 @@ def main(): ctx.dir = os.path.realpath(os.path.join(os.path.dirname(__file__), os.path.pardir)) ctx.work = os.path.realpath(os.path.join(ctx.dir, "build")) parse_arguments(ctx) + log.info(f"package version: {ctx.version}") log.info(f"source tree folder: {ctx.dir}") log.info(f"workspace folder: {ctx.work}") log.info(f"build target name: {ctx.target}") bootstrap.build_rootfs(ctx) + if ctx.preset: + done_package(ctx) diff --git a/configs/presets/ayn-odin2-sdcard-gnome-global.yaml b/configs/presets/ayn-odin2-sdcard-gnome-global.yaml new file mode 100644 index 0000000..44f25f0 --- /dev/null +++ b/configs/presets/ayn-odin2-sdcard-gnome-global.yaml @@ -0,0 +1,5 @@ +package: + file: ArchLinuxARM-AYN-Odin2-SDCard-GNOME-Global-${version}.7z + configs: + - target/ayn-odin2-sdcard + - desktop/gnome diff --git a/configs/presets/ayn-odin2-sdcard-gnome-zh-cn.yaml b/configs/presets/ayn-odin2-sdcard-gnome-zh-cn.yaml new file mode 100644 index 0000000..f81c5f6 --- /dev/null +++ b/configs/presets/ayn-odin2-sdcard-gnome-zh-cn.yaml @@ -0,0 +1,6 @@ +package: + file: ArchLinuxARM-AYN-Odin2-SDCard-GNOME-zh_CN-${version}.7z + configs: + - target/ayn-odin2-sdcard + - locale/zh-cn + - desktop/gnome diff --git a/configs/presets/ayn-odin2-ufs-gnome-global.yaml b/configs/presets/ayn-odin2-ufs-gnome-global.yaml new file mode 100644 index 0000000..b059d3f --- /dev/null +++ b/configs/presets/ayn-odin2-ufs-gnome-global.yaml @@ -0,0 +1,5 @@ +package: + file: ArchLinuxARM-AYN-Odin2-UFS-GNOME-Global-${version}.7z + configs: + - target/ayn-odin2-ufs + - desktop/gnome diff --git a/configs/presets/ayn-odin2-ufs-gnome-zh-cn.yaml b/configs/presets/ayn-odin2-ufs-gnome-zh-cn.yaml new file mode 100644 index 0000000..5dd0957 --- /dev/null +++ b/configs/presets/ayn-odin2-ufs-gnome-zh-cn.yaml @@ -0,0 +1,6 @@ +package: + file: ArchLinuxARM-AYN-Odin2-UFS-GNOME-zh_CN-${version}.7z + configs: + - target/ayn-odin2-ufs + - locale/zh-cn + - desktop/gnome