Compare commits

...

87 Commits

Author SHA1 Message Date
5c64e19ef5 Update w1700k cherrypicks 2025-12-19 18:25:07 -05:00
16e401789a Add support for nonstandard cherrypicks 2025-12-19 12:45:41 -05:00
f3831e097d Default w1700k to source 2025-12-19 11:31:24 -05:00
13c7fbd87e Default w1700k to imagebuilder 2025-12-19 11:30:44 -05:00
cfab86865d Add w1700k profile 2025-12-19 11:20:40 -05:00
5b9f1f2f39 Re-add specific device config 2025-10-23 16:46:16 -04:00
c5bfc7907b Remove specific device config 2025-10-23 16:43:34 -04:00
533b0b5ffc Re-add specific device config 2025-10-23 16:34:37 -04:00
eba54804d3 Blank the seed file 2025-10-23 16:31:34 -04:00
09b62923a8 Re-add specific device config 2025-10-23 16:19:58 -04:00
960755e6a2 Use faster feeds mirror 2025-10-22 21:16:41 -04:00
0fa9b0d85a Streamling config options 2025-10-22 21:02:36 -04:00
4de18e6696 Add optional build clean arg to --source 2025-10-22 20:55:20 -04:00
3772d373bb Tune resource limits 2025-10-22 20:27:21 -04:00
b75597946d Improve worktree detection 2025-10-22 19:35:38 -04:00
018a91e216 Introduce reusable worktrees 2025-10-22 19:31:58 -04:00
0c61a27b06 Reorganize from_source() 2025-10-22 19:25:59 -04:00
675ed5eb39 Abandon upstream seed, untenable 2025-10-22 19:11:51 -04:00
94f60e30b1 Pass BIN_DIR to make and not .config 2025-10-22 15:46:06 -04:00
e8ccb76cc6 Remove more default buildbot configs 2025-10-21 23:58:35 -04:00
4274f876a7 Remove more default buildbot configs 2025-10-21 20:40:19 -04:00
4760c84bff Remove more default buildbot configs 2025-10-21 20:35:38 -04:00
20b3f7f4ec Strip CONFIG_ALL_KMODS 2025-10-21 10:45:18 -04:00
f178e39a28 Use CONFIG_ALL_KMODS=n in global profile 2025-10-20 16:31:48 -04:00
c7b954252d Fetch worktree branch instead of pull 2025-10-19 15:21:53 -04:00
18929109a2 Omit oldconfig step 2025-10-18 21:17:35 -04:00
8d24cb96a9 Switch to canonical make order 2025-10-18 12:27:40 -04:00
9be43af11a Make olddefconfig non-interactive 2025-10-18 11:33:04 -04:00
ce2e85d197 Attempt one step olddefconfig 2025-10-18 11:30:42 -04:00
aeead798c3 Test explicit branch 2025-09-23 16:12:57 -04:00
72355bb65a Use fetch --all to grab wt breanches 2025-09-23 15:37:13 -04:00
3053b24063 Update default release 2025-09-23 15:13:35 -04:00
186fe21d73 Update profiles 2025-09-10 19:29:56 -04:00
d63a909d54 Simplify script dir ID 2025-09-09 16:57:22 -04:00
9128c453f3 Move pfring exclusions to r4s 2025-08-19 16:54:27 -04:00
ffbd193b79 Clarify skipping lock files for --debug 2025-08-19 16:38:03 -04:00
5259c72de4 Exclude pfring kmods 2025-08-18 07:43:09 -04:00
045f43b51f Exclude more pfring packages 2025-08-15 16:53:59 -04:00
89cc3cddeb Exclude problematic packages 2025-08-13 17:34:37 -04:00
cd7449dd7c Re-disable multicore make 2025-08-11 17:44:04 -04:00
2b35e1e017 Re-enable multicore make 2025-08-11 17:10:20 -04:00
983f9ecb04 Exclude libpfring to fix compilation 2025-08-11 15:50:20 -04:00
b5f567ce2b Attempt to mix yes and execute() 2025-08-09 00:01:34 -04:00
a16e713895 Use canonincal method for now 2025-08-08 23:56:28 -04:00
70d24d7fae Replace defconfig with oldconfig 2025-08-08 22:33:30 -04:00
d5069d4c40 Add golang dependency 2025-08-08 22:24:39 -04:00
718b29cfe8 Try to omit oldconfig 2025-08-08 22:22:35 -04:00
e3ce0b6e57 Make oldconfig to prevent upstream clobbers 2025-08-08 20:50:07 -04:00
3ba76a4e8d Add early debugging 2025-08-08 19:48:53 -04:00
4f1f145a10 Fix comments 2025-08-08 14:33:50 -04:00
2123205ca0 Reformat profiles 2025-08-08 14:30:31 -04:00
e510f8ccb6 Don't build unecessary kmods 2025-08-08 14:20:50 -04:00
da398172e8 Workaround libpfring issue #26569 2025-08-06 21:10:36 -04:00
12067ac09b Disable cherrypicks by default since branch-specific 2025-08-06 21:06:25 -04:00
cf2c35b114 Specify fork with cherrypick 2025-08-06 21:01:08 -04:00
5629472aa3 Support cherrypicks 2025-08-06 20:55:59 -04:00
a7a85ee67a Use --detached worktrees 2025-08-05 14:14:16 -04:00
4890aa192d Cleanup some comments 2025-07-29 17:40:02 -04:00
819ff0add0 Update README 2025-07-29 02:13:55 -04:00
149da1be87 Update README 2025-07-29 02:12:03 -04:00
6f1bc4dd00 SHow more commit info 2025-07-29 02:01:52 -04:00
5d434f031d Remove extraneous normalize_and_ref output 2025-07-29 01:58:37 -04:00
25b5623a65 Add temp debug 2025-07-29 01:56:19 -04:00
20477c21ab Add temp debug 2025-07-29 01:54:34 -04:00
8ed85fff2b Add temp debug 2025-07-29 01:52:51 -04:00
ab8f58ca92 Add temp debug 2025-07-29 01:52:36 -04:00
20e11b7419 Add temp debug 2025-07-29 01:49:03 -04:00
11c28c7ab3 Add temp debug 2025-07-29 01:47:28 -04:00
908664b185 Resimplify worktrees 2025-07-29 01:43:53 -04:00
40ce9940ae Debug commit print 2025-07-29 01:15:10 -04:00
64ffeeca17 Fix git object 2025-07-29 01:06:01 -04:00
0106ac7eff Use full name for branch ref 2025-07-29 00:44:49 -04:00
86f5bf7e3f Skip fetch 2025-07-29 00:32:38 -04:00
a18d467c4f Hacky way to show latest commit 2025-07-29 00:25:06 -04:00
3a659b4798 Fix clashing worktrees 2025-07-29 00:05:26 -04:00
7f996e7724 Silence commond debug warning 2025-07-28 23:51:44 -04:00
3688539a90 Return early and add debug output for dependencies 2025-07-28 23:48:14 -04:00
c28d7683d8 Make BUILD_DIR worktree_dir 2025-07-28 23:44:19 -04:00
a5b559c59c Fix parsing in normalize_and_ref() 2025-07-28 23:29:46 -04:00
d22d21148c Implement per-profile modes 2025-07-28 23:24:16 -04:00
2b4dac7ef3 Hide openwrt src dir 2025-07-28 21:38:09 -04:00
498f8a7333 Use a global release object 2025-07-28 21:36:01 -04:00
d28f2e8c31 Only fetch if not checked out 2025-07-28 19:03:17 -04:00
ca3f1e82ed Use git fetch for branches 2025-07-28 19:00:44 -04:00
4b66de068b Refactor worktree code 2025-07-28 18:31:20 -04:00
1e88f1b912 Revert to serial debug 2025-07-28 17:45:51 -04:00
cbe7e0468d Use multicore debug 2025-07-28 01:02:49 -04:00
4 changed files with 442 additions and 323 deletions

1
.gitignore vendored
View File

@@ -1,6 +1,7 @@
src/
bin/
.vscode/
*.code-workspace
backups/
.dependencies_source
.dependencies_ib

View File

@@ -1,6 +1,6 @@
# openwrtbuilder
Build and deploy OpenWRT images using convenient profiles.
Build and deploy OpenWRT images using shell-style device profiles, via source code or the official Image Builder.
## Usage
@@ -13,9 +13,9 @@ Build and deploy OpenWRT images using convenient profiles.
--release,-r,--version,-v RELEASE ("snapshot", "22.03.3")
--buildroot,-b PATH (Default: script directory)
--source
Build image from source, not from Image Builder
Allows make config options to be passed in profile
Uses git worktree for multi-profile deduplication
Build image from source code, not from Image Builder.
Allows make config options to be passed in profile.
Uses git worktree for multi-profile deduplication.
--ssh-upgrade HOST
Example: root@192.168.1.1
--ssh-backup SSH_PATH
@@ -27,7 +27,6 @@ Build and deploy OpenWRT images using convenient profiles.
Can be combined with -p to reset a specific profile
--depends
Force dependency installation
Ignores .dependencies files
--yes,-y
Assume yes for all questions (automatic mode)
--debug,-d
@@ -36,10 +35,13 @@ Build and deploy OpenWRT images using convenient profiles.
## Profiles
See `profiles` for example device profile definitions.
See `profiles` for example device profile definitions. Multiple `--profile` can be passed at once.
The default build mode is `imagebuilder` unless `--source` is passed. Default profile modes can be set individually in `profiles`.
## Examples
* `openwrtbuilder -p r4s -p ax6000`
* `openwrtbuilder -p r4s -r snapshot --debug`
* `openwrtbuilder -p ax6000 -r 23.05.5 --source --debug`
* `openwrtbuilder -p rpi4 -r 23.05.5 --flash /dev/sdX`
@@ -47,7 +49,7 @@ See `profiles` for example device profile definitions.
## Additional Info
Did you find `openwrtbuilder` useful? [Buy me a coffee!](https://paypal.me/bryanroessler)
Find `openwrtbuilder` useful? [Paypal me a coffee!](https://paypal.me/bryanroessler)
[↓ ↓ ↓ Bitcoin ↓ ↓ ↓](bitcoin:bc1q7wy0kszjavgcrvkxdg7mf3s6rh506rasnhfa4a)

View File

@@ -1,11 +1,11 @@
#!/usr/bin/env bash
# Builds and deploys OpenWRT images
# Build and deploy OpenWRT images using shell-style device profiles, via source code or the official Image Builder.
# Copyright 2022-25 Bryan C. Roessler
# Apache 2.0 License
# See README and profiles for device configuration
# See README and ./profiles for device configuration
# Set default release
: "${RELEASE:="24.10.2"}"
: "${RELEASE:="24.10.5"}"
# @internal
print_help() {
@@ -22,18 +22,16 @@ print_help() {
--release,-r,--version,-v RELEASE ("snapshot", "22.03.5")
--buildroot,-b PATH
Default: location of openwrtbuilder script
--source
--source[=CLEAN]
Build image from source, not from Image Builder
Allows make config options to be passed in profile
Uses git worktree for multi-profile deduplication
Optional CLEAN runs the given clean mode before building
(clean|targetclean|dirclean|distclean)
--ssh-upgrade HOST
Examples: root@192.168.1.1, root@router.lan
--ssh-backup SSH_PATH
Enabled by default for --ssh-upgrade
--flash,-f DEVICE
Example: /dev/sdX
--reset
Cleanup all source and output files
--depends
Force dependency installation
--yes,-y
@@ -58,7 +56,7 @@ init() {
# Save the script directory
# https://stackoverflow.com/a/4774063
SCRIPT_DIR="$(cd -- "$(dirname "$0")" >/dev/null 2>&1 || exit $? ; pwd -P)"
SCRIPT_DIR=$(readlink -f "$(dirname "${BASH_SOURCE[0]}")")
if [[ -e "/etc/os-release" ]]; then
source "/etc/os-release"
@@ -127,8 +125,8 @@ parse_input() {
debug "${FUNCNAME[0]}" "$*"
declare -ga PROFILES
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
local long_opts='release:,version:,profile:,buildroot:,source,'
declare -g USER_RELEASE SSH_UPGRADE_PATH SSH_BACKUP_PATH FLASH_DEV SOURCE_CLEAN
local long_opts='release:,version:,profile:,buildroot:,source::,'
long_opts+='ssh-upgrade:,ssh-backup:,flash:,reset,depends,yes,debug,help'
if _input=$(getopt -o +r:v:p:b:sf:ydh -l $long_opts -- "$@"); then
@@ -138,7 +136,12 @@ parse_input() {
--release|-r|--version|-v) shift; USER_RELEASE="$1" ;;
--profile|-p) shift; PROFILES+=("$1") ;;
--buildroot|-b) shift; BUILD_ROOT="$1" ;;
--source|-s) FROM_SOURCE=1 ;;
--source|-s) FROM_SOURCE=1
case "$1" in
-*|"") ;; # if empty
*) SOURCE_CLEAN="$1"; shift ;;
esac
;;
--ssh-upgrade) shift; SSH_UPGRADE_PATH="$1" ;;
--ssh-backup) shift; SSH_BACKUP_PATH="$1" ;;
--flash|-f) shift; FLASH_DEV="$1" ;;
@@ -158,161 +161,214 @@ parse_input() {
}
# @description Install build dependencies on major distros
# @arg $1 string Build mode ("source" or "imagebuilder")
install_dependencies() {
debug "${FUNCNAME[0]}"
local mode="$1"
local -a pkg_list
local lock_file
if ((FROM_SOURCE)); then
lock_file="$BUILD_ROOT/.dependencies_source"
else
lock_file="$BUILD_ROOT/.dependencies_ib"
# Set appropriate lock file based on mode
if [[ "$mode" == "source" ]]; then
lock_file="$BUILD_ROOT/.dependencies_source.lock"
elif [[ "$mode" == "imagebuilder" ]]; then
lock_file="$BUILD_ROOT/.dependencies_ib.lock"
fi
if ((FORCE_DEPENDS)) || [[ ! -f $lock_file ]]; then
if ((FROM_SOURCE)); then
# For building from source code see:
# https://openwrt.org/docs/guide-developer/toolchain/install-buildsystem
case "$ID" in
fedora|centos)
pkg_list+=(
bzip2
clang # for qosify
diffutils
gcc
gcc-c++
git
llvm15-libs # for qosify
make
ncurses-devel
patch
perl
perl-Data-Dumper
perl-File-Compare
perl-File-Copy
perl-FindBin
perl-IPC-Cmd
perl-JSON-PP
perl-Thread-Queue
perl-Time-Piece
perl-base
python3
python3-devel
python3-pyelftools
python3-setuptools
rsync
swig
tar
unzip
wget
which
) ;;
debian|ubuntu)
pkg_list+=(
build-essential
clang
file
flex
g++
gawk
gcc-multilib
gettext
git
liblzma-dev
libncurses5-dev
libssl-dev
python3-distutils
rsync
patch
unzip
wget
zlib1g-dev
) ;;
arch)
pkg_list+=(
autoconf
automake
base-devel
bash
binutils
bison
bzip2
clang
fakeroot
file
findutils
flex
gawk
gcc
gettext
git
grep
groff
gzip
libelf
libtool
libxslt
m4
make
ncurses
net-snmp
openssl
patch
pkgconf
python
rsync
sed
texinfo
time
unzip
util-linux
wget
which
xz
zlib
) ;;
*) debug "Unsupported OS, skipping dependencies"; return 1 ;;
esac
else
# For Imagebuilder
case "$ID" in
fedora|centos)
pkg_list+=(
@c-development
@development-tools
@development-libs
perl-FindBin
zlib-static
elfutils-libelf-devel
gawk
unzip
file
wget
python3
axel
perl-IPC-Cmd
zstd) ;;
debian|ubuntu)
pkg_list+=(
build-essential
libncurses5-dev
libncursesw5-dev
zlib1g-dev
gawk
git
gettext
libssl-dev
xsltproc
wget
unzip
python
axel
zstd) ;;
*) debug "Unsupported OS for automatic dependency install"; return 1 ;;
esac
fi
[[ -f $lock_file ]] && debug "$lock_file lock file exists but skipping for --debug" && return 0
pkg_install "${pkg_list[@]}" && echo "${pkg_list[@]}" > "$lock_file"
if [[ "$mode" == "source" ]]; then
# For building from source code see:
# https://openwrt.org/docs/guide-developer/toolchain/install-buildsystem
case "$ID" in
fedora|centos)
pkg_list+=(
bzip2
clang # for qosify
diffutils
gcc
gcc-c++
git
golang
llvm15-libs # for qosify
make
ncurses-devel
patch
perl
perl-Data-Dumper
perl-File-Compare
perl-File-Copy
perl-FindBin
perl-IPC-Cmd
perl-JSON-PP
perl-Thread-Queue
perl-Time-Piece
perl-base
python3
python3-devel
python3-pyelftools
python3-setuptools
quilt
rsync
swig
tar
unzip
wget
which
) ;;
debian|ubuntu)
pkg_list+=(
build-essential
clang
file
flex
g++
gawk
gcc-multilib
gettext
git
golang
liblzma-dev
libncurses5-dev
libssl-dev
python3-distutils
quilt
rsync
patch
unzip
wget
zlib1g-dev
) ;;
arch)
pkg_list+=(
autoconf
automake
base-devel
bash
binutils
bison
bzip2
clang
fakeroot
file
findutils
flex
gawk
gcc
gettext
git
golang
grep
groff
gzip
libelf
libtool
libxslt
m4
make
ncurses
net-snmp
openssl
patch
pkgconf
python
quilt
rsync
sed
texinfo
time
unzip
util-linux
wget
which
xz
zlib
) ;;
*) debug "Unsupported OS, skipping dependency install"; return 1 ;;
esac
elif [[ "$mode" == "imagebuilder" ]]; then
# For Imagebuilder
case "$ID" in
fedora|centos)
pkg_list+=(
@c-development
@development-tools
@development-libs
perl-FindBin
zlib-static
elfutils-libelf-devel
gawk
unzip
file
wget
python3
axel
perl-IPC-Cmd
zstd) ;;
debian|ubuntu)
pkg_list+=(
build-essential
libncurses5-dev
libncursesw5-dev
zlib1g-dev
gawk
git
gettext
libssl-dev
xsltproc
wget
unzip
python
axel
zstd) ;;
*) debug "Unsupported OS, skipping dependency install"; return 1 ;;
esac
fi
pkg_install "${pkg_list[@]}" && echo "${pkg_list[@]}" > "$lock_file"
}
# @description Normalize release and set worktree reference
# @arg $1 string Raw release input
# @arg $2 string Build mode ("source" or "imagebuilder")
# @returns string Normalized release and reference
normalize_and_ref() {
local input="$1" mode="$2"
local rel ref branch tag
case "$input" in
snapshot|latest|main|master)
rel="snapshot"
ref="main"
;;
v[0-9][0-9].[0-9][0-9].*|[0-9][0-9].[0-9][0-9].*)
# strip optional leading “v”
rel="${input#v}"
if [[ "$mode" == "source" ]]; then
branch="openwrt-${rel%.*}"
tag="v$rel"
if ask_ok "Use branch $branch HEAD (y) or tag $tag (n)?"; then
ref="$branch"
else
ref="$tag"
fi
else
ref="$rel"
fi
;;
*)
if [[ "$mode" == "source" ]]; then
# arbitrary commit-ish allowed
rel="$input"
ref="$input"
else
echo "Error: invalid release '$input'" >&2
exit 1
fi
;;
esac
printf '%s %s' "$rel" "$ref"
}
# @description Acquires the OpenWRT Image Builder
@@ -337,17 +393,6 @@ get_imagebuilder() {
done
}
add_repos() {
debug "${FUNCNAME[0]}"
if [[ -v P_ARR[repo] ]]; then
if ! grep -q "${P_ARR[repo]}" "$BUILD_DIR/repositories.conf"; then
echo "${P_ARR[repo]}" >> "$BUILD_DIR/repositories.conf"
fi
sed -i '/option check_signature/d' "$BUILD_DIR/repositories.conf"
fi
}
ssh_backup() {
debug "${FUNCNAME[0]}"
local date hostname backup_fname
@@ -461,106 +506,135 @@ ssh_upgrade() {
# @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() {
debug "${FUNCNAME[0]}" "$*"
local seed_url="$1"
local profile="$2"
local ref="$3"
local src_url="https://github.com/openwrt/openwrt.git"
local seed_file="$WORKTREE_DIR/.config"
local worktree_name; worktree_name="$(basename "$WORKTREE_DIR")"
local worktree_meta="$SRC_DIR/.git/worktrees/$worktree_name"
local pkg config commit seed_file wt_commit description
local -a make_opts config_opts
local seed_file="$BUILD_DIR/.config"
local worktree_meta="$SRC_DIR/.git/worktrees/source-$ref"
local pkg config commit seed_file description
local -a make_opts
local -a config_opts=(
"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"
if ((DEBUG)); then
echo "Profile settings:"
for x in "${!P_ARR[@]}"; do printf "%s=%s\n" "$x" "${P_ARR[$x]}"; done
echo "Environment variables:"
declare -p
fi
# Remove all build directories and worktrees if --reset
if ((RESET)); then
if [[ -d "$WORKTREE_DIR" || -d "$worktree_meta" ]]; then
execute git -C "$SRC_DIR" worktree remove --force --force "$WORKTREE_DIR"
[[ -d "$WORKTREE_DIR" ]] && execute rm -rf "$WORKTREE_DIR"
if [[ -d "$BUILD_DIR" || -d "$worktree_meta" ]]; then
execute git -C "$SRC_DIR" worktree remove --force --force "$BUILD_DIR"
[[ -d "$BUILD_DIR" ]] && execute rm -rf "$BUILD_DIR"
[[ -d "$worktree_meta" ]] && execute rm -rf "$worktree_meta"
fi
[[ -d "$BUILD_DIR" ]] && execute rm -rf "$BUILD_DIR"
fi
# Update source code
if [[ ! -d "$SRC_DIR" ]]; then
# Fetch or clone source repo (no local merges)
if [[ -d "$SRC_DIR" ]]; then
execute git -C "$SRC_DIR" fetch origin --tags --prune
else
execute mkdir -p "$SRC_DIR"
execute git clone "$src_url" "$SRC_DIR"
fi
execute git -C "$SRC_DIR" worktree prune --verbose
execute git -C "$SRC_DIR" pull
# Generate commitish for git worktree
case "$RELEASE" in
snapshot) wt_commit="origin/main" ;;
[0-9][0-9].[0-9][0-9].*)
local branch="openwrt-${RELEASE%.*}"
local tag="v$RELEASE"
if ask_ok "Use $branch branch HEAD (y, recommended) or $tag tag (n)?"; then
wt_commit="origin/$branch"
else
wt_commit="$tag"
fi
;;
*)
debug "Passing '$RELEASE' commit-ish to git worktree"
wt_commit="$RELEASE"
;;
esac
# Pull existing or add new git worktree
if [[ -d "$WORKTREE_DIR" && -d "$worktree_meta" ]]; then
execute git -C "$WORKTREE_DIR" checkout "$wt_commit"
execute git -C "$WORKTREE_DIR" pull
# Reuse worktree if present; otherwise create it (support branches and tags)
if git -C "$BUILD_DIR" rev-parse --is-inside-work-tree >/dev/null 2>&1; then
execute git -C "$BUILD_DIR" fetch origin --tags --prune
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
[[ -d "$WORKTREE_DIR" ]] && execute rm -rf "$WORKTREE_DIR"
[[ -d "$worktree_meta" ]] && execute rm -rf "$worktree_meta"
execute git -C "$SRC_DIR" worktree add --force --force --detach "$WORKTREE_DIR" "$wt_commit"
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
# Print commit information
commit=$(git -C "$WORKTREE_DIR" rev-parse HEAD)
description=$(git -C "$WORKTREE_DIR" describe)
# Add cherrypicks
for entry in ${P_ARR[cherrypicks]}; do
url_branch="${entry%%:*}"
commit="${entry##*:}"
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
execute git -C "$BUILD_DIR" merge-base --is-ancestor "$commit" HEAD ||
execute git -C "$BUILD_DIR" cherry-pick "$commit"
done
# Print commit info
commit=$(git -C "$BUILD_DIR" rev-parse HEAD)
description=$(git -C "$BUILD_DIR" describe --always --dirty)
echo "Current commit hash: $commit"
echo "Git worktree description: $description"
((DEBUG)) && git --no-pager -C "$WORKTREE_DIR" log -1
((DEBUG)) && git --no-pager -C "$BUILD_DIR" log -1
# Enter worktree
execute pushd "$WORKTREE_DIR" || return 1
execute pushd "$BUILD_DIR" || return 1
# Cleanup build environment
# Begin OpenWRT build process
((DEBUG)) && make_opts+=("V=sc")
execute make "${make_opts[@]}" "-j1" distclean
# Cleanup build environment: heavy clean only when --reset was used earlier
# make clean # compiled output
# make targetclean # compiled output, toolchain
# make dirclean # compiled output, toolchain, build tools
# make distclean # compiled output, toolchain, build tools, .config, feeds, .ccache
if [[ -n $SOURCE_CLEAN ]]; then
execute make "${make_opts[@]}" "-j1" "$SOURCE_CLEAN"
else
debug "Skipping cleanup step"
fi
# 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
./scripts/feeds update -a -f &&
./scripts/feeds install -a -f
# Grab the release seed config
if ! execute "$DL_TOOL" "-o" "$seed_file" "$seed_url"; then
echo "Could not obtain $seed_file from $seed_url"
return 1
fi
# Set compilation output dir
config_opts+=("CONFIG_BINARY_FOLDER=\"$BIN_DIR\"")
# Add custom packages
for pkg in $PACKAGES; do
if [[ $pkg == -* ]]; then
@@ -570,52 +644,37 @@ from_source() {
fi
done
# Add config options from profile
# Add profile config options
for config in ${P_ARR[config]}; do
config_opts+=("$config")
done
# Only compile selected fs
execute sed -i '/CONFIG_TARGET_ROOTFS_/d' "$seed_file"
config_opts+=("CONFIG_TARGET_PER_DEVICE_ROOTFS=n")
if [[ $FILESYSTEM == "squashfs" ]]; then
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
# Reset and write options to config seed file
[[ -f $seed_file ]] && execute rm -f "$seed_file"
for config in "${config_opts[@]}"; do
debug "Writing $config to $seed_file"
echo "$config" >> "$seed_file"
done
# Make prep
# Expand seed into full config
execute make "${make_opts[@]}" "-j1" defconfig
# Run serial make download for better reliability
execute make "${make_opts[@]}" "-j1" download
((DEBUG)) && make_opts+=("-j1") || make_opts+=("-j$(($(nproc)-1))")
# (Optional) Disable multicore make world
# ((DEBUG)) && make_opts+=("-j1") || make_opts+=("-j$(($(nproc)-2))")
make_opts+=("-j$(($(nproc)-2))")
# Make image
if ! execute ionice -c 3 chrt --idle 0 nice -n19 make "${make_opts[@]}" world; then
if ! execute ionice -c2 -n7 nice -n19 make "${make_opts[@]}" BIN_DIR="$BIN_DIR" world; then
echo "Error: make failed"
return 1
fi
execute popd || return 1
# Symlink output images to root of BIN_DIR (match Image Builder)
# Symlink output images to root of BIN_DIR (match Image Builder behavior)
shopt -s nullglob
for image in "$BIN_DIR/targets/${TARGET}/"*.{img,img.gz,ubi}; do
execute ln -fs "$image" "$BIN_DIR/${image##*/}"
@@ -633,7 +692,7 @@ backup() {
local file="$1" dir="$2"
local creation_date base_name backup_file
[[ -f $file ]] || { debug "File not found: $file"; return 1; }
[[ -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) && \
@@ -722,8 +781,13 @@ main() {
exit $?
fi
install_dependencies
# Remove dependency lock files for --depends
if ((FORCE_DEPENDS)); then
[[ -f "$BUILD_ROOT/.dependencies_source.lock" ]] && rm -f "$BUILD_ROOT/.dependencies_source.lock"
[[ -f "$BUILD_ROOT/.dependencies_ib.lock" ]] && rm -f "$BUILD_ROOT/.dependencies_ib.lock"
fi
# Run selected profiles
for profile in "${PROFILES[@]}"; do
debug "Running profile: $profile"
@@ -733,40 +797,34 @@ main() {
fi
# Store profile in P_ARR nameref
declare -gn P_ARR="$profile"
local -n P_ARR="$profile"
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 TARGET="${P_ARR[target]}"
declare -g DEVICE="${P_ARR[device]}"
declare -g PACKAGES="${P_ARR[packages]:-}"
declare -g RELEASE="${USER_RELEASE:=${P_ARR[release]:=$RELEASE}}"
# normalize RELEASE
case "$RELEASE" in
snapshot|latest|main|master) RELEASE="snapshot" ;;
v[0-9][0-9].[0-9][0-9].*) RELEASE="${RELEASE#v}" ;;
[0-9][0-9].[0-9][0-9].*) ;;
*)
if ! ((FROM_SOURCE)); then
echo "Error: Invalid release version format"
echo "Use semantic version, tag, or 'snapshot'"
exit 1
fi
;;
esac
# pull in USER_RELEASE from args or profile default
local raw_release="${USER_RELEASE:=${P_ARR[release]:=$RELEASE}}"
declare -g SRC_DIR="$BUILD_ROOT/src/openwrt"
declare -g WORKTREE_DIR="$BUILD_ROOT/src/$profile/$RELEASE-src"
declare -g BUILD_DIR="$BUILD_ROOT/src/$profile/$RELEASE"
declare -g BIN_DIR="$BUILD_ROOT/bin/$profile/$RELEASE"
# single call to normalize+ref
read -r release ref < <(normalize_and_ref "$raw_release" "$mode")
if [[ "$RELEASE" == "snapshot" ]]; then
declare -g SRC_DIR="$BUILD_ROOT/src/.openwrt"
declare -g BUILD_DIR="$BUILD_ROOT/src/$profile/$ref-$mode"
declare -g BIN_DIR="$BUILD_ROOT/bin/$profile/$ref-$mode"
if [[ "$release" == "snapshot" ]]; then
local url_prefix="https://downloads.openwrt.org/snapshots/targets/$TARGET"
local url_filename="openwrt-imagebuilder-${TARGET//\//-}.Linux-x86_64.tar.zst"
local img_fname="openwrt-${TARGET//\//-}-$DEVICE-$FILESYSTEM"
else
local url_prefix="https://downloads.openwrt.org/releases/$RELEASE/targets/$TARGET"
local url_filename="openwrt-imagebuilder-$RELEASE-${TARGET//\//-}.Linux-x86_64.tar.zst"
local img_fname="openwrt-$RELEASE-${TARGET//\//-}-$DEVICE-$FILESYSTEM"
local url_prefix="https://downloads.openwrt.org/releases/$release/targets/$TARGET"
local url_filename="openwrt-imagebuilder-$release-${TARGET//\//-}.Linux-x86_64.tar.zst"
local img_fname="openwrt-$release-${TARGET//\//-}-$DEVICE-$FILESYSTEM"
fi
local ib_url="$url_prefix/$url_filename"
@@ -775,22 +833,27 @@ main() {
local ib_sha256_file="$BUILD_DIR/sha256sums"
local seed_url="$url_prefix/config.buildinfo"
if ((FROM_SOURCE)); then
if [[ "$mode" == "source" ]]; then
declare -g SYSUPGRADEIMGGZ="$BIN_DIR/targets/$TARGET/$img_fname-sysupgrade.img.gz"
else
declare -g SYSUPGRADEIMGGZ="$BUILD_DIR/$img_fname-sysupgrade.img.gz"
fi
backup "$SYSUPGRADEIMGGZ" "$BACKUP_DIR/$profile/$RELEASE"
backup "$SYSUPGRADEIMGGZ" "$BACKUP_DIR/$profile/$ref-$mode"
if ((FROM_SOURCE)); then
from_source "$seed_url" || return $?
else
if [[ "$mode" == "source" ]]; then
from_source "$seed_url" "$profile" "$ref" || return $?
elif [[ "$mode" == "imagebuilder" ]]; then
[[ -d $BUILD_DIR ]] || mkdir -p "$BUILD_DIR"
get_imagebuilder "$ib_url" "$ib_file" "$ib_sha256_url" "$ib_sha256_file" &&
verify "$ib_file" "$ib_sha256_file" &&
extract "$ib_file" "$BUILD_DIR" || return $?
add_repos
if [[ -v $repo ]]; then
if ! grep -q "$repo" "$BUILD_DIR/repositories.conf"; then
echo "$repo" >> "$BUILD_DIR/repositories.conf"
fi
sed -i '/option check_signature/d' "$BUILD_DIR/repositories.conf"
fi
make_images
# Verify output image for stock builds (in testing)
if [[ ! -v P_ARR[packages] || -z ${P_ARR[packages]} ]]; then
@@ -810,5 +873,9 @@ main() {
done
}
# Roughly turn debugging on for pre-init
# Reset and reparse in parse_input() with getopt
[[ " $* " =~ ( --debug | -d ) ]] && DEBUG=1
main "$@"
exit

View File

@@ -1,64 +1,109 @@
#!/usr/bin/env bash
# shellcheck disable=SC2034
# Device profiles for openwrtbuilder
# shellcheck disable=SC2034
# Default packages
default_packages="luci luci-ssl luci-proto-wireguard luci-app-statistics \
collectd-mod-sensors collectd-mod-thermal collectd-mod-conntrack \
collectd-mod-cpu nano htop diffutils tar iperf3 zsh rsync \
openssh-sftp-server"
# Default (but optional) packages (precede with "-" to exclude)
default_packages=(nano htop diffutils tar iperf3 zsh rsync curl tcpdump
openssh-sftp-server luci luci-ssl luci-proto-wireguard luci-app-statistics
collectd-mod-sensors collectd-mod-thermal collectd-mod-conntrack collectd-mod-cpu
)
# Default (but optional) kernel configs
default_configs=(
)
# Current devices
declare -Ag r4s=(
[mode]="source"
[device]="friendlyarm_nanopi-r4s"
[target]="rockchip/armv8"
[filesystem]="ext4"
[packages]="$default_packages luci-app-ddns luci-app-sqm irqbalance \
[packages]="${default_packages[*]} \
luci-app-ddns luci-app-sqm \
adblock luci-app-adblock \
collectd-mod-df usbutils kmod-usb-storage kmod-usb-storage-uas \
kmod-fs-btrfs btrfs-progs block-mount smcroute avahi-daemon \
curl ethtool ca-bundle tailscale"
[config]="CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y \
CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=32 \
CONFIG_BUILDBOT=n"
ethtool ca-bundle tailscale"
[config]="${default_configs[*]} \
CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y \
CONFIG_TARGET_ROOTFS_PARTSIZE=512 CONFIG_TARGET_KERNEL_PARTSIZE=32"
[files]="/mnt/backup"
# For 24.10 branch (Linux 6.6)
# [cherrypicks]="https://github.com/wurzerj/openwrt.git:59d6e31 \
# https://github.com/wurzerj/openwrt.git:bb251b8" # fix inconsistent reboot
)
declare -Ag ax6000=(
[mode]="imagebuilder"
[device]="xiaomi_redmi-router-ax6000-stock"
[target]="mediatek/filogic"
[release]="snapshot"
[filesystem]="squashfs"
[packages]="$default_packages -dnsmasq -odhcpd-ipv6only -nftables -firewall4 tailscale"
[packages]="${default_packages[*]} \
-dnsmasq -odhcpd-ipv6only -nftables -firewall4 tailscale"
)
declare -Ag ax6000_uboot=(
[mode]="imagebuilder"
[device]="xiaomi_redmi-router-ax6000-ubootmod"
[target]="mediatek/filogic"
[release]="snapshot"
[filesystem]="squashfs"
[packages]="$default_packages -dnsmasq -odhcpd-ipv6only -nftables -firewall4"
[packages]="${default_packages[*]} \
-dnsmasq -odhcpd-ipv6only -nftables -firewall4"
)
declare -Ag n5100=(
[device]="generic"
[target]="x86/64"
[filesystem]="squashfs"
[packages]="$default_packages luci-app-ddns irqbalance collectd-mod-df \
[packages]="${default_packages[*]} \
luci-app-ddns irqbalance collectd-mod-df \
usbutils kmod-usb-storage kmod-usb-storage-uas kmod-fs-btrfs \
btrfs-progs block-mount cryptsetup kmod-crypto-xts smcroute \
avahi-daemon curl ethtool ca-bundle smartmontools intel-microcode \
avahi-daemon ethtool ca-bundle smartmontools intel-microcode \
lm-sensors samba4-server luci-app-samba4 tailscale shadow-useradd"
[config]="CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y \
[config]="${default_configs[*]} \
CONFIG_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y \
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-ddns luci-app-sqm \
adblock luci-app-adblock \
smcroute avahi-daemon \
lm-sensors samba4-server luci-app-samba4 tailscale shadow-useradd \
ethtool ca-bundle tailscale"
[cherrypicks]="\
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:4cfd50f648 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:59bb20c522 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:1d58331f5c \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:c2712ff093 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:dc3dd61835 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:32caca6a76 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:cf66b89f84 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:ef002d6422 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:af3e569610 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:66b0757616 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:26398bc2c6 \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:16be0246ca \
https://github.com/OpenWRT-fanboy/OpenW1700k.git@lumos:3cdf63b0ec"
)
declare -Ag rpi4=(
[device]="rpi-4"
[target]="bcm27xx/bcm2711"
[filesystem]="ext4"
[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"
[packages]="${default_packages[*]} \
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=(
@@ -72,7 +117,8 @@ declare -Ag totolink=(
[device]="totolink_x5000r"
[target]="ramips/mt7621"
[filesystem]="squashfs"
[packages]="$default_packages -dnsmasq -odhcpd-ipv6only -nftables -firewall4 \
[packages]="${default_packages[*]} \
-dnsmasq -odhcpd-ipv6only -nftables -firewall4 \
-kmod-nft-offload collectd-mod-iwinfo"
)
@@ -80,7 +126,7 @@ declare -Ag archer=(
[device]="tplink_archer-c7-v2"
[target]="ath79/generic"
[filesystem]="squashfs"
[packages]="$default_packages -dnsmasq -odhcpd -iptables \
[packages]="${default_packages[*]} -dnsmasq -odhcpd -iptables \
-ath10k-firmware-qca988x-ct ath10k-firmware-qca988x-ct-full-htt"
)
@@ -88,14 +134,16 @@ declare -Ag linksys=(
[device]="linksys_ea8300"
[target]="ipq40xx/generic"
[filesystem]="squashfs"
[packages]="$default_packages -dnsmasq -odhcpd -iptables"
[packages]="${default_packages[*]} \
-dnsmasq -odhcpd -iptables"
)
declare -Ag r2s=(
[device]="friendlyarm_nanopi-r2s"
[target]="rockchip/armv8"
[filesystem]="ext4"
[packages]="$default_packages luci-app-upnp luci-app-pbr -dnsmasq dnsmasq-full \
[packages]="${default_packages[*]} \
luci-app-upnp luci-app-pbr -dnsmasq dnsmasq-full \
luci-app-ddns luci-app-sqm luci-app-statistics collectd-mod-sensors \
collectd-mod-thermal collectd-mod-conntrack smcroute curl ethtool"
)
@@ -104,7 +152,8 @@ declare -Ag r2s_tr=(
[device]="friendlyarm_nanopi-r2s"
[target]="rockchip/armv8"
[filesystem]="ext4"
[packages]="$default_packages luci-app-upnp luci-app-pbr luci-app-ddns \
[packages]="${default_packages[*]} \
luci-app-upnp luci-app-pbr luci-app-ddns \
luci-app-statistics collectd-mod-sensors collectd-mod-thermal \
collectd-mod-conntrack curl ethtool travelmate"
)