Compare commits

...

21 Commits

Author SHA1 Message Date
37aed6dfee configs: device/ayn-odin2: add AYN Odin2 RGB LED Tuner
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:16 +08:00
37c8f1ff21 configs: device/ayn-odin2: enable packages/adbd
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:16 +08:00
d44bc72beb configs: device/ayn-odin2: enable common/persistent-mac
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:16 +08:00
c81a64fb06 configs: device/ayn-odin2: add sudo nopasswd
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:16 +08:00
f8fbcbf24c configs: device/ayn-odin2: disable NetworkManager WiFi power save
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:16 +08:00
b58cfb153d configs: target/ayn-odin2-ufs: auto grow rootfs
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:16 +08:00
623fc7e793 configs: packages/systemd-gadget: enable USB Gadget and disable default router
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:16 +08:00
496221588f configs: desktop/gnome: add PackageKit for GNOME Software 2024-05-24 11:58:16 +08:00
cd9a2a504f configs: packages/bluez: add bluez-tools and bluez-utils for bluetoothctl
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:16 +08:00
4bae93f7d8 configs: packages: add adbd for Android Debug Bridge Daemon via USB Gadget
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:16 +08:00
94e33d2565 configs: common: add persistent-mac for Network Interface and Bluetooth
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 11:58:15 +08:00
bb0508cede configs: common: add systemd-wait-for for network wait in units
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 02:58:09 +08:00
0fa8d98e58 builder: disk: filesystem: build.py: remove unnecessary rootflags in kernel cmdline
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 02:57:07 +08:00
97bcdf7379 builder: disk: filesystem: build.py: allow grow filesystem only when GPT partition table unavailable
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 02:57:07 +08:00
b5f69b7b08 configs: add mirrors for download acceleration
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 02:56:29 +08:00
205079fd83 configs: repo: update repo servers to global url
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 02:56:29 +08:00
e54f17a02f builder: component: pacman.py: add pacman mirrors select
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 02:55:18 +08:00
11ee7f3517 builder: lib: subscript.py: SubScript: fix dollar escape
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 02:51:33 +08:00
e49f667db9 builder: lib: subscript.py: add resolve_simple_values
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 02:51:33 +08:00
7ad662ab28 builder: lib: mount.py: fix MountPoint clone option list
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-24 02:51:33 +08:00
84d8a0c247 builder: disk: add image file supports
Signed-off-by: BigfootACA <bigfoot@classfun.cn>
2024-05-23 17:15:18 +08:00
25 changed files with 479 additions and 78 deletions

View File

@ -23,14 +23,15 @@ pacman -S qemu-user-static-binfmt
## Example ## Example
```commandline ```commandline
python build.py -c target/ayn-odin2-sdcard,locale/zh-cn,desktop/gnome python build.py -c target/ayn-odin2-sdcard,locale/zh-cn,desktop/gnome -m bfsu,tuna
``` ```
## Options ## Options
| Option | Description | | Option | Description |
|-------------------------------------|----------------------------------| |-------------------------------------|------------------------------------|
| -C, --clean | Clean workspace before build | | -C, --clean | Clean workspace before build |
| -m MIRROR, --mirror MIRROR | Select mirror to download package |
| -p PRESET, --preset PRESET | Select preset to create package | | -p PRESET, --preset PRESET | Select preset to create package |
| -c CONFIG, --config CONFIG | Select configs to build | | -c CONFIG, --config CONFIG | Select configs to build |
| -o WORKSPACE, --workspace WORKSPACE | Set workspace for builder | | -o WORKSPACE, --workspace WORKSPACE | Set workspace for builder |

View File

@ -4,8 +4,10 @@ import logging
import shutil import shutil
import libarchive import libarchive
from logging import getLogger from logging import getLogger
from builder.lib.serializable import SerializableDict
from builder.lib.context import ArchBuilderContext from builder.lib.context import ArchBuilderContext
from builder.lib.config import ArchBuilderConfigError from builder.lib.config import ArchBuilderConfigError
from builder.lib.subscript import resolve_simple_values
log = getLogger(__name__) log = getLogger(__name__)
@ -30,6 +32,51 @@ def progress_cb(target, percent, n, i):
log.info(f"processing {target} ({i}/{n})") log.info(f"processing {target} ({i}/{n})")
class PacmanRepoServer(SerializableDict):
url: str = None
name: str = None
mirror: bool = False
def __init__(
self,
name: str = None,
url: str = None,
mirror: bool = None
):
if url is not None: self.url = url
if name is not None: self.name = name
if mirror is not None: self.mirror = mirror
class PacmanRepo(SerializableDict):
name: str = None
priority: int = 10000
servers: list[PacmanRepoServer] = None
def __init__(
self,
name: str = None,
priority: int = None,
servers: list[PacmanRepoServer] = None
):
if name is not None: self.name = name
if priority is not None: self.priority = priority
if servers is not None: self.servers = servers
else: self.servers = []
def add_server(
self,
name: str = None,
url: str = None,
mirror: bool = None
):
self.servers.append(PacmanRepoServer(
name=name,
url=url,
mirror=mirror,
))
class Pacman: class Pacman:
handle: pyalpm.Handle handle: pyalpm.Handle
ctx: ArchBuilderContext ctx: ArchBuilderContext
@ -37,17 +84,22 @@ class Pacman:
databases: dict[str: pyalpm.DB] databases: dict[str: pyalpm.DB]
config: dict config: dict
caches: list[str] caches: list[str]
repos: list[PacmanRepo]
def append_repos(self, lines: list[str]): def append_repos(self, lines: list[str]):
""" """
Add all databases into config Add all databases into config
""" """
for repo in self.databases: for repo in self.repos:
db = self.databases[repo] lines.append(f"[{repo.name}]\n")
lines.append(f"[{repo}]\n") for server in repo.servers:
for server in db.servers: if server.mirror:
log.debug(f"server {server}") lines.append(f"# Mirror {server.name}\n")
lines.append(f"Server = {server}\n") log.debug(f"use mirror {server.name} url {server.url}")
else:
lines.append("# Original Repo\n")
log.debug(f"use original repo url {server.url}")
lines.append(f"Server = {server.url}\n")
def append_config(self, lines: list[str]): def append_config(self, lines: list[str]):
""" """
@ -127,54 +179,27 @@ class Pacman:
ret = self.ctx.run_external(cmds) ret = self.ctx.run_external(cmds)
if ret != 0: raise OSError(f"pacman failed with {ret}") if ret != 0: raise OSError(f"pacman failed with {ret}")
def add_database(self, repo: dict):
"""
Add a database and update it
"""
def resolve(url: str) -> str:
"""
Replace pacman.conf variables
"""
return (url
.replace("$arch", self.ctx.tgt_arch)
.replace("$repo", name))
if "name" not in repo:
raise ArchBuilderConfigError("repo name not set")
name = repo["name"]
# never add local into database
if name == "local" or "/" in name:
raise ArchBuilderConfigError("bad repo name")
# register database
if name not in self.databases:
self.databases[name] = self.handle.register_syncdb(
name, pyalpm.SIG_DATABASE_MARGINAL_OK
)
db = self.databases[name]
# add databases servers
servers: list[str] = []
if "server" in repo:
servers.append(resolve(repo["server"]))
if "servers" in repo:
for server in repo["servers"]:
servers.append(resolve(server))
db.servers = servers
# update database now via pyalpm
log.info(f"updating database {name}")
db.update(False)
def load_databases(self): def load_databases(self):
""" """
Add all databases and load them Add all databases and load them
""" """
cfg = self.config for mirror in self.repos:
if "repo" not in cfg: # register database
raise ArchBuilderConfigError("no repos found in config") if mirror.name not in self.databases:
for repo in cfg["repo"]: self.databases[mirror.name] = self.handle.register_syncdb(
self.add_database(repo) mirror.name, pyalpm.SIG_DATABASE_MARGINAL_OK
)
db = self.databases[mirror.name]
# add databases servers
servers: list[str] = []
for server in mirror.servers:
servers.append(server.url)
db.servers = servers
# update database now via pyalpm
log.info(f"updating database {mirror.name}")
db.update(False)
self.init_config() self.init_config()
self.refresh() self.refresh()
@ -231,6 +256,78 @@ class Pacman:
os.makedirs(work_cache, mode=0o0755, exist_ok=True) os.makedirs(work_cache, mode=0o0755, exist_ok=True)
os.makedirs(root_cache, mode=0o0755, exist_ok=True) os.makedirs(root_cache, mode=0o0755, exist_ok=True)
def add_repo(self, repo: PacmanRepo):
if not repo or not repo.name or len(repo.servers) <= 0:
raise ArchBuilderConfigError("bad repo")
self.repos.append(repo)
self.repos.sort(key=lambda r: r.priority)
def init_repos(self):
"""
Initialize mirrors
"""
if "repo" not in self.config:
raise ArchBuilderConfigError("no repos found in config")
mirrors = self.ctx.get("mirrors", [])
for repo in self.config["repo"]:
if "name" not in repo:
raise ArchBuilderConfigError("repo name not set")
# never add local into database
if repo["name"] == "local" or "/" in repo["name"]:
raise ArchBuilderConfigError("bad repo name")
# create pacman repo instance
pacman_repo = PacmanRepo(name=repo["name"])
if "priority" in repo:
pacman_repo.priority = repo["priority"]
originals: list[str] = []
servers: list[str] = []
# add all original repo url
if "server" in repo: servers.append(repo["server"])
if "servers" in repo: servers.extend(repo["server"])
if len(servers) <= 0:
raise ArchBuilderConfigError("no any original repo url found")
# resolve original repo url
for server in servers:
originals.append(resolve_simple_values(server, {
"arch": self.ctx.tgt_arch,
"repo": repo["name"],
}))
# add repo mirror url
for mirror in mirrors:
if "name" not in mirror:
raise ArchBuilderConfigError("mirror name not set")
if "repos" not in mirror:
raise ArchBuilderConfigError("repos list not set")
for repo in mirror["repos"]:
if "original" not in repo:
raise ArchBuilderConfigError("original url not set")
if "mirror" not in repo:
raise ArchBuilderConfigError("mirror url not set")
for original in originals:
if original.startswith(repo["original"]):
path = original[len(repo["original"]):]
real_url = repo["mirror"] + path
pacman_repo.add_server(
name=mirror["name"],
url=real_url,
mirror=True,
)
# add original url
for original in originals:
pacman_repo.add_server(
url=original,
mirror=False
)
self.add_repo(pacman_repo)
def __init__(self, ctx: ArchBuilderContext): def __init__(self, ctx: ArchBuilderContext):
""" """
Initialize pacman context Initialize pacman context
@ -250,7 +347,9 @@ class Pacman:
self.handle.progresscb = progress_cb self.handle.progresscb = progress_cb
self.databases = {} self.databases = {}
self.caches = [] self.caches = []
self.repos = []
self.init_cache() self.init_cache()
self.init_repos()
for cache in self.caches: for cache in self.caches:
self.handle.add_cachedir(cache) self.handle.add_cachedir(cache)
self.init_config() self.init_config()

27
builder/disk/file.py Normal file
View File

@ -0,0 +1,27 @@
import os
from logging import getLogger
from builder.disk.content import ImageContentBuilder
from builder.lib.config import ArchBuilderConfigError
log = getLogger(__name__)
class ImageFileBuilder(ImageContentBuilder):
def build(self):
cmds = ["dd"]
ctx = self.builder.ctx
cfg = self.builder.config
if "file" not in cfg:
raise ArchBuilderConfigError("file not set")
file: str = cfg["file"]
if file.startswith("/"): file = file[1:]
path = os.path.join(ctx.get_rootfs(), file)
if not os.path.exists(path):
raise FileNotFoundError(f"image file {path} not found")
cmds.append("status=progress")
cmds.append(f"if={path}")
cmds.append(f"of={self.builder.device}")
cmds.append(f"bs={self.builder.sector}")
log.info(f"start writing image file {path}")
ret = ctx.run_external(cmds)
if ret != 0: raise OSError("dd failed")
log.info(f"write image file {path} done")

View File

@ -19,6 +19,11 @@ class FileSystemBuilder(ImageContentBuilder):
def proc_cmdline_root(self, cfg: dict, mnt: MountPoint): def proc_cmdline_root(self, cfg: dict, mnt: MountPoint):
ccfg = self.builder.ctx.config_orig ccfg = self.builder.ctx.config_orig
mnt.remove_option("ro")
mnt.remove_option("rw")
for opt in mnt.option:
if opt.startswith("x-"):
mnt.option.remove(opt)
if "kernel" not in ccfg: ccfg["kernel"] = {} if "kernel" not in ccfg: ccfg["kernel"] = {}
kern = ccfg["kernel"] kern = ccfg["kernel"]
if "cmdline" not in kern: kern["cmdline"] = [] if "cmdline" not in kern: kern["cmdline"] = []
@ -27,12 +32,16 @@ class FileSystemBuilder(ImageContentBuilder):
raise ArchBuilderConfigError("root already set in cmdline") raise ArchBuilderConfigError("root already set in cmdline")
if mnt.target != "/": if mnt.target != "/":
log.warning(f"root target is not / ({mnt.target})") log.warning(f"root target is not / ({mnt.target})")
if not mnt.source.startswith("/") and "=" not in mnt.source:
log.warning(f"bad root source ({mnt.source})")
ecmds = [ ecmds = [
"ro", "rootwait", "ro", "rootwait",
f"root={mnt.source}", f"root={mnt.source}",
f"rootfstype={mnt.fstype}",
f"rootflags={mnt.options}",
] ]
if mnt.fstype != "none":
ecmds.append(f"rootfstype={mnt.fstype}")
if len(mnt.option) > 0:
ecmds.append(f"rootflags={mnt.options}")
scmds = " ".join(ecmds) scmds = " ".join(ecmds)
log.debug(f"add root cmdline {scmds}") log.debug(f"add root cmdline {scmds}")
cmds.extend(ecmds) cmds.extend(ecmds)
@ -53,7 +62,10 @@ class FileSystemBuilder(ImageContentBuilder):
def proc_grow(self, cfg: dict, mnt: MountPoint): def proc_grow(self, cfg: dict, mnt: MountPoint):
root = self.builder.ctx.get_rootfs() root = self.builder.ctx.get_rootfs()
if "ptype" not in cfg: raise ArchBuilderConfigError("no ptype set for grow") if "ptype" not in cfg:
log.warning("no partition type set, grow filesystem only")
mnt.option.append("x-systemd.growfs")
return
ptype = DiskTypesGPT.lookup_one_uuid(cfg["ptype"]) ptype = DiskTypesGPT.lookup_one_uuid(cfg["ptype"])
if ptype is None: raise ArchBuilderConfigError(f"unknown type {cfg['ptype']}") if ptype is None: raise ArchBuilderConfigError(f"unknown type {cfg['ptype']}")
mnt.option.append("x-systemd.growfs") mnt.option.append("x-systemd.growfs")
@ -110,7 +122,7 @@ class FileSystemBuilder(ImageContentBuilder):
self.builder.ctx.fstab.append(mnt) self.builder.ctx.fstab.append(mnt)
self.builder.ctx.fsmap[mnt.source] = self.builder.device self.builder.ctx.fsmap[mnt.source] = self.builder.device
if "boot" in fstab and fstab["boot"]: if "boot" in fstab and fstab["boot"]:
self.proc_cmdline_root(cfg, mnt) self.proc_cmdline_root(cfg, mnt.clone())
def format(self, fstype: str): def format(self, fstype: str):
from builder.disk.filesystem.creator import FileSystemCreators from builder.disk.filesystem.creator import FileSystemCreators

View File

@ -2,6 +2,7 @@ from builder.disk.content import ImageContentBuilder
from builder.disk.layout.build import DiskLayoutBuilder from builder.disk.layout.build import DiskLayoutBuilder
from builder.disk.filesystem.build import FileSystemBuilder from builder.disk.filesystem.build import FileSystemBuilder
from builder.disk.abootimg import AndroidBootBuilder from builder.disk.abootimg import AndroidBootBuilder
from builder.disk.file import ImageFileBuilder
types: list[tuple[str, type[ImageContentBuilder]]] = [ types: list[tuple[str, type[ImageContentBuilder]]] = [
@ -9,4 +10,5 @@ types: list[tuple[str, type[ImageContentBuilder]]] = [
("filesystem", FileSystemBuilder), ("filesystem", FileSystemBuilder),
("aboot", AndroidBootBuilder), ("aboot", AndroidBootBuilder),
("avndboot", AndroidBootBuilder), ("avndboot", AndroidBootBuilder),
("image", ImageFileBuilder),
] ]

View File

@ -262,7 +262,7 @@ class MountPoint(SerializableDict):
mnt.source = self.source mnt.source = self.source
mnt.target = self.target mnt.target = self.target
mnt.fstype = self.fstype mnt.fstype = self.fstype
mnt.option = self.option mnt.options = self.options
mnt.fs_freq = self.fs_freq mnt.fs_freq = self.fs_freq
mnt.fs_passno = self.fs_passno mnt.fs_passno = self.fs_passno
return mnt return mnt

View File

@ -39,6 +39,13 @@ def dict_get(key: str, root: dict):
return node return node
def resolve_simple_values(original: str, values: dict) -> str:
value = str(original)
for key in values:
value = value.replace(f"${key}", values[key])
return value
class SubScript: class SubScript:
root: dict root: dict
resolved: list[str] resolved: list[str]
@ -75,7 +82,8 @@ class SubScript:
last = content.find("$", last) last = content.find("$", last)
if last < 0: break if last < 0: break
if content[last:last + 2] == "$$": if content[last:last + 2] == "$$":
last += 2 content = content[:last] + content[last + 1:]
last += 1
continue continue
if len(content) <= last + 2 or content[last + 1] != "{": if len(content) <= last + 2 or content[last + 1] != "{":
raise ValueError(f"unexpected token in subscript at {lvl}") raise ValueError(f"unexpected token in subscript at {lvl}")

View File

@ -18,6 +18,7 @@ def parse_arguments(ctx: ArchBuilderContext):
parser.add_argument("-C", "--clean", help="Clean workspace before build", default=False, action='store_true') parser.add_argument("-C", "--clean", help="Clean workspace before build", default=False, action='store_true')
parser.add_argument("-p", "--preset", help="Select preset to create package") 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("-c", "--config", help="Select config to build", action='append')
parser.add_argument("-m", "--mirror", help="Select mirror to download package", action='append')
parser.add_argument("-o", "--workspace", help="Set workspace for builder", default=ctx.work) 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("-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') parser.add_argument("-G", "--no-gpgcheck", help="Disable GPG check", default=False, action='store_true')
@ -45,6 +46,10 @@ def parse_arguments(ctx: ArchBuilderContext):
pcfgs = ctx.get("package.configs", []) pcfgs = ctx.get("package.configs", [])
configs.extend(pcfgs) configs.extend(pcfgs)
if args.mirror:
for mirror in args.mirror:
configs.extend([f"mirrors/{name}" for name in mirror.split(",")])
# load and populate configs # load and populate configs
config.load_configs(ctx, configs) config.load_configs(ctx, configs)
config.populate_config(ctx) config.populate_config(ctx)

View File

@ -0,0 +1,52 @@
filesystem:
files:
- path: /etc/systemd/scripts/generate-mac.sh
content: |
#!/bin/bash
mac="$$((cat /etc/machine-id; echo "$$@"; ) | sha256sum -)"
echo "42:$${mac:0:2}:$${mac:4:2}:$${mac:8:2}:$${mac:12:2}:$${mac:16:2}"
- path: /etc/systemd/scripts/net-update-mac.sh
content: |
#!/bin/bash
MAC="$$(bash /etc/systemd/scripts/generate-mac.sh "$$@")"
ip link set dev "$$@" down &> /dev/null || true
ip link set dev "$$@" address "$$MAC"
- path: /etc/systemd/scripts/bt-update-mac.sh
content: |
#!/bin/bash
MAC="$$(bash /etc/systemd/scripts/generate-mac.sh bluetooth)"
for i in {0..5}; do
sleep "$$i"
if bluetoothctl mgmt.public-addr "$$MAC"; then
break
fi
done
exit "$$?"
- path: /etc/systemd/system/bt-update-mac.service
content: |
[Unit]
Description=Update Bluetooth Persistent MAC Address
After=bluetooth.service systemd-machine-id-commit.service
Wants=bluetooth.service
[Service]
Type=oneshot
ExecStart=bash /etc/systemd/scripts/bt-update-mac.sh
SyslogIdentifier=bt-update-mac
[Install]
WantedBy=bluetooth.target
- path: /etc/systemd/system/net-update-mac@.service
content: |
[Unit]
Description=Update Persistent MAC Address for %i
Before=network.target
After=wait-interface@%i.service systemd-machine-id-commit.service
Wants=wait-interface@%i.service
[Service]
Type=oneshot
ExecStart=bash /etc/systemd/scripts/net-update-mac.sh %i
SyslogIdentifier=wlan-update-mac
[Install]
WantedBy=sysinit.target
+also:
- packages/bluez
- common/systemd-wait-for

View File

@ -0,0 +1,80 @@
filesystem:
files:
- path: /etc/systemd/system/wait-addresses@.service
content: |
[Unit]
Description=Wait for addresses %i
[Service]
Type=oneshot
ExecStart=bash /etc/systemd/scripts/wait-addresses.sh %i 60
SyslogIdentifier=wait-addresses
[Install]
WantedBy=network-online.target
- path: /etc/systemd/system/wait-interface@.service
content: |
[Unit]
Description=Wait for interface %i
[Service]
Type=oneshot
ExecStart=bash /etc/systemd/scripts/wait-interface.sh %i 60
SyslogIdentifier=wait-interface
[Install]
WantedBy=network-online.target
- path: /etc/systemd/system/wait-reached@.service
content: |
[Unit]
Description=Wait for reached %i
After=network-online.target
[Service]
Type=oneshot
ExecStart=bash /etc/systemd/scripts/wait-reached.sh %i 60
SyslogIdentifier=wait-reached
[Install]
WantedBy=network-online.target
- path: /etc/systemd/scripts/wait-addresses.sh
content: |
#!/usr/bin/bash
address="$${1}"
timeout="$${2}"
[ -z "$${address}" ]&&exit 2
[ -z "$${timeout}" ]&&timeout=10
[[ "$${timeout}" -lt 0 ]]&&exit 2
int=0
timeout=$$((timeout*5))
while ! ip address show | grep -w "$${address}" &>/dev/null; do
int=$$((int+1))
[[ "$${int}" -gt "$${timeout}" ]]&&exit 1
sleep 0.2
done
true
- path: /etc/systemd/scripts/wait-interface.sh
content: |
#!/usr/bin/bash
interface="$${1}"
timeout="$${2}"
[ -z "$${interface}" ]&&exit 2
[ -z "$${timeout}" ]&&timeout=10
[[ "$${timeout}" -lt 0 ]]&&exit 2
int=0
timeout=$$((timeout*5))
while ! [ -h "/sys/class/net/$${interface}" ]; do
int=$$((int+1))
[[ "$${int}" -gt "$${timeout}" ]]&&exit 1
sleep 0.2
done
true
- path: /etc/systemd/scripts/wait-reached.sh
content: |
#!/usr/bin/bash
address="$${1}"
stimeout="$${2}"
[ -z "$${address}" ]&&exit 2
[ -z "$${stimeout}" ]&&stimeout=10
[[ "$${stimeout}" -lt 0 ]]&&exit 2
int=0
while ! timeout 1s ping -c 1 -W 1 "$${address}" &>/dev/null; do
int=$$((int+1))
[[ "$${int}" -gt "$${stimeout}" ]]&&exit 1
sleep 0.5
done
true

View File

@ -2,6 +2,7 @@
pacman: pacman:
install: install:
- gnome - gnome
- gnome-packagekit
systemd: systemd:
default: graphical.target default: graphical.target
enable: enable:

View File

@ -25,10 +25,16 @@ pacman:
# Vulkan dependency # Vulkan dependency
- xcb-util-keysyms - xcb-util-keysyms
# AYN Odin2 RGB LED Tuner
- rgb-led
systemd: systemd:
disable: disable:
# No modem in this device # No modem in this device
- rmtfs.service - rmtfs.service
enable:
- bt-update-mac.service
- net-update-mac@wlp1s0.service
filesystem: filesystem:
files: files:
# GamePAD workaround # GamePAD workaround
@ -54,6 +60,10 @@ filesystem:
[Resolve] [Resolve]
MulticastDNS=no MulticastDNS=no
LLMNR=no LLMNR=no
- path: /etc/NetworkManager/conf.d/80-no-wifi-powersave.conf
content: |
[connection]
wifi.powersave = 2
sysconf: sysconf:
chassis: handset chassis: handset
environments: environments:
@ -102,6 +112,9 @@ mkinitcpio:
# USB Gadget tools # USB Gadget tools
- packages/systemd-gadget - packages/systemd-gadget
# Android Debug Bridge Daemon via USB Gadget
- packages/adbd
# OpenSSH Server # OpenSSH Server
- packages/openssh - packages/openssh
@ -110,3 +123,9 @@ mkinitcpio:
# Bluetooth related services # Bluetooth related services
- packages/bluez - packages/bluez
# Persistent MAC Address
- common/persistent-mac
# Root without password
- common/wheel-nopasswd

26
configs/mirrors/bfsu.yaml Normal file
View File

@ -0,0 +1,26 @@
mirrors:
- name: bfsu
repos:
# ArchLinux
- original: https://geo.mirror.pkgbuild.com/
mirror: https://mirrors.bfsu.edu.cn/archlinux/
# ArchLinux ARM
- name: archlinuxarm
original: http://mirror.archlinuxarm.org/
mirror: https://mirrors.bfsu.edu.cn/archlinuxarm/
# Arch4Edu
- name: arch4edu
original: https://repository.arch4edu.org/
mirror: https://mirrors.bfsu.edu.cn/arch4edu/
# ArchLinux CN
- name: archlinuxcn
original: https://repo.archlinuxcn.org/
mirror: https://mirrors.bfsu.edu.cn/archlinuxcn/
# BlackArch
- name: blackarch
original: https://www.blackarch.org/blackarch/
mirror: https://mirrors.bfsu.edu.cn/blackarch/

26
configs/mirrors/tuna.yaml Normal file
View File

@ -0,0 +1,26 @@
mirrors:
- name: tuna
repos:
# ArchLinux
- original: https://geo.mirror.pkgbuild.com/
mirror: https://mirrors.tuna.tsinghua.edu.cn/archlinux/
# ArchLinux ARM
- name: archlinuxarm
original: http://mirror.archlinuxarm.org/
mirror: https://mirrors.tuna.tsinghua.edu.cn/archlinuxarm/
# Arch4Edu
- name: arch4edu
original: https://repository.arch4edu.org/
mirror: https://mirrors.tuna.tsinghua.edu.cn/arch4edu/
# ArchLinux CN
- name: archlinuxcn
original: https://repo.archlinuxcn.org/
mirror: https://mirrors.tuna.tsinghua.edu.cn/archlinuxcn/
# BlackArch
- name: blackarch
original: https://www.blackarch.org/blackarch/
mirror: https://mirrors.tuna.tsinghua.edu.cn/blackarch/

21
configs/mirrors/ustc.yaml Normal file
View File

@ -0,0 +1,21 @@
mirrors:
- name: ustc
repos:
# ArchLinux
- original: https://geo.mirror.pkgbuild.com/
mirror: https://mirrors.ustc.edu.cn/archlinux/
# ArchLinux ARM
- name: archlinuxarm
original: http://mirror.archlinuxarm.org/
mirror: https://mirrors.ustc.edu.cn/archlinuxarm/
# ArchLinux CN
- name: archlinuxcn
original: https://repo.archlinuxcn.org/
mirror: https://mirrors.ustc.edu.cn/archlinuxcn/
# BlackArch
- name: blackarch
original: https://www.blackarch.org/blackarch/
mirror: https://mirrors.ustc.edu.cn/blackarch/

View File

@ -0,0 +1,9 @@
# Android Debug Bridge Daemon via USB Gadget
pacman:
install:
- adbd
systemd:
enable:
- adbd-usb.service
+also:
- packages/systemd-gadget

View File

@ -2,6 +2,8 @@
pacman: pacman:
install: install:
- bluez - bluez
- bluez-tools
- bluez-utils
systemd: systemd:
enable: enable:
- bluetooth.service - bluetooth.service

View File

@ -9,5 +9,15 @@ systemd:
- getty@ttyGS0.service - getty@ttyGS0.service
- usbgadget-func-acm.service - usbgadget-func-acm.service
enable: enable:
- gadget-init.service
- gadget-start.service
- usbgadget-func-rndis.service
# Enable systemd-networkd for RNDIS # Enable systemd-networkd for RNDIS
- systemd-networkd.service - systemd-networkd.service
filesystem:
files:
- path: /etc/systemd/network/sharenet.network.d/override.conf
content: |
[DHCPServer]
EmitRouter=no
EmitDNS=no

View File

@ -2,6 +2,6 @@ pacman:
repo: repo:
- name: arch4edu - name: arch4edu
priority: 800 priority: 800
server: https://mirrors.bfsu.edu.cn/arch4edu/${arch} server: https://repository.arch4edu.org/$$arch
install: install:
- arch4edu/arch4edu-keyring - arch4edu/arch4edu-keyring

View File

@ -2,13 +2,13 @@ pacman:
repo: repo:
- name: core - name: core
priority: 100 priority: 100
server: https://mirrors.bfsu.edu.cn/archlinux/core/os/${arch} server: https://geo.mirror.pkgbuild.com/$$repo/os/$$arch
- name: extra - name: extra
priority: 110 priority: 110
server: https://mirrors.bfsu.edu.cn/archlinux/extra/os/${arch} server: https://geo.mirror.pkgbuild.com/$$repo/os/$$arch
- name: multilib - name: multilib
priority: 120 priority: 120
server: https://mirrors.bfsu.edu.cn/archlinux/multilib/os/${arch} server: https://geo.mirror.pkgbuild.com/$$repo/os/$$arch
trust: trust:
- eworm@archlinux.org - eworm@archlinux.org
- dvzrv@archlinux.org - dvzrv@archlinux.org

View File

@ -2,16 +2,16 @@ pacman:
repo: repo:
- name: core - name: core
priority: 100 priority: 100
server: http://mirrors.bfsu.edu.cn/archlinuxarm/${arch}/core server: http://mirror.archlinuxarm.org/$$arch/$$repo
- name: extra - name: extra
priority: 110 priority: 110
server: https://mirrors.bfsu.edu.cn/archlinuxarm/${arch}/extra server: http://mirror.archlinuxarm.org/$$arch/$$repo
- name: alarm - name: alarm
priority: 120 priority: 120
server: https://mirrors.bfsu.edu.cn/archlinuxarm/${arch}/alarm server: http://mirror.archlinuxarm.org/$$arch/$$repo
- name: aur - name: aur
priority: 130 priority: 130
server: https://mirrors.bfsu.edu.cn/archlinuxarm/${arch}/aur server: http://mirror.archlinuxarm.org/$$arch/$$repo
trust: trust:
- builder@archlinuxarm.org - builder@archlinuxarm.org
install: install:

View File

@ -2,7 +2,7 @@ pacman:
repo: repo:
- name: archlinuxcn - name: archlinuxcn
priority: 500 priority: 500
server: https://mirrors.bfsu.edu.cn/archlinuxcn/${arch} server: https://repo.archlinuxcn.org/$$arch
trust: trust:
- farseerfc@archlinux.org - farseerfc@archlinux.org
install: install:

View File

@ -2,7 +2,7 @@ pacman:
repo: repo:
- name: blackarch - name: blackarch
priority: 1000 priority: 1000
server: https://mirrors.bfsu.edu.cn/blackarch/blackarch/os/${arch} server: https://www.blackarch.org/$$repo/os/$$arch
trust: trust:
- noptrix@nullsecurity.net - noptrix@nullsecurity.net
install: install:

View File

@ -2,7 +2,7 @@ pacman:
repo: repo:
- name: renegade-project - name: renegade-project
priority: 200 priority: 200
server: https://mirror.renegade-project.tech/arch/${arch} server: https://mirror.renegade-project.tech/arch/$$arch
trust: trust:
- renegade-project@classfun.cn - renegade-project@classfun.cn
install: install:

View File

@ -9,6 +9,7 @@ image:
size: 8GiB size: 8GiB
sector: 4096 sector: 4096
mount: / mount: /
grow: yes
fstab: fstab:
boot: yes boot: yes
flags: rw,noatime,discard flags: rw,noatime,discard