Compare commits
5 Commits
f5f32ed8d4
...
master
| Author | SHA1 | Date | |
|---|---|---|---|
| 2d83b552c7 | |||
| ec8fb8f960 | |||
| 2ce592b693 | |||
| 4d70450fe8 | |||
| 2245e7feef |
29
README.md
29
README.md
@@ -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
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
5
profiles
5
profiles
@@ -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=(
|
||||||
|
|||||||
Reference in New Issue
Block a user