Compare commits

..

1 Commits

Author SHA1 Message Date
251b54937b Use --detached worktrees 2025-08-05 14:13:27 -04:00
3 changed files with 217 additions and 401 deletions

View File

@@ -12,12 +12,10 @@ Build and deploy OpenWRT images using shell-style device profiles, via source co
--profile,-p PROFILE --profile,-p PROFILE
--release,-r,--version,-v RELEASE ("snapshot", "22.03.3") --release,-r,--version,-v RELEASE ("snapshot", "22.03.3")
--buildroot,-b PATH (Default: script directory) --buildroot,-b PATH (Default: script directory)
--cpus,-c NUM --source
Default: # of host CPUS minus 1 Build image from source code, not from Image Builder
--mode,-m imagebuilder|source Allows make config options to be passed in profile
Default: imagebuilder Uses git worktree for multi-profile deduplication
--clean clean|targetclean|dirclean|distclean
Optional clean step for source mode
--ssh-upgrade HOST --ssh-upgrade HOST
Example: root@192.168.1.1 Example: root@192.168.1.1
--ssh-backup SSH_PATH --ssh-backup SSH_PATH
@@ -39,39 +37,14 @@ Build and deploy OpenWRT images using shell-style device profiles, via source co
See `profiles` for example device profile definitions. Multiple `--profile` can be passed at once. See `profiles` for example device profile definitions. Multiple `--profile` can be passed at once.
The default build mode is `imagebuilder` unless `--mode=source` is passed. Default profile modes can be set individually in `profiles`. The default build mode is `imagebuilder` unless `--source` is passed. Default profile modes can be set individually in `profiles`.
`--mode=imagebuilder` inherits `CONFIG_TARGET_ROOTFS_PARTSIZE=`, but all other kconfigs only work in `--mode=source`.
Profile keys:
| Key | Required | Description |
|---|---|---|
| `mode` | No | Build mode for this profile: `imagebuilder` or `source`. CLI `--mode` overrides profile value. |
| `device` | Yes | OpenWrt device/profile id used by build commands (for example `friendlyarm_nanopi-r4s`). |
| `target` | Yes | OpenWrt target/subtarget (for example `rockchip/armv8`, `x86/64`). |
| `filesystem` | No | Root filesystem type (`squashfs`, `ext4`, etc). Defaults to `squashfs`. |
| `packages` | No | Space-separated package list. Prefix with `-` to remove a package in Image Builder or source config generation. |
| `kconfigs` | No | Space-separated Kconfig symbols. In `imagebuilder` mode only `CONFIG_TARGET_ROOTFS_PARTSIZE=<MB>` is used (mapped to `ROOTFS_PARTSIZE`). In `source` mode all entries are written to `.config` seed. |
| `files` | No | Host directory containing custom overlay files. In `imagebuilder` mode this is passed as `FILES=<dir>`. In `source` mode contents are synced into `<build dir>/files/` before build. Defaults to `<buildroot>/src/files`. |
| `cherrypicks` | No | Space-separated entries in `URL@branch:commit` form. Each commit is fetched and cherry-picked in `source` mode. |
| `branches` | No | Space-separated `URL@branch` entries to merge into the source worktree in `source` mode. |
| `release` | No | Default release/ref for the profile (for example `snapshot`, `25.12.3`). CLI `--release` overrides it. |
| `clean` | No | Optional source cleanup step (`clean`, `targetclean`, `dirclean`, `distclean`). CLI `--clean` overrides it. |
| `repo` | No | Extra Image Builder repository line appended to `repositories.conf` before build. |
Notes:
* The profile file uses associative arrays (`declare -Ag name=( [key]="value" ... )`).
* `packages`, `kconfigs`, `cherrypicks`, and `branches` are parsed as scalar whitespace-separated strings.
* If a profile-specific `files` path is configured, it must exist.
## Examples ## Examples
* `openwrtbuilder -p r4s -p ax6000` * `openwrtbuilder -p r4s -p ax6000`
* `openwrtbuilder -p r4s -r snapshot --debug` * `openwrtbuilder -p r4s -r snapshot --debug`
* `openwrtbuilder -p ax6000 -r 25.12.3 --mode source --debug` * `openwrtbuilder -p ax6000 -r 23.05.5 --source --debug`
* `openwrtbuilder -p rpi4 -r 25.12.3 --flash /dev/sdX` * `openwrtbuilder -p rpi4 -r 23.05.5 --flash /dev/sdX`
* `openwrtbuilder -p linksys -r snapshot --ssh-upgrade root@192.168.1.1` * `openwrtbuilder -p linksys -r snapshot --ssh-upgrade root@192.168.1.1`
## Additional Info ## Additional Info

View File

@@ -1,51 +1,49 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Build and deploy OpenWRT images using shell-style device profiles, via source code or the official Image Builder. # Build and deploy OpenWRT images using shell-style device profiles, via source code or the official Image Builder.# Copyright 2022-25 Bryan C. Roessler
# Copyright 2022-26 Bryan C. Roessler
# Apache 2.0 License # Apache 2.0 License
# See README and ./profiles for device configuration # See README and profiles for device configuration
# Set default release # Set default release
: "${DEFAULT_RELEASE:=${RELEASE:="25.12.3"}}" # do find all replace : "${RELEASE:="24.10.2"}"
# @internal # @internal
usage() { print_help() {
debug "${FUNCNAME[0]}" debug "${FUNCNAME[0]}"
cat <<-'EOF' cat <<-'EOF'
Build and deploy OpenWRT images using convenient profiles. Build and deploy OpenWRT images using convenient profiles.
USAGE: USAGE:
openwrtbuilder [OPTIONS] [-p PROFILE]... openwrtbuilder [OPTION [VALUE]]... -p PROFILE [-p PROFILE]...
OPTIONS OPTIONS
--profile,-p PROFILE --profile,-p PROFILE
--release,-r,--version,-v RELEASE ("snapshot", "25.12.3") --release,-r,--version,-v RELEASE ("snapshot", "22.03.5")
Default: From profile or hardcoded RELEASE
--buildroot,-b PATH --buildroot,-b PATH
Default: location of openwrtbuilder script Default: location of openwrtbuilder script
--cpus,-c NUM --source
Default: # of host CPUS minus 1 Build image from source, not from Image Builder
--mode,-m imagebuilder|source Allows make config options to be passed in profile
Default: imagebuilder Uses git worktree for multi-profile deduplication
--clean clean|targetclean|dirclean|distclean
Optional clean step for source mode
--ssh-upgrade HOST --ssh-upgrade HOST
Examples: root@192.168.1.1, root@router.lan Examples: root@192.168.1.1, root@router.lan
--ssh-backup SSH_PATH --ssh-backup SSH_PATH
Enabled by default for --ssh-upgrade Enabled by default for --ssh-upgrade
--flash,-f DEVICE --flash,-f DEVICE
Example: /dev/sdX Example: /dev/sdX
--reset
Cleanup all source and output files
--depends --depends
Force dependency installation Force dependency installation
--yes,-y --yes,-y
Assume yes for all questions (non-interactive) Assume yes for all questions (automatic mode)
--debug,-d --debug,-d
--help,-h --help,-h
EXAMPLES EXAMPLES
openwrtbuilder -p r4s -r snapshot openwrtbuilder -p r4s -r snapshot
openwrtbuilder -p ax6000 -r 23.05.0-rc3 --mode source --debug openwrtbuilder -p ax6000 -r 23.05.0-rc3 --source --debug
openwrtbuilder -p rpi4 -r 25.12.3 --flash /dev/sdX openwrtbuilder -p rpi4 -r 24.10.0 --flash /dev/sdX
openwrtbuilder -p linksys -r snapshot --ssh-upgrade root@192.168.1.1 openwrtbuilder -p linksys -r snapshot --ssh-upgrade root@192.168.1.1
EOF EOF
} }
@@ -59,14 +57,14 @@ init() {
# Save the script directory # Save the script directory
# https://stackoverflow.com/a/4774063 # https://stackoverflow.com/a/4774063
SCRIPT_DIR=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")") SCRIPT_DIR="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 || exit $? ; pwd -P)"
if [[ -e "/etc/os-release" ]]; then if [[ -e "/etc/os-release" ]]; then
source "/etc/os-release" source "/etc/os-release"
else else
echo "/etc/os-release not found" echo "/etc/os-release not found"
echo "Your OS is unsupported" echo "Your OS is unsupported"
usage print_help
exit 1 exit 1
fi fi
@@ -127,21 +125,19 @@ init() {
parse_input() { parse_input() {
debug "${FUNCNAME[0]}" "$*" debug "${FUNCNAME[0]}" "$*"
declare -ga PROFILES declare -ga PROFILES
declare -gi RESET=0 YES=0 DEBUG=0 FORCE_DEPENDS=0 CPUS=0 declare -gi RESET=0 FROM_SOURCE=0 YES=0 DEBUG=0 FORCE_DEPENDS=0
declare -g USER_RELEASE SSH_UPGRADE_PATH SSH_BACKUP_PATH FLASH_DEV USER_MODE USER_CLEAN declare -g USER_RELEASE SSH_UPGRADE_PATH SSH_BACKUP_PATH FLASH_DEV
local long_opts='release:,version:,profile:,buildroot:,cpus:,mode:,clean:' local long_opts='release:,version:,profile:,buildroot:,source,'
long_opts+='ssh-upgrade:,ssh-backup:,flash:,reset,depends,yes,debug,help' long_opts+='ssh-upgrade:,ssh-backup:,flash:,reset,depends,yes,debug,help'
if _input=$(getopt -o +r:v:p:b:m:c:f:ydh -l $long_opts -- "$@"); then if _input=$(getopt -o +r:v:p:b:sf:ydh -l $long_opts -- "$@"); then
eval set -- "$_input" eval set -- "$_input"
while true; do while true; do
case "$1" in case "$1" in
--release|-r|--version|-v) shift; USER_RELEASE="$1" ;; --release|-r|--version|-v) shift; USER_RELEASE="$1" ;;
--profile|-p) shift; PROFILES+=("$1") ;; --profile|-p) shift; PROFILES+=("$1") ;;
--buildroot|-b) shift; BUILD_ROOT="$1" ;; --buildroot|-b) shift; BUILD_ROOT="$1" ;;
--mode|-m) shift; USER_MODE="$1" ;; --source|-s) FROM_SOURCE=1 ;;
--clean) shift; USER_CLEAN="$1" ;;
--cpus|-c) shift; CPUS="$1" ;;
--ssh-upgrade) shift; SSH_UPGRADE_PATH="$1" ;; --ssh-upgrade) shift; SSH_UPGRADE_PATH="$1" ;;
--ssh-backup) shift; SSH_BACKUP_PATH="$1" ;; --ssh-backup) shift; SSH_BACKUP_PATH="$1" ;;
--flash|-f) shift; FLASH_DEV="$1" ;; --flash|-f) shift; FLASH_DEV="$1" ;;
@@ -149,14 +145,14 @@ parse_input() {
--depends) FORCE_DEPENDS=1 ;; --depends) FORCE_DEPENDS=1 ;;
--yes|-y) YES=1 ;; --yes|-y) YES=1 ;;
--debug|-d) echo "Debugging on"; DEBUG=1 ;; --debug|-d) echo "Debugging on"; DEBUG=1 ;;
--help|-h) usage; exit 0 ;; --help|-h) print_help; exit 0 ;;
--) shift; break ;; --) shift; break ;;
esac esac
shift shift
done done
else else
echo "Incorrect options provided" echo "Incorrect options provided"
usage; exit 1 print_help; exit 1
fi fi
} }
@@ -172,10 +168,10 @@ install_dependencies() {
if [[ "$mode" == "source" ]]; then if [[ "$mode" == "source" ]]; then
lock_file="$BUILD_ROOT/.dependencies_source.lock" lock_file="$BUILD_ROOT/.dependencies_source.lock"
elif [[ "$mode" == "imagebuilder" ]]; then elif [[ "$mode" == "imagebuilder" ]]; then
lock_file="$BUILD_ROOT/.dependencies_imagebuilder.lock" lock_file="$BUILD_ROOT/.dependencies_ib.lock"
fi fi
[[ -f $lock_file ]] && debug "$lock_file lock file exists, skipping dependency install" && return 0 [[ -f $lock_file ]] && debug "$lock_file lock file exists" && return 0
if [[ "$mode" == "source" ]]; then if [[ "$mode" == "source" ]]; then
# For building from source code see: # For building from source code see:
@@ -189,7 +185,6 @@ install_dependencies() {
gcc gcc
gcc-c++ gcc-c++
git git
golang
llvm15-libs # for qosify llvm15-libs # for qosify
make make
ncurses-devel ncurses-devel
@@ -208,7 +203,6 @@ install_dependencies() {
python3-devel python3-devel
python3-pyelftools python3-pyelftools
python3-setuptools python3-setuptools
quilt
rsync rsync
swig swig
tar tar
@@ -227,12 +221,10 @@ install_dependencies() {
gcc-multilib gcc-multilib
gettext gettext
git git
golang
liblzma-dev liblzma-dev
libncurses5-dev libncurses5-dev
libssl-dev libssl-dev
python3-distutils python3-distutils
quilt
rsync rsync
patch patch
unzip unzip
@@ -257,7 +249,6 @@ install_dependencies() {
gcc gcc
gettext gettext
git git
golang
grep grep
groff groff
gzip gzip
@@ -272,7 +263,6 @@ install_dependencies() {
patch patch
pkgconf pkgconf
python python
quilt
rsync rsync
sed sed
texinfo texinfo
@@ -403,51 +393,31 @@ ssh_backup() {
[[ -d "$FILES_DIR" ]] || execute mkdir -p "$FILES_DIR" [[ -d "$FILES_DIR" ]] || execute mkdir -p "$FILES_DIR"
# Make backup archive on remote # Make backup archive on remote
if ! execute ssh -t "$SSH_BACKUP_PATH" sysupgrade -b "/tmp/$backup_fname"; then if ! execute "ssh -t $SSH_BACKUP_PATH sysupgrade -b /tmp/$backup_fname"; then
echo "SSH backup failed" echo "SSH backup failed"
exit 1 exit 1
fi fi
# Move backup archive locally # Move backup archive locally
if ! execute rsync -avz --remove-source-files "$SSH_BACKUP_PATH:/tmp/$backup_fname" "$BUILD_DIR/"; then if ! execute "rsync -avz --remove-source-files $SSH_BACKUP_PATH:/tmp/$backup_fname $BUILD_DIR/"; then
echo "Could not copy SSH backup" echo "Could not copy SSH backup"
exit 1 exit 1
fi fi
# Extract backup archive # Extract backup archive
if ! execute tar -C "$FILES_DIR" -xzf "$BUILD_DIR/$backup_fname"; then if ! execute "tar -C $FILES_DIR -xzf $BUILD_DIR/$backup_fname"; then
echo "Could not extract SSH backup" echo "Could not extract SSH backup"
exit 1 exit 1
fi fi
execute rm "$BUILD_DIR/$backup_fname" execute "rm $BUILD_DIR/$backup_fname"
} }
make_images() { make_images() {
debug "${FUNCNAME[0]}" debug "${FUNCNAME[0]}"
local -a make_opts; ((DEBUG)) && make_opts+=("V=sc") local -a make_opts
local rootfs_partsize
# Image Builder accepts ROOTFS_PARTSIZE, not CONFIG_TARGET_ROOTFS_PARTSIZE.
# Parse profile KCONFIGS (scalar string) and extract only this value.
for kconfig in $KCONFIGS; do
case "$kconfig" in
CONFIG_TARGET_ROOTFS_PARTSIZE=*) rootfs_partsize="${kconfig#*=}" ;;
esac
done
local -a make_cmd=(make "${make_opts[@]}" image
BIN_DIR="$BIN_DIR"
PROFILE="$DEVICE"
PACKAGES="$PACKAGES"
FILES="$FILES_DIR"
--directory="$BUILD_DIR"
--jobs="$JOBS")
[[ -n "$rootfs_partsize" ]] && make_cmd+=("ROOTFS_PARTSIZE=$rootfs_partsize")
# Reuse the existing output # Reuse the existing output
# TODO Disable for now since it was causing issues
# if [[ -d "$BIN_DIR" ]]; then # if [[ -d "$BIN_DIR" ]]; then
# if ask_ok "$BIN_DIR exists. Rebuild?"; then # if ask_ok "$BIN_DIR exists. Rebuild?"; then
# execute rm -rf "$BIN_DIR" # execute rm -rf "$BIN_DIR"
@@ -456,10 +426,21 @@ make_images() {
# fi # fi
# fi # fi
# Debug manually so we can log output ((DEBUG)) && make_opts+=("V=sc")
debug "${make_cmd[*]}"
"${make_cmd[@]}" 2>&1 | tee "$BUILD_DIR/make.log" debug make "${make_opts[@]}" image BIN_DIR="$BIN_DIR" \
return "${PIPESTATUS[0]}" # bash-specific way to return exit code of piped command PROFILE="$DEVICE" PACKAGES="$PACKAGES" \
FILES="$FILES_DIR" --directory="$BUILD_DIR" \
--jobs="$(($(nproc) - 1))"
make "${make_opts[@]}" image \
BIN_DIR="$BIN_DIR" \
PROFILE="$DEVICE" \
PACKAGES="$PACKAGES" \
FILES="$FILES_DIR" \
--directory="$BUILD_DIR" \
--jobs="$(($(nproc) - 1))" \
> "$BUILD_DIR/make.log"
} }
flash_images() { flash_images() {
@@ -467,8 +448,9 @@ flash_images() {
local img_gz="$1" local img_gz="$1"
local dev="$2" local dev="$2"
local img="${img_gz%.gz}" local img="${img_gz%.gz}"
local partitions
if [[ ! -b "$dev" ]]; then if [[ ! -e "$dev" ]]; then
echo "The device specified by --flash could not be found" echo "The device specified by --flash could not be found"
return 1 return 1
fi fi
@@ -476,13 +458,13 @@ flash_images() {
[[ -f $img_gz ]] || { echo "$img_gz does not exist"; return 1; } [[ -f $img_gz ]] || { echo "$img_gz does not exist"; return 1; }
execute gunzip -qfk "$img_gz" execute gunzip -qfk "$img_gz"
[[ -f "$img" ]] || { echo "Extracted image '$img' is missing"; return 1; }
echo "Unmounting target device $dev partitions"
partitions=("$dev"?*)
execute sudo umount "${partitions[@]}"
if execute sudo dd if="$img" of="$dev" bs=2M conv=fsync; then if execute sudo dd if="$img" of="$dev" bs=2M conv=fsync; then
sync sync
if command -v partprobe &>/dev/null; then
execute sudo partprobe "$dev" || debug "partprobe failed for $dev"
fi
echo "Image flashed successfully!" echo "Image flashed successfully!"
else else
echo "dd failed!" echo "dd failed!"
@@ -512,35 +494,24 @@ ssh_upgrade() {
} }
# @description Builds OpenWRT from source code using the the default buildbot as base # @description Builds OpenWRT from source code using the the default buildbot as base
# This enables the use of kernel config options in profiles
# @arg $1 string .config seed URL
# @arg $2 string Profile name
# @arg $3 string Worktree ref (commit-ish or branch name)
from_source() { from_source() {
debug "${FUNCNAME[0]}" debug "${FUNCNAME[0]}" "$*"
local seed_url="$1"
local profile="$2"
local ref="$3"
local src_url="https://github.com/openwrt/openwrt.git" local src_url="https://github.com/openwrt/openwrt.git"
local seed_file="$BUILD_DIR/.config" local seed_file="$BUILD_DIR/.config"
local worktree_meta="$SRC_DIR/.git/worktrees/source-$REF" local worktree_meta="$SRC_DIR/.git/worktrees/source-$ref"
local pkg kconfig commit description local pkg config commit seed_file description
local -a make_opts local -a make_opts config_opts
local -a kconfigs=(
"CONFIG_TARGET_${TARGET%%/*}=y"
"CONFIG_TARGET_${TARGET//\//_}=y"
"CONFIG_TARGET_PROFILE=DEVICE_$DEVICE"
"CONFIG_TARGET_${TARGET//\//_}_DEVICE_$DEVICE=y"
"CONFIG_TARGET_ROOTFS_${FILESYSTEM^^}=y"
"CONFIG_TARGET_MULTI_PROFILE=n"
"CONFIG_BUILDBOT=n"
"CONFIG_ALL_KMODS=n"
"CONFIG_ALL_NONSHARED=n"
"CONFIG_DEVEL=n"
"CONFIG_COLLECT_KERNEL_DEBUG=n"
"CONFIG_SDK=n"
"CONFIG_SDK_LLVM_BPF=n"
"CONFIG_IB=n"
"CONFIG_MAKE_TOOLCHAIN=n"
"CONFIG_TARGET_PER_DEVICE_ROOTFS=n"
)
echo "Building from source is under development" echo "Building from source is under development"
# Remove all build directories and worktrees if --reset # Remove all build directories and worktrees
if ((RESET)); then if ((RESET)); then
if [[ -d "$BUILD_DIR" || -d "$worktree_meta" ]]; then if [[ -d "$BUILD_DIR" || -d "$worktree_meta" ]]; then
execute git -C "$SRC_DIR" worktree remove --force --force "$BUILD_DIR" execute git -C "$SRC_DIR" worktree remove --force --force "$BUILD_DIR"
@@ -550,101 +521,24 @@ from_source() {
[[ -d "$BUILD_DIR" ]] && execute rm -rf "$BUILD_DIR" [[ -d "$BUILD_DIR" ]] && execute rm -rf "$BUILD_DIR"
fi fi
# Fetch or clone source repo (no local merges) # Pull or clone source repo
if [[ -d "$SRC_DIR" ]]; then if [[ -d "$SRC_DIR" ]]; then
execute git -C "$SRC_DIR" fetch origin --tags --prune execute git -C "$SRC_DIR" pull
else else
execute mkdir -p "$SRC_DIR" execute mkdir -p "$SRC_DIR"
execute git clone "$src_url" "$SRC_DIR" execute git clone "$src_url" "$SRC_DIR"
fi fi
# Reuse worktree if present; otherwise create it (support branches and tags) # Remove existing build dir and add new worktree
if git -C "$BUILD_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then if [[ -d "$BUILD_DIR" ]]; then
execute git -C "$BUILD_DIR" fetch origin --tags --prune execute rm -rf "$BUILD_DIR"
execute git -C "$BUILD_DIR" reset --hard "origin/$REF" || \
execute git -C "$BUILD_DIR" reset --hard "$REF" || \
execute git -C "$BUILD_DIR" checkout --detach "$REF"
else
execute git -C "$SRC_DIR" worktree prune --verbose
# Prefer local tag/branch if present, otherwise use remote-tracking branch
if ! execute git -C "$SRC_DIR" worktree add --detach "$BUILD_DIR" "$REF"; then
execute git -C "$SRC_DIR" worktree add --detach "$BUILD_DIR" "origin/$REF"
fi
fi fi
execute git -C "$SRC_DIR" worktree prune --verbose
execute git -C "$SRC_DIR" worktree add --detached "$BUILD_DIR" "$ref"
# Add cherrypicks
for cherrypick in $CHERRYPICKS; do
url_branch="${cherrypick%:*}"
commit="${cherrypick##*:}"
branch=""
url="$url_branch"
if [[ "$url_branch" == *"@"* ]]; then
url="${url_branch%@*}"
branch="${url_branch#*@}"
fi
remote="${url%.git}"
remote="${remote##*/}"
remote=${remote//[^A-Za-z0-9._-]/_}
[[ -z $remote ]] && remote="cherry"
if ! git -C "$BUILD_DIR" remote | grep -q "^$remote$"; then
execute git -C "$BUILD_DIR" remote add "$remote" "$url"
else
execute git -C "$BUILD_DIR" remote set-url "$remote" "$url"
fi
if [[ -n $branch ]]; then
execute git -C "$BUILD_DIR" fetch "$remote" "$branch"
else
execute git -C "$BUILD_DIR" fetch "$remote"
fi
# Verify commit exists before attempting cherry-pick
if ! git -C "$BUILD_DIR" cat-file -e "$commit^{commit}" 2>/dev/null; then
debug "Commit $commit not found after fetching from $remote; skipping"
continue
fi
execute git -C "$BUILD_DIR" merge-base --is-ancestor "$commit" HEAD ||
execute git -C "$BUILD_DIR" cherry-pick "$commit"
done
# Merge entire branches
for branch in $BRANCHES; do
url_branch="$branch"
branch=""
url="$url_branch"
if [[ "$url_branch" == *"@"* ]]; then
url="${url_branch%@*}"
branch="${url_branch#*@}"
fi
remote="${url%.git}"
remote="${remote##*/}"
remote=${remote//[^A-Za-z0-9._-]/_}
[[ -z $remote ]] && remote="merge"
if ! git -C "$BUILD_DIR" remote | grep -q "^$remote$"; then
execute git -C "$BUILD_DIR" remote add "$remote" "$url"
else
execute git -C "$BUILD_DIR" remote set-url "$remote" "$url"
fi
if [[ -n $branch ]]; then
execute git -C "$BUILD_DIR" fetch "$remote" "$branch"
echo "Merging $remote/$branch into $(git -C "$BUILD_DIR" rev-parse --abbrev-ref HEAD)"
execute git -C "$BUILD_DIR" merge --allow-unrelated-histories -m "Merge $remote/$branch" "$remote/$branch" || \
{ debug "Merge conflict or failed for $remote/$branch"; return 1; }
else
debug "Cannot merge: no branch specified in entry '$branch'"
continue
fi
done
# Print commit info # Print commit info
commit=$(git -C "$BUILD_DIR" rev-parse HEAD) commit=$(git -C "$BUILD_DIR" rev-parse HEAD)
description=$(git -C "$BUILD_DIR" describe --always --dirty) description=$(git -C "$BUILD_DIR" describe)
echo "Current commit hash: $commit" echo "Current commit hash: $commit"
echo "Git worktree description: $description" echo "Git worktree description: $description"
@@ -656,72 +550,86 @@ from_source() {
# Begin OpenWRT build process # Begin OpenWRT build process
((DEBUG)) && make_opts+=("V=sc") ((DEBUG)) && make_opts+=("V=sc")
# Cleanup build environment: heavy clean only when --reset was used earlier # Cleanup build environment
execute make "${make_opts[@]}" "-j1" distclean
# make clean # compiled output # make clean # compiled output
# make targetclean # compiled output, toolchain # make targetclean # compiled output, toolchain
# make dirclean # compiled output, toolchain, build tools # make dirclean # compiled output, toolchain, build tools
# make distclean # compiled output, toolchain, build tools, .config, feeds, .ccache # make distclean # compiled output, toolchain, build tools, .config, feeds, .ccache
if [[ -n $CLEAN ]]; then
execute make "${make_opts[@]}" "-j1" "$CLEAN"
else
debug "Skipping cleanup step"
fi
# Use a custom (faster) mirror # Use a custom (faster) mirror
execute sed -i -E 's;git.openwrt.org/(feed|project);github.com/openwrt;' feeds.conf.default # execute sed -i -E 's;git.openwrt.org/(feed|project);github.com/openwrt;' feeds.conf.default
# Update package feed # Update package feed
./scripts/feeds update -a -f && ./scripts/feeds update -a -f &&
./scripts/feeds install -a -f ./scripts/feeds install -a -f
# Apply custom files overlay for source builds. # Grab the release seed config
execute rm -rf "$BUILD_DIR/files" if ! execute "$DL_TOOL" "-o" "$seed_file" "$seed_url"; then
if [[ -d "$FILES_DIR" ]]; then echo "Could not obtain $seed_file from $seed_url"
execute mkdir -p "$BUILD_DIR/files" return 1
execute rsync -a "$FILES_DIR/" "$BUILD_DIR/files/"
fi fi
# Set compilation output dir
config_opts+=("CONFIG_BINARY_FOLDER=\"$BIN_DIR\"")
# Add custom packages # Add custom packages
for pkg in $PACKAGES; do for pkg in $PACKAGES; do
if [[ $pkg == -* ]]; then if [[ $pkg == -* ]]; then
kconfigs+=("CONFIG_PACKAGE_${pkg#-}=n") # remove package config_opts+=("CONFIG_PACKAGE_${pkg#-}=n") # remove package
else else
kconfigs+=("CONFIG_PACKAGE_$pkg=y") # add package config_opts+=("CONFIG_PACKAGE_$pkg=y") # add package
fi fi
done done
# Add profile kconfig options # Add config options from profile
# $KCONFIGS is a scalar, use a loop to split and avoid SC2068 for config in ${P_ARR[config]}; do
for kconfig in $KCONFIGS; do config_opts+=("$config")
kconfigs+=("$kconfig")
done done
# Reset and write options to config seed file # Only compile selected fs
[[ -f $seed_file ]] && execute rm -f "$seed_file" execute sed -i '/CONFIG_TARGET_ROOTFS_/d' "$seed_file"
for kconfig in "${kconfigs[@]}"; do config_opts+=("CONFIG_TARGET_PER_DEVICE_ROOTFS=n")
debug "Writing $kconfig to $seed_file" if [[ $FILESYSTEM == "squashfs" ]]; then
echo "$kconfig" >> "$seed_file" config_opts+=("CONFIG_TARGET_ROOTFS_EXT4FS=n")
config_opts+=("CONFIG_TARGET_ROOTFS_SQUASHFS=y")
elif [[ $FILESYSTEM == "ext4" ]]; then
config_opts+=("CONFIG_TARGET_ROOTFS_SQUASHFS=n")
config_opts+=("CONFIG_TARGET_ROOTFS_EXT4FS=y")
fi
# Only compile selected target image
execute sed -i '/CONFIG_TARGET_DEVICE_/d' "$seed_file"
config_opts+=("CONFIG_TARGET_MULTI_PROFILE=n")
config_opts+=("CONFIG_TARGET_PROFILE=DEVICE_$DEVICE")
config_opts+=("CONFIG_TARGET_${TARGET//\//_}_DEVICE_$DEVICE=y")
config_opts+=("CONFIG_SDK=n")
config_opts+=("CONFIG_SDK_LLVM_BPF=n")
config_opts+=("CONFIG_IB=n")
config_opts+=("CONFIG_MAKE_TOOLCHAIN=n")
# Write options to config seed file
for config in "${config_opts[@]}"; do
debug "Writing $config to $seed_file"
echo "$config" >> "$seed_file"
done done
# Expand seed into full config # Serial make prep is more reliable
execute make "${make_opts[@]}" "-j1" defconfig execute make "${make_opts[@]}" "-j1" defconfig
# Run serial make download for better reliability
execute make "${make_opts[@]}" "-j1" download execute make "${make_opts[@]}" "-j1" download
# (Optional) Disable multicore make world # make_opts+=("-j$(($(nproc)-1))")
# ((DEBUG)) && make_opts+=("-j1") || make_opts+=("-j$JOBS)") ((DEBUG)) && make_opts+=("-j1") || make_opts+=("-j$(($(nproc)-1))")
make_opts+=("-j$JOBS")
# Make image # Make image
if ! execute ionice -c2 -n7 nice -n19 make "${make_opts[@]}" BIN_DIR="$BIN_DIR" world; then if ! execute ionice -c 3 chrt --idle 0 nice -n19 make "${make_opts[@]}" world; then
echo "Error: make failed" echo "Error: make failed"
return 1 return 1
fi fi
execute popd || return 1 execute popd || return 1
# Symlink output images to root of BIN_DIR (match Image Builder behavior) # Symlink output images to root of BIN_DIR (match Image Builder)
shopt -s nullglob shopt -s nullglob
for image in "$BIN_DIR/targets/${TARGET}/"*.{img,img.gz,ubi}; do for image in "$BIN_DIR/targets/${TARGET}/"*.{img,img.gz,ubi}; do
execute ln -fs "$image" "$BIN_DIR/${image##*/}" execute ln -fs "$image" "$BIN_DIR/${image##*/}"
@@ -731,6 +639,32 @@ from_source() {
return 0 return 0
} }
# @description Backs up a file to a chosen directory using its timestamp
# @arg $1 string File to backup
# @arg $2 string Directory to backup to
backup() {
debug "${FUNCNAME[0]}" "$*"
local file="$1" dir="$2"
local creation_date base_name backup_file
[[ -f $file ]] || return 1
[[ -d $dir ]] || execute mkdir -p "$dir" || { debug "Failed to create directory: $dir"; return 1; }
if creation_date=$(stat -c %w "$file" 2>/dev/null || stat -c %y "$file" 2>/dev/null) && \
[[ $creation_date != "-" && -n $creation_date ]] && \
creation_date=$(date -d "$creation_date" +%y%m%d%H%M 2>/dev/null); then
debug "Creation date: $creation_date"
else
creation_date="unknown"
debug "Unable to determine creation date, using 'unknown'"
fi
base_name="${file##*/}"
backup_file="$dir/$creation_date-$base_name"
[[ -f $backup_file ]] || execute cp --archive "$file" "$backup_file"
}
# @section Helper functions # @section Helper functions
# @internal # @internal
debug() { ((DEBUG)) && echo "Debug: $*"; } debug() { ((DEBUG)) && echo "Debug: $*"; }
@@ -781,6 +715,7 @@ main() {
# Fallback to SCRIPT_DIR if BUILD_ROOT has not been set # Fallback to SCRIPT_DIR if BUILD_ROOT has not been set
declare -g BUILD_ROOT="${BUILD_ROOT:=$SCRIPT_DIR}" declare -g BUILD_ROOT="${BUILD_ROOT:=$SCRIPT_DIR}"
declare -g FILES_DIR="${FILES_DIR:=$BUILD_ROOT/src/files}"
declare -g BACKUP_DIR="$SCRIPT_DIR/backups" declare -g BACKUP_DIR="$SCRIPT_DIR/backups"
# This could be dangerous # This could be dangerous
@@ -804,101 +739,73 @@ main() {
# Remove dependency lock files for --depends # Remove dependency lock files for --depends
if ((FORCE_DEPENDS)); then if ((FORCE_DEPENDS)); then
[[ -f "$BUILD_ROOT/.dependencies_source.lock" ]] && rm -f "$BUILD_ROOT/.dependencies_source.lock" [[ -f "$BUILD_ROOT/.dependencies_source.lock" ]] && rm -f "$BUILD_ROOT/.dependencies_source.lock"
[[ -f "$BUILD_ROOT/.dependencies_imagebuilder.lock" ]] && rm -f "$BUILD_ROOT/.dependencies_imagebuilder.lock" [[ -f "$BUILD_ROOT/.dependencies_ib.lock" ]] && rm -f "$BUILD_ROOT/.dependencies_ib.lock"
fi fi
# Run selected profiles # Run selected profiles
for PROFILE in "${PROFILES[@]}"; do for profile in "${PROFILES[@]}"; do
debug "Running profile: $PROFILE" debug "Running profile: $profile"
if [[ ! ${!PROFILE@a} = A ]]; then if [[ ! ${!profile@a} = A ]]; then
echo "Profile '$PROFILE' does not exist" echo "Profile '$profile' does not exist"
return 1 return 1
fi fi
# Store profile in P_ARR nameref and set global profile vars # Store profile in P_ARR nameref
local -n P_ARR="$PROFILE" local -n P_ARR="$profile"
declare -g REPO="${P_ARR[repo]:-}" local mode="${P_ARR[mode]:="imagebuilder"}"
((FROM_SOURCE)) && mode="source" # allow cli override
install_dependencies "$mode"
local repo="${P_ARR[repo]:-}"
declare -g FILESYSTEM="${P_ARR[filesystem]:="squashfs"}" declare -g FILESYSTEM="${P_ARR[filesystem]:="squashfs"}"
declare -g TARGET="${P_ARR[target]}" declare -g TARGET="${P_ARR[target]}"
declare -g DEVICE="${P_ARR[device]}" declare -g DEVICE="${P_ARR[device]}"
declare -g MODE="${USER_MODE:-${P_ARR[mode]:-imagebuilder}}" declare -g PACKAGES="${P_ARR[packages]:-}"
declare -g CLEAN="${USER_CLEAN:-${P_ARR[clean]:-}}"
declare -g PACKAGES="${P_ARR[packages]:-}" # scalar
declare -g CHERRYPICKS="${P_ARR[cherrypicks]:-}" # scalar
declare -g BRANCHES="${P_ARR[branches]:-}" # scalar
declare -g KCONFIGS="${P_ARR[kconfigs]:-}" # scalar
declare -g FILES_DIR="${P_ARR[files]:-$BUILD_ROOT/src/files}"
if [[ ! -d "$FILES_DIR" ]]; then # pull in USER_RELEASE from args or profile default
if [[ -v P_ARR[files] ]]; then local raw_release="${USER_RELEASE:=${P_ARR[release]:=$RELEASE}}"
echo "Profile '$PROFILE' files directory does not exist: $FILES_DIR"
return 1
fi
execute mkdir -p "$FILES_DIR"
fi
install_dependencies "$MODE" # single call to normalize+ref
read -r release ref < <(normalize_and_ref "$raw_release" "$mode")
# Set number of parallel jobs for make and imagebuilder
declare -gi JOBS
if ((CPUS)); then
JOBS="$CPUS" # user overide (--cpus)
else
JOBS=$(nproc || echo 4) # fallback to quad-core if nproc fails
((JOBS > 1)) && JOBS=$((JOBS - 1)) # leave one CPU free
fi
# Normalize RELEASE and set REF committish
local raw_release="${USER_RELEASE:=${P_ARR[release]:=$DEFAULT_RELEASE}}"
declare -g RELEASE REF
read -r RELEASE REF < <(normalize_and_ref "$raw_release" "$MODE")
declare -g SRC_DIR="$BUILD_ROOT/src/.openwrt" declare -g SRC_DIR="$BUILD_ROOT/src/.openwrt"
declare -g BUILD_DIR="$BUILD_ROOT/src/$PROFILE/$REF-$MODE" declare -g BUILD_DIR="$BUILD_ROOT/src/$profile/$mode-$ref"
declare -g BIN_DIR="$BUILD_ROOT/bin/$PROFILE/$REF-$MODE" declare -g BIN_DIR="$BUILD_ROOT/bin/$profile/$mode-$ref"
if [[ "$RELEASE" == "snapshot" ]]; then if [[ "$release" == "snapshot" ]]; then
local url_prefix="https://downloads.openwrt.org/snapshots/targets/$TARGET" local url_prefix="https://downloads.openwrt.org/snapshots/targets/$TARGET"
local url_filename="openwrt-imagebuilder-${TARGET//\//-}.Linux-x86_64.tar.zst" local url_filename="openwrt-imagebuilder-${TARGET//\//-}.Linux-x86_64.tar.zst"
local img_fname="openwrt-${TARGET//\//-}-$DEVICE-$FILESYSTEM" local img_fname="openwrt-${TARGET//\//-}-$DEVICE-$FILESYSTEM"
else else
local url_prefix="https://downloads.openwrt.org/releases/$RELEASE/targets/$TARGET" local url_prefix="https://downloads.openwrt.org/releases/$release/targets/$TARGET"
local url_filename="openwrt-imagebuilder-$RELEASE-${TARGET//\//-}.Linux-x86_64.tar.zst" local url_filename="openwrt-imagebuilder-$release-${TARGET//\//-}.Linux-x86_64.tar.zst"
local img_fname="openwrt-$RELEASE-${TARGET//\//-}-$DEVICE-$FILESYSTEM" local img_fname="openwrt-$release-${TARGET//\//-}-$DEVICE-$FILESYSTEM"
fi fi
local imagebuilder_url="$url_prefix/$url_filename" local ib_url="$url_prefix/$url_filename"
local imagebuilder_file="$BUILD_DIR/$url_filename" local ib_file="$BUILD_DIR/$url_filename"
local imagebuilder_sha256_url="$url_prefix/sha256sums" local ib_sha256_url="$url_prefix/sha256sums"
local imagebuilder_sha256_file="$BUILD_DIR/sha256sums" local ib_sha256_file="$BUILD_DIR/sha256sums"
local seed_url="$url_prefix/config.buildinfo"
if [[ "$MODE" == "source" ]]; then if [[ "$mode" == "source" ]]; then
declare -g SYSUPGRADEIMGGZ="$BIN_DIR/targets/$TARGET/$img_fname-sysupgrade.img.gz" declare -g SYSUPGRADEIMGGZ="$BIN_DIR/targets/$TARGET/$img_fname-sysupgrade.img.gz"
else else
declare -g SYSUPGRADEIMGGZ="$BUILD_DIR/$img_fname-sysupgrade.img.gz" declare -g SYSUPGRADEIMGGZ="$BUILD_DIR/$img_fname-sysupgrade.img.gz"
fi fi
# Backup existing output directory backup "$SYSUPGRADEIMGGZ" "$BACKUP_DIR/$profile/$mode-$ref"
if [[ -d "$BIN_DIR" ]]; then
local timestamp
timestamp=$(date +%y%m%d%H%M)
execute mkdir -p "$BACKUP_DIR/$PROFILE/$REF-$MODE-$timestamp"
execute rsync -a --delete --exclude 'packages/' "$BIN_DIR/" "$BACKUP_DIR/$PROFILE/$REF-$MODE-$timestamp/"
fi
if [[ "$MODE" == "source" ]]; then if [[ "$mode" == "source" ]]; then
from_source || return $? from_source "$seed_url" "$profile" "$ref" || return $?
elif [[ "$MODE" == "imagebuilder" ]]; then elif [[ "$mode" == "imagebuilder" ]]; then
[[ -d $BUILD_DIR ]] || mkdir -p "$BUILD_DIR" [[ -d $BUILD_DIR ]] || mkdir -p "$BUILD_DIR"
get_imagebuilder "$imagebuilder_url" "$imagebuilder_file" "$imagebuilder_sha256_url" "$imagebuilder_sha256_file" && get_imagebuilder "$ib_url" "$ib_file" "$ib_sha256_url" "$ib_sha256_file" &&
verify "$imagebuilder_file" "$imagebuilder_sha256_file" && verify "$ib_file" "$ib_sha256_file" &&
extract "$imagebuilder_file" "$BUILD_DIR" || return $? extract "$ib_file" "$BUILD_DIR" || return $?
if [[ -v $repo ]]; then
# Add external repositories for the Image Builder build if ! grep -q "$repo" "$BUILD_DIR/repositories.conf"; then
if [[ -n $REPO ]]; then echo "$repo" >> "$BUILD_DIR/repositories.conf"
if ! grep -q "$REPO" "$BUILD_DIR/repositories.conf"; then
echo "$REPO" >> "$BUILD_DIR/repositories.conf"
fi fi
sed -i '/option check_signature/d' "$BUILD_DIR/repositories.conf" sed -i '/option check_signature/d' "$BUILD_DIR/repositories.conf"
fi fi
@@ -909,7 +816,7 @@ main() {
local -a outfiles=("$BIN_DIR"/*.img.gz "$BIN_DIR"/*.img) local -a outfiles=("$BIN_DIR"/*.img.gz "$BIN_DIR"/*.img)
shopt -u nullglob shopt -u nullglob
for outfile in "${outfiles[@]}"; do for outfile in "${outfiles[@]}"; do
verify "$outfile" "$imagebuilder_sha256_file" || return 1 verify "$outfile" "$ib_sha256_file" || return 1
done done
fi fi
#copyFiles #copyFiles
@@ -921,9 +828,5 @@ main() {
done done
} }
# Roughly turn debugging on for pre-init
# Reset and reparse in parse_input() with getopt
[[ " $* " =~ ( --debug | -d ) ]] && DEBUG=1
main "$@" main "$@"
exit exit

112
profiles
View File

@@ -1,20 +1,12 @@
#!/usr/bin/env bash #!/usr/bin/env bash
# Device profiles for openwrtbuilder
# shellcheck disable=SC2034 # shellcheck disable=SC2034
# Device profiles for openwrtbuilder
DEFAULT_RELEASE="25.12.3" # overrides default release in openwrtbuilder # Default packages
default_packages="luci luci-ssl luci-proto-wireguard luci-app-statistics \
# Default packages (precede with "-" to exclude) collectd-mod-sensors collectd-mod-thermal collectd-mod-conntrack \
default_packages=( collectd-mod-cpu nano htop diffutils tar iperf3 zsh rsync \
ca-bundle nano vim htop diffutils tar iperf3 zsh rsync tcpdump ethtool openssh-sftp-server"
openssh-sftp-server
luci luci-ssl luci-proto-wireguard luci-app-statistics luci-app-filemanager
collectd-mod-sensors collectd-mod-thermal collectd-mod-conntrack collectd-mod-cpu
)
# Default kernel configs
default_kconfigs=(
)
# Current devices # Current devices
declare -Ag r4s=( declare -Ag r4s=(
@@ -22,102 +14,54 @@ declare -Ag r4s=(
[device]="friendlyarm_nanopi-r4s" [device]="friendlyarm_nanopi-r4s"
[target]="rockchip/armv8" [target]="rockchip/armv8"
[filesystem]="ext4" [filesystem]="ext4"
[packages]="${default_packages[*]} \ [packages]="$default_packages luci-app-ddns luci-app-sqm irqbalance \
adblock luci-app-adblock \
luci-app-sqm \
collectd-mod-df usbutils kmod-usb-storage kmod-usb-storage-uas \ collectd-mod-df usbutils kmod-usb-storage kmod-usb-storage-uas \
kmod-fs-btrfs btrfs-progs block-mount smcroute avahi-daemon \ kmod-fs-btrfs btrfs-progs block-mount smcroute avahi-daemon \
ethtool ca-bundle tailscale" curl ethtool ca-bundle tailscale"
[kconfigs]="${default_kconfigs[*]} \ [config]="CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y \
CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=32 \ CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=32 \
CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y" CONFIG_BUILDBOT=n"
# For 24.10 branch (Linux 6.6) [files]="/mnt/backup"
# [cherrypicks]="https://github.com/wurzerj/openwrt.git:59d6e31 \
# https://github.com/wurzerj/openwrt.git:bb251b8" # fix inconsistent reboot
) )
declare -Ag ax6000=( declare -Ag ax6000=(
[mode]="imagebuilder" [mode]="imagebuilder"
[device]="xiaomi_redmi-router-ax6000-stock" [device]="xiaomi_redmi-router-ax6000-stock"
[target]="mediatek/filogic" [target]="mediatek/filogic"
[release]="snapshot"
[filesystem]="squashfs" [filesystem]="squashfs"
[packages]="${default_packages[*]} \ [packages]="$default_packages -dnsmasq -odhcpd-ipv6only -nftables -firewall4 tailscale"
tailscale"
) )
declare -Ag ax6000_uboot_ap=( declare -Ag ax6000_uboot=(
[mode]="imagebuilder" [mode]="imagebuilder"
[device]="xiaomi_redmi-router-ax6000-ubootmod" [device]="xiaomi_redmi-router-ax6000-ubootmod"
[target]="mediatek/filogic" [target]="mediatek/filogic"
[release]="snapshot" [release]="snapshot"
[filesystem]="squashfs" [filesystem]="squashfs"
[packages]="${default_packages[*]} \ [packages]="$default_packages -dnsmasq -odhcpd-ipv6only -nftables -firewall4"
-dnsmasq -odhcpd-ipv6only -nftables -firewall4"
) )
declare -Ag n5100=( declare -Ag n5100=(
[device]="generic" [device]="generic"
[target]="x86/64" [target]="x86/64"
[filesystem]="squashfs" [filesystem]="squashfs"
[packages]="${default_packages[*]} \ [packages]="$default_packages luci-app-ddns irqbalance collectd-mod-df \
luci-app-ddns irqbalance collectd-mod-df \
usbutils kmod-usb-storage kmod-usb-storage-uas kmod-fs-btrfs \ usbutils kmod-usb-storage kmod-usb-storage-uas kmod-fs-btrfs \
btrfs-progs block-mount cryptsetup kmod-crypto-xts smcroute \ btrfs-progs block-mount cryptsetup kmod-crypto-xts smcroute \
avahi-daemon ethtool ca-bundle smartmontools intel-microcode \ avahi-daemon curl ethtool ca-bundle smartmontools intel-microcode \
lm-sensors samba4-server luci-app-samba4 tailscale shadow-useradd" lm-sensors samba4-server luci-app-samba4 tailscale shadow-useradd"
[kconfigs]="${default_kconfigs[*]} \ [config]="CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y \
CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y \
CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=32" CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=32"
) # [files]="/mnt/backup"
declare -Ag w1700k=(
[mode]="source"
[device]="gemtek_w1700k"
[target]="airoha/an7581"
[filesystem]="squashfs"
[release]="snapshot"
[packages]="${default_packages[*]} \
luci-app-sqm \
smcroute avahi-daemon \
lm-sensors samba4-server luci-app-samba4 shadow-useradd \
ca-bundle tailscale"
# [cherrypicks]="\
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:8d449e968cfaa774ab7a219b3a5ab4251b2f9352 \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:3033241393ef6eb562539c6a3ccb9d3cf1a25d05 \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:79a21e0986a9efe6de3a07394a71ac15a2107b16 \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:2f8a1cbf901df0d325dfe112fdfe8013a72c8305 \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:71b09bc5852797cdbf7cb3b56a7d8fcd9d4ca9db \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:fe0135f0b7037a9cc1985d5937dd24cb99bfccb1 \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:cdb937180fb971fe702078f0e0fef63f2fcce337 \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:6dc847c802b9dc597fc2c64711ca85499f128d1d \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:b6e6cf911915dd987eecde908a2013419565cff4 \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:708089948949e66f5234249fc631e0453b58942e \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:9841a707a577385498591bcfb56b836176325c2f \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:8446ec6431a3247683a27070d3c69f2789b52c70 \
# https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:05380e2ef5fb96c171da23453ba32aa349a4b126"
# [branches]="https://github.com/OpenWRT-fanboy/OpenW1700k.git@minimal"
)
declare -Ag w1700k_ap=(
[mode]="source"
[device]="gemtek_w1700k"
[target]="airoha/an7581"
[filesystem]="squashfs"
[release]="snapshot"
[packages]="${default_packages[*]} \
-dnsmasq -odhcpd-ipv6only -nftables -firewall4 \
wpad-openssl libiwinfo-data tailscale bridger switch smp_util \
kmod-crypto-hw-eip93"
# [branches]="https://github.com/OpenWRT-fanboy/OpenW1700k.git@minimal"
) )
declare -Ag rpi4=( declare -Ag rpi4=(
[device]="rpi-4" [device]="rpi-4"
[target]="bcm27xx/bcm2711" [target]="bcm27xx/bcm2711"
[filesystem]="ext4" [filesystem]="ext4"
[packages]="${default_packages[*]} \ [packages]="$default_packages kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8152 \
luci-app-upnp luci-app-pbr -dnsmasq dnsmasq-full luci-app-ddns luci-app-sqm \ luci-app-upnp luci-app-pbr -dnsmasq dnsmasq-full luci-app-ddns luci-app-sqm"
kmod-usb-net-asix-ax88179 kmod-usb-net-rtl8152"
) )
declare -Ag r4s_stock=( declare -Ag r4s_stock=(
@@ -131,8 +75,7 @@ declare -Ag totolink=(
[device]="totolink_x5000r" [device]="totolink_x5000r"
[target]="ramips/mt7621" [target]="ramips/mt7621"
[filesystem]="squashfs" [filesystem]="squashfs"
[packages]="${default_packages[*]} \ [packages]="$default_packages -dnsmasq -odhcpd-ipv6only -nftables -firewall4 \
-dnsmasq -odhcpd-ipv6only -nftables -firewall4 \
-kmod-nft-offload collectd-mod-iwinfo" -kmod-nft-offload collectd-mod-iwinfo"
) )
@@ -140,7 +83,7 @@ declare -Ag archer=(
[device]="tplink_archer-c7-v2" [device]="tplink_archer-c7-v2"
[target]="ath79/generic" [target]="ath79/generic"
[filesystem]="squashfs" [filesystem]="squashfs"
[packages]="${default_packages[*]} -dnsmasq -odhcpd -iptables \ [packages]="$default_packages -dnsmasq -odhcpd -iptables \
-ath10k-firmware-qca988x-ct ath10k-firmware-qca988x-ct-full-htt" -ath10k-firmware-qca988x-ct ath10k-firmware-qca988x-ct-full-htt"
) )
@@ -148,16 +91,14 @@ declare -Ag linksys=(
[device]="linksys_ea8300" [device]="linksys_ea8300"
[target]="ipq40xx/generic" [target]="ipq40xx/generic"
[filesystem]="squashfs" [filesystem]="squashfs"
[packages]="${default_packages[*]} \ [packages]="$default_packages -dnsmasq -odhcpd -iptables"
-dnsmasq -odhcpd -iptables"
) )
declare -Ag r2s=( declare -Ag r2s=(
[device]="friendlyarm_nanopi-r2s" [device]="friendlyarm_nanopi-r2s"
[target]="rockchip/armv8" [target]="rockchip/armv8"
[filesystem]="ext4" [filesystem]="ext4"
[packages]="${default_packages[*]} \ [packages]="$default_packages luci-app-upnp luci-app-pbr -dnsmasq dnsmasq-full \
luci-app-upnp luci-app-pbr -dnsmasq dnsmasq-full \
luci-app-ddns luci-app-sqm luci-app-statistics collectd-mod-sensors \ luci-app-ddns luci-app-sqm luci-app-statistics collectd-mod-sensors \
collectd-mod-thermal collectd-mod-conntrack smcroute curl ethtool" collectd-mod-thermal collectd-mod-conntrack smcroute curl ethtool"
) )
@@ -166,8 +107,7 @@ declare -Ag r2s_tr=(
[device]="friendlyarm_nanopi-r2s" [device]="friendlyarm_nanopi-r2s"
[target]="rockchip/armv8" [target]="rockchip/armv8"
[filesystem]="ext4" [filesystem]="ext4"
[packages]="${default_packages[*]} \ [packages]="$default_packages luci-app-upnp luci-app-pbr luci-app-ddns \
luci-app-upnp luci-app-pbr luci-app-ddns \
luci-app-statistics collectd-mod-sensors collectd-mod-thermal \ luci-app-statistics collectd-mod-sensors collectd-mod-thermal \
collectd-mod-conntrack curl ethtool travelmate" collectd-mod-conntrack curl ethtool travelmate"
) )