Compare commits

..

5 Commits

Author SHA1 Message Date
2d83b552c7 Cleanup usage() 2026-05-12 10:43:23 -04:00
ec8fb8f960 r4s: remove very erroneous /mnt/backup files dir 2026-05-11 21:57:10 -04:00
2ce592b693 Document profiles keys 2026-05-11 21:29:53 -04:00
4d70450fe8 Fix files overlay and flash_images() 2026-05-11 21:29:19 -04:00
2245e7feef r4s: add luci-app-sqm 2026-05-11 21:28:15 -04:00
3 changed files with 61 additions and 22 deletions

View File

@@ -41,12 +41,37 @@ See `profiles` for example device profile definitions. Multiple `--profile` can
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 `--mode=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 23.05.5 --mode source --debug` * `openwrtbuilder -p ax6000 -r 25.12.3 --mode source --debug`
* `openwrtbuilder -p rpi4 -r 23.05.5 --flash /dev/sdX` * `openwrtbuilder -p rpi4 -r 25.12.3 --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,25 +1,25 @@
#!/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"}}" : "${DEFAULT_RELEASE:=${RELEASE:="25.12.3"}}" # do find all replace
# @internal # @internal
print_help() { usage() {
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 [OPTION [VALUE]]... -p PROFILE [-p PROFILE]... openwrtbuilder [OPTIONS] [-p PROFILE]...
OPTIONS OPTIONS
--profile,-p PROFILE --profile,-p PROFILE
--release,-r,--version,-v RELEASE ("snapshot", "24.10.5") --release,-r,--version,-v RELEASE ("snapshot", "25.12.3")
Default: From profile or hardcoded RELEASE Default: From profile or hardcoded RELEASE
--buildroot,-b PATH --buildroot,-b PATH
Default: location of openwrtbuilder script Default: location of openwrtbuilder script
@@ -45,7 +45,7 @@ print_help() {
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 --mode source --debug
openwrtbuilder -p rpi4 -r 24.10.0 --flash /dev/sdX openwrtbuilder -p rpi4 -r 25.12.3 --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
} }
@@ -66,7 +66,7 @@ init() {
else else
echo "/etc/os-release not found" echo "/etc/os-release not found"
echo "Your OS is unsupported" echo "Your OS is unsupported"
print_help usage
exit 1 exit 1
fi fi
@@ -149,14 +149,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) print_help; exit 0 ;; --help|-h) usage; exit 0 ;;
--) shift; break ;; --) shift; break ;;
esac esac
shift shift
done done
else else
echo "Incorrect options provided" echo "Incorrect options provided"
print_help; exit 1 usage; exit 1
fi fi
} }
@@ -458,7 +458,8 @@ make_images() {
# Debug manually so we can log output # Debug manually so we can log output
debug "${make_cmd[*]}" debug "${make_cmd[*]}"
"${make_cmd[@]}" > "$BUILD_DIR/make.log" 2>&1 "${make_cmd[@]}" 2>&1 | tee "$BUILD_DIR/make.log"
return "${PIPESTATUS[0]}" # bash-specific way to return exit code of piped command
} }
flash_images() { flash_images() {
@@ -466,9 +467,8 @@ 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 [[ ! -e "$dev" ]]; then if [[ ! -b "$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 +476,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!"
@@ -674,6 +674,13 @@ from_source() {
./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.
execute rm -rf "$BUILD_DIR/files"
if [[ -d "$FILES_DIR" ]]; then
execute mkdir -p "$BUILD_DIR/files"
execute rsync -a "$FILES_DIR/" "$BUILD_DIR/files/"
fi
# Add custom packages # Add custom packages
for pkg in $PACKAGES; do for pkg in $PACKAGES; do
if [[ $pkg == -* ]]; then if [[ $pkg == -* ]]; then
@@ -774,7 +781,6 @@ 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
@@ -822,6 +828,15 @@ main() {
declare -g CHERRYPICKS="${P_ARR[cherrypicks]:-}" # scalar declare -g CHERRYPICKS="${P_ARR[cherrypicks]:-}" # scalar
declare -g BRANCHES="${P_ARR[branches]:-}" # scalar declare -g BRANCHES="${P_ARR[branches]:-}" # scalar
declare -g KCONFIGS="${P_ARR[kconfigs]:-}" # scalar declare -g KCONFIGS="${P_ARR[kconfigs]:-}" # scalar
declare -g FILES_DIR="${P_ARR[files]:-$BUILD_ROOT/src/files}"
if [[ ! -d "$FILES_DIR" ]]; then
if [[ -v P_ARR[files] ]]; then
echo "Profile '$PROFILE' files directory does not exist: $FILES_DIR"
return 1
fi
execute mkdir -p "$FILES_DIR"
fi
install_dependencies "$MODE" install_dependencies "$MODE"

View File

@@ -24,13 +24,13 @@ declare -Ag r4s=(
[filesystem]="ext4" [filesystem]="ext4"
[packages]="${default_packages[*]} \ [packages]="${default_packages[*]} \
adblock luci-app-adblock \ 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" ethtool ca-bundle tailscale"
[kconfigs]="${default_kconfigs[*]} \ [kconfigs]="${default_kconfigs[*]} \
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_KERNEL_BTRFS_FS_POSIX_ACL=y CONFIG_BTRFS_PROGS_ZSTD=y"
[files]="/mnt/backup"
# For 24.10 branch (Linux 6.6) # For 24.10 branch (Linux 6.6)
# [cherrypicks]="https://github.com/wurzerj/openwrt.git:59d6e31 \ # [cherrypicks]="https://github.com/wurzerj/openwrt.git:59d6e31 \
# https://github.com/wurzerj/openwrt.git:bb251b8" # fix inconsistent reboot # https://github.com/wurzerj/openwrt.git:bb251b8" # fix inconsistent reboot
@@ -45,7 +45,7 @@ declare -Ag ax6000=(
tailscale" tailscale"
) )
declare -Ag ax6000_uboot=( declare -Ag ax6000_uboot_ap=(
[mode]="imagebuilder" [mode]="imagebuilder"
[device]="xiaomi_redmi-router-ax6000-ubootmod" [device]="xiaomi_redmi-router-ax6000-ubootmod"
[target]="mediatek/filogic" [target]="mediatek/filogic"
@@ -68,7 +68,6 @@ declare -Ag n5100=(
[kconfigs]="${default_kconfigs[*]} \ [kconfigs]="${default_kconfigs[*]} \
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=( declare -Ag w1700k=(