Skip to content

Instantly share code, notes, and snippets.

@Taverius
Last active July 25, 2024 21:20
Show Gist options
  • Save Taverius/392033ddb0b597936e0b4eb527627cb1 to your computer and use it in GitHub Desktop.
Save Taverius/392033ddb0b597936e0b4eb527627cb1 to your computer and use it in GitHub Desktop.
OpenWrt ImageBuilder script
#!/bin/bash
# ------------------------------------------------------------------------------
#
# Bash script to ease generating images with image-builder
# Designed to be used with a directory strcture like:
#
# | builder.sh (this script)
# | /files-local/ (extract your uci backups in here)
# | /packages-local/ (put out-of-tree package .ipk that don't have a feed here)
# | /openwrt-imagebuilder-*/ (your image builder extracted from package)
#
# 1. Download the script and place it.
# 2. Edit script variables as desired.
# 3. 'chmod +x builder.sh' to make it executable.
# 4. CD into the image builder directory.
# 5. call '../builder.sh'.
#
# Script will:
#
# 1. clear any *.ipk from openwrt-imagebuilder-*/packages/
# 2. copy any *.ipk from ../packages-local/ into ./packages/
# 3. make clean
# 5. make images with your config
#
# You can configure packages, disable services, set profile and partition sizes
# in the next section.
#
# Any variables left blank or commented out will be ignored.
#
# ------------------------------------------------------------------------------
# ------------------- #
# #
# BEGIN CONFIGURATION #
# #
# ------------------- #
# Profile
#
# The chosen build profile.
profile="generic"
# Packages
#
# Your custom package definitions.
#
# Add the package name to include. Prepend a dash like '-package-name' to
# remove a default package.
#
# For example:
# packages="-dnsmasq -logd dnsmasq-full luci-ssl-nginx syslog-ng" would replace
# dnsmasq for the full-feature but larger version, replace logd with syslog-ng,
# and install the nginx version of LuCI.
#
# You can use multiple defitions like:
# packages="-package-1 package-2"
# packages="$packages package-3"
# to make things more readable if you'd like.
#
# Note that the image builder doesn't perform full dependency resolution, so the
# order can matter.
# For example, calling with:
#
# packages="avahi-daemon-service-http avahi-utils"
#
# Would fail because avahi-daemon-service-http depends on either
# avahi-dbus-daemon or avahi-nodbus-daemon and prefers the latter
# (because of size), while avahi-utils requires avahi-dbus-daemon.
#
# Imagebuilder will process the first package, pull in avahi-nodbus-daemon,
# process the second and fail because you cannot have both version of the avahi
# daemon at the same time.
#
# So in order to resolve you would need to either:
#
# 1. Specify avahi-utils BEFORE avahi-daemon-service-http:
# packages="avahi-utils avahi-daemon-service-http"
#
# 2. Specifiy avahi-dbus-daemon BEFORE avahi-daemon-service-http:
# packages="avahi-dbus-daemon avahi-daemon-service-http avahi-utils"
packages=""
# Disabled services
#
# Any services you want to be disabled on first boot.
#
# For example, if you're using luci-ssl-nginx but also prometheus-exporter
# which depends on uhttpd, you'd add 'uhttpd' here so it doesn't try to start
# the default server on :80/:443 which could conflict with LuCI on nginx.
disabled_services=""
# Root Partition Size
#
# Uncomment this to change the size of your root partition from your profile
# default.
# This is often needed once you start adding packages.
#
# Value is the size, in megabytes, as an integer.
#
# On x86 you can input 512 and that will be good for nearly anything,
# on embedded-storage devices you will want to be more minimalistic and try
# multiple values until your find out exactly how much you need and no more.
root_partsize=""
# Files Directory
#
# The directory where local files (like an extracted uci backup) are stored.
files_dir="../files-local"
# Output Directory
#
# Alternate directory to save built images to.
output_dir=""
# Packages Directory
#
# The directory where local .ipk packages are stored.
# They will be copied into the imagebuilder's /packages directory.
#
# NOTE: The builder's packages directory is *ALWAYS* cleared of .ipk files
# when the script is run, even if this value is not present.
packages_dir="../packages-local"
# -------------------- #
# #
# END OF CONFIGURATION #
# #
# -------------------- #
echo "Checking if $PWD/ is a valid image builder ..."
echo "Checking files ..."
for filename in .config .packageinfo .targetinfo Makefile repositories.conf rules.mk
do
printf "Checking for ./$filename ... "
if [[ -f "$filename" ]]; then
echo "Passed."
else
echo "Failed!"
echo "./$filename is missing!"
echo "Is $PWD an image-builder root?"
exit 1
fi
done
echo "Checking directories ..."
for directory in build_dir include keys packages scripts staging_dir target
do
printf "Checking for ./$directory/ ... "
if [[ -d "$directory" ]]; then
echo "Passed."
else
echo "Failed!"
echo "./$directory/ is missing!"
echo "Is $PWD an image-builder root?"
exit 1
fi
done
echo "Done!"
echo
echo "Building parameters ..."
parameters=()
if [[ ${#files_dir} -ge 1 ]]; then
printf "Checking local files directory ... "
if [[ -d "$files_dir" ]]; then
echo "Passed."
parameters+=(FILES="$files_dir")
else
echo "Failed!"
echo "$files_dir is not a valid directory, exiting."
exit 1
fi
fi
if [[ ${#output_dir} -ge 1 ]]; then
printf "Checking output directory ... "
if [[ -d "$output_dir" ]]; then
echo "Passed."
parameters+=(BIN_DIR="$output_dir")
else
echo "Failed!"
echo "$output_dir is not a valid directory, exiting."
exit 1
fi
fi
if [[ ${#root_partsize} -ge 1 ]]; then
printf "Checking root partition size ... "
if [[ -n $root_partsize ]] && [[ "$root_partsize" =~ ^[0-9]+$ ]]; then
echo "Passed."
parameters+=(ROOTFS_PARTSIZE=$root_partsize)
else
echo "Failed!"
echo "$root_partsize is not an integer, exiting."
exit 1
fi
fi
if [[ ${#profile} -ge 1 ]]; then
printf "Setting profile ... "
parameters+=(PROFILE="$profile")
echo "Done."
fi
if [[ ${#packages} -ge 1 ]]; then
printf "Setting package list ... "
parameters+=(PACKAGES="$packages")
echo "Done."
fi
if [[ ${#disabled_services} -ge 1 ]]; then
printf "Setting disabled services list ... "
parameters+=(DISABLED_SERVICES="$disabled_services")
echo "Done."
fi
echo "Done!"
echo "Using parameters:" ${parameters[@]@Q}
echo
echo "Removing local packages from image-builder ..."
for package in ./packages/*.ipk
do
printf "Removing $package ... "
if rm $package; then
echo "Done."
else
echo "Failed!"
echo "Could not remove $package, exiting."
exit 1
fi
done
echo "Done!"
echo
if [[ ${#packages_dir} -ge 1 ]]; then
printf "Checking local packages directory ... "
if [[ -d "$packages_dir" ]]; then
echo "Passed."
else
echo "Failed!"
echo "$packages_dir is not a valid directory, exiting."
exit 1
fi
echo "Preparing local packages ..."
for package in $packages_dir/*.ipk
do
filename=$(basename -- "$package")
printf "Copying $filename into $PWD/packages ... "
if cp $package ./packages/; then
echo "Done."
else
echo "Failed!"
echo "Could not copy $package, exiting."
exit 1
fi
done
echo "Done!"
echo
fi
echo "Cleaning up ..."
make clean || exit 1
echo "Building images ..."
make image "${parameters[@]}"
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment