4 Commits

Author SHA1 Message Date
Attila Lendvai
7a3ae89b20 added a manifest.scm for guix 2023-10-23 00:09:19 +02:00
Attila Lendvai
0d4d33409e set SOURCE_DATE_EPOCH
without this the image builder fails.

this might be connected to the inability of the configure script to
properly detect git on guix, but not likely.
2023-10-22 22:48:41 +02:00
Attila Lendvai
836235e656 use OpenWrt 19.07.9 2023-10-22 22:22:22 +02:00
Attila Lendvai
ab6816284f decrease memory need of dd while erasing the partition table
this was leading to the OOM killer killing dd.
2023-10-22 21:53:49 +02:00
6 changed files with 116 additions and 149 deletions

View File

@@ -1,63 +1,51 @@
# What # What
It's a script to build a customized It's a script to build a customized
[OpenWrt](https://openwrt.org/docs/guide-user/start) [OpenWRT](https://openwrt.org/docs/guide-user/start)
firmware image using firmware image using
[ImageBuilder](https://openwrt.org/docs/guide-user/additional-software/imagebuilder). [ImageBuilder](https://openwrt.org/docs/guide-user/additional-software/imagebuilder).
If the generated image is flashed on a router, then during its boot If the generated image is flashed on a device it will try to automatically set up
process it will try to automatically set up
[extroot](https://openwrt.org/docs/guide-user/additional-software/extroot_configuration) [extroot](https://openwrt.org/docs/guide-user/additional-software/extroot_configuration)
on **any (!)** storage device plugged into the USB port (`/dev/sda`), on **any (!)** storage device plugged into the USB port (`/dev/sda`). Keep in
including your already working extroot pendrive if you plug it in too mind that **this will erase any inserted storage device while the
late in the boot process. router is in the initial setup phase**! Unfortunately there's little
that can be done at that point to ask the user for confirmation.
# Why # Why
So that e.g. customers can buy a router on their own, download and flash our custom So that e.g. customers can buy a router on their own, flash our custom
firmware, plug in a pendrive, and manage their SIP (telephony) node firmware, plug in a pendrive, and manage their SIP (telephony) node
from our webapp. from our webapp.
I've extracted the generic parts from the above mentioned auto-provision I've extracted the generic parts from the above mentioned auto-provision
project because I thought it's useful enough for making it public. project because I thought it's useful enough for making it public.
It also serves me well on my own routers ever since then.
# How # How
You can read more about the underlying technology on the OpenWrt wiki: see e.g. the You can read more about the underlying technology on the OpenWRT wiki: see e.g. the
[ImageBuilder](https://openwrt.org/docs/guide-user/additional-software/imagebuilder) [ImageBuilder](https://openwrt.org/docs/guide-user/additional-software/imagebuilder)
page, or the page that lists some other page, or the page that lists some other
[ImageBuilder frontends](https://openwrt.org/docs/guide-developer/imagebuilder_frontends). [ImageBuilder frontends](https://openwrt.org/docs/guide-developer/imagebuilder_frontends).
As for the actual mechanism: custom scripts are baked into the boot As for the actual mechanism: custom scripts are baked into the boot process of the
process of the flashed firmware. If the extroot overlay is properly flashed firmware. If the extroot overlay is properly set up, then these scripts get hidden by it;
set up, then these scripts get hidden by it; i.e. they will only be run i.e. they will only run when the extroot has failed to mount early in the boot.
when the extroot has failed to mount early in the boot process.
Keep in mind that **this will automatically erase/format any inserted
storage device while the router is in the initial setup phase**!
Unfortunately there's little that can be done at that point to ask the
user for confirmation.
### Building ### Building
OpenWrt's ImageBuilder only works on Linux x86_64. To build a firmware, issue the following command: OpenWRT's ImageBuilder only works on Linux x86_64. To build a firmware, issue the following command:
`./build.sh architecture variant device-profile`, e.g.: `./build.sh architecture variant device-profile`, e.g.:
* `./build.sh ath79 generic tplink_tl-wr1043nd-v1` * `./build.sh ar71xx generic tplink_tl-wr1043nd-v1`
* `./build.sh ath79 generic tplink_archer-c6-v2` * `./build.sh ath79 generic tplink_archer-c6-v2`
* `./build.sh ath79 generic tplink_tl-wdr4300-v1`
* `./build.sh bcm53xx generic dlink_dir-885l`
Results will be under `build/openwrt-imagebuilder-${release}-${architecture}-${variant}.Linux-x86_64/bin/`. Results will be under `build/openwrt-imagebuilder-${release}-${architecture}-${variant}.Linux-x86_64/bin/`.
To see a list of available targets, run `make info` in the ImageBuilder dir. To see a list of available targets, run `make info` in the ImageBuilder dir.
If you want to change which OpenWrt version is used, then try editing If you want to change which OpenWRT version is used, then edit the relevant variable(s)
the relevant variable(s) in `build.sh`. It's not guaranteed to work in `build.sh`.
across OpenWrt releases, therefore we keep git branches for the past
releases.
### Setup stages ### Setup stages
@@ -74,7 +62,7 @@ space), and then reboot.
#### Stage 2: download and install some packages from the internet #### Stage 2: download and install some packages from the internet
Once it rebooted into the new extroot, it will continuously keep trying to install Once it rebooted into the new extroot, it will continuously keep trying to install
some OpenWrt packages until an internet connection is set up on the router. You some OpenWRT packages until an internet connection is set up on the router. You
need to do that manually either by using ssh or the web UI (LuCI). need to do that manually either by using ssh or the web UI (LuCI).
#### Stage 3, optional #### Stage 3, optional
@@ -91,7 +79,7 @@ By default the root passwd is not set, so the router will start telnet with
no password. If you want to set up a password, then edit the stage 2 script: no password. If you want to set up a password, then edit the stage 2 script:
[autoprovision-stage2.sh](image-extras/common/root/autoprovision-stage2.sh#L53). [autoprovision-stage2.sh](image-extras/common/root/autoprovision-stage2.sh#L53).
If a password is set, then telnet is disabled by OpenWrt and SSH will listen If a password is set, then telnet is disabled by OpenWRT and SSH will listen
using the keys specified in [authorized_keys](image-extras/common/etc/dropbear/authorized_keys). using the keys specified in [authorized_keys](image-extras/common/etc/dropbear/authorized_keys).
Once connected, you can read the log with `logread -f`. Once connected, you can read the log with `logread -f`.
@@ -99,54 +87,42 @@ Once connected, you can read the log with `logread -f`.
# Status # Status
This is more of a template than something standalone, but I use it for This is more of a template than something standalone, but I use it for
my home routers as is. For more specific applications you most my home routers as is. You most
probably want to customize this script here and there; search for probably want to customize this script here and there; search for
`CUSTOMIZE` for places of interest. `CUSTOMIZE` for places of interest.
Most importantly, **set up a password and maybe add your ssh key** by Most importantly, **set up a password and maybe an ssh key**.
adding it to `image-extras/common/etc/dropbear/authorized_keys`.
None of this script is hardware specific except `setLedAttribute`, At the time of writing it only supports a few `ar71xx` routers out of the box,
which is used to provide feedback about the progress of the initial but it's easy to extend it. Support for a new router entails looking up
setup phase. At the time of writing it only works on a few routers some led names for setLedAttribute for the user feedback through the blinking of
(mostly `ath79` ones), but without this everything should work fine, the leds. It should work fine without that, but it will be less convenient to
if only a bit less convenient. interact with your router in the initial setup phase.
# Troubleshooting # Troubleshooting
## Which file should I flash? ## Which file should I flash?
You should consult the [OpenWrt documentation](https://openwrt.org/docs/guide-user/start). You should consult the [OpenWRT documentation](https://openwrt.org/docs/guide-user/start).
The produced firmware files should be somewhere around The produced firmware files should be somewhere around
```./build/openwrt-imagebuilder-21.02.0-ath79-generic.Linux-x86_64/bin/targets/ath79/generic/```. ```build/openwrt-imagebuilder-17.01.4-ar71xx-generic.Linux-x86_64/bin/ar71xx```.
In short: In short:
* You need a file with the name ```-factory.bin``` or ```-sysupgrade.bin```. The former is to * You need a file with the name ```-factory.bin``` or ```-sysupgrade.bin```. The former is to
be used when you first install OpenWrt, the latter is when you upgrade an already installed be used when you first install OpenWRT, the latter is when you upgrade an already installed
OpenWrt. OpenWRT.
* You must carefully pick the proper firmware file for your **hardware version**! I advise you * You must carefully pick the proper firmware file for your **hardware version**! I advise you
to look up the wiki page for your hardware on the [OpenWrt wiki](https://openwrt.org), to look up the wiki page for your hardware on the [OpenWRT wiki](https://openwrt.org),
because most of them have a table of the released hardware versions with comments on their because most of them have a table of the released hardware versions with comments on their
status (sometimes new hardware revisions are only supported by the latest OpenWrt, which is status (sometimes new hardware revisions are only supported by the latest OpenWRT, which is
not released yet). not released yet).
## Help! The build has finished but there's no firmware file! ## Help! The build has finished but there's no firmware file!
If the build doesn't yield a firmware file (```*-factory.bin``` and/or ```*-sysupgrade.bin```): If the build doesn't yield a firmware file (```*-factory.bin``` and/or ```*-sysupgrade.bin```):
when there's not enough space in the flash memory of the target device to install everything when there's not enough space in the flash memory of the target device to install everything
then the OpenWrt ImageBuilder prints a hardly visible error into its flow of output and then the OpenWRT ImageBuilder prints a hardly visible error into its flow of output and
silently continues. Look into [build.sh](build.sh#L31) and try to remove some packages silently continues. Look into [build.sh](build.sh#L31) and try to remove some packages
that you can live without. that you can live without.
## Extroot is not mounted after a `sysupgrade`
In short, this is an OpenWrt issue, and the solution is to mount the extroot
somewhere, and delete `/etc/.extroot-uuid`. More details are available in
[this issue](https://github.com/attila-lendvai/openwrt-auto-extroot/issues/12),
and a way to deal with it can be found in
[this blog post](https://blog.mbirth.de/archives/2014/05/26/openwrt-sysupgrade-with-extroot.html).
You may also want to check out the
[official OpenWrt wiki](https://openwrt.org/docs/guide-user/additional-software/extroot_configuration#system_upgrade)
on this topic.

View File

@@ -1,8 +1,4 @@
#!/usr/bin/env bash #!/bin/sh
# Note: this runs as-is, pretty much without external
# dependencies. The OpenWrt ImageBuilder contains the toolchain and
# everything that is needed to build the firmware images.
set -e set -e
@@ -10,13 +6,13 @@ TARGET_ARCHITECTURE=$1
TARGET_VARIANT=$2 TARGET_VARIANT=$2
TARGET_DEVICE=$3 TARGET_DEVICE=$3
BUILD="$(dirname "${0}")/build/" BUILD=`dirname "$0"`"/build/"
BUILD="$(readlink -f "${BUILD}")" BUILD=`readlink -f $BUILD`
### ###
### chose a release ### chose a release
### ###
RELEASE="22.03.5" RELEASE="19.07.9"
IMGBUILDER_NAME="openwrt-imagebuilder-${RELEASE}-${TARGET_ARCHITECTURE}-${TARGET_VARIANT}.Linux-x86_64" IMGBUILDER_NAME="openwrt-imagebuilder-${RELEASE}-${TARGET_ARCHITECTURE}-${TARGET_VARIANT}.Linux-x86_64"
IMGBUILDER_DIR="${BUILD}/${IMGBUILDER_NAME}" IMGBUILDER_DIR="${BUILD}/${IMGBUILDER_NAME}"
@@ -30,20 +26,18 @@ IMGBUILDERURL="https://downloads.openwrt.org/releases/${RELEASE}/targets/${TARGE
if [ -z ${TARGET_DEVICE} ]; then if [ -z ${TARGET_DEVICE} ]; then
echo "Usage: $0 architecture variant device-profile" echo "Usage: $0 architecture variant device-profile"
echo " e.g.: $0 ath79 generic tplink_tl-wr1043nd-v1" echo " e.g.: $0 ar71xx generic tplink_tl-wr1043nd-v1"
echo " $0 ath79 generic tplink_archer-c6-v2" echo " $0 ath79 generic tplink_archer-c6-v2"
echo " $0 ath79 generic tplink_tl-wdr4300-v1" echo " $0 bcm53xx generic dlink-dir-885l"
echo " $0 bcm53xx generic dlink_dir-885l" echo " (this last one will not work without editing build.sh, details: https://github.com/attila-lendvai/openwrt-auto-extroot/pull/15#issuecomment-405847440)"
echo " to get a list of supported devices issue a 'make info' in the OpenWRT image builder directory:" echo " to get a list of supported devices issue a 'make info' in the OpenWRT image builder directory:"
echo " '${IMGBUILDER_DIR}'" echo " '${IMGBUILDER_DIR}'"
echo " the build results will be under '${IMGBUILDER_DIR}/bin/targets/'"
kill -INT $$ kill -INT $$
fi fi
# the absolute minimum for extroot to work at all (i.e. when the disk is already set up, for example by hand). # the absolute minimum for extroot to work at all (i.e. when the disk is already set up, for example by hand).
# this list may be smaller and/or different for your router, but it works with my ath79. # this list may be smaller and/or different for your router, but it works with my ar71xx.
# blockdev is needed to re-read the partition table using `blockdev --rereadpt /dev/sdX` PREINSTALLED_PACKAGES="block-mount kmod-usb2 kmod-usb-storage kmod-fs-ext4"
PREINSTALLED_PACKAGES="block-mount kmod-fs-ext4 kmod-usb-storage blockdev"
# some kernel modules may also be needed for your hardware # some kernel modules may also be needed for your hardware
#PREINSTALLED_PACKAGES+=" kmod-usb-uhci kmod-usb-ohci" #PREINSTALLED_PACKAGES+=" kmod-usb-uhci kmod-usb-ohci"
@@ -52,41 +46,37 @@ PREINSTALLED_PACKAGES="block-mount kmod-fs-ext4 kmod-usb-storage blockdev"
PREINSTALLED_PACKAGES+=" blkid mount-utils swap-utils e2fsprogs fdisk" PREINSTALLED_PACKAGES+=" blkid mount-utils swap-utils e2fsprogs fdisk"
# the following packages are optional, feel free to (un)comment them # the following packages are optional, feel free to (un)comment them
PREINSTALLED_PACKAGES+=" wireless-tools firewall4" PREINSTALLED_PACKAGES+=" wireless-tools firewall iptables"
PREINSTALLED_PACKAGES+=" kmod-usb-storage-extras kmod-mmc" PREINSTALLED_PACKAGES+=" kmod-usb-storage-extras kmod-mmc"
PREINSTALLED_PACKAGES+=" ppp ppp-mod-pppoe ppp-mod-pppol2tp ppp-mod-pptp kmod-ppp kmod-pppoe" PREINSTALLED_PACKAGES+=" ppp ppp-mod-pppoe ppp-mod-pppol2tp ppp-mod-pptp kmod-ppp kmod-pppoe"
PREINSTALLED_PACKAGES+=" luci" PREINSTALLED_PACKAGES+=" luci"
# you exclude packages with this to shrink the image for mkdir -pv ${BUILD}
# routers with smaller flash storage.
# SAVE_SPACE_PACKAGES=" -ppp -ppp-mod-pppoe -ip6tables -odhcp6c -kmod-ipv6 -kmod-ip6tables -ath10k"
SAVE_SPACE_PACKAGES=""
PREINSTALLED_PACKAGES+=${SAVE_SPACE_PACKAGES} rm -rf $IMGTEMPDIR
cp -r image-extras/common/ $IMGTEMPDIR
mkdir -pv "${BUILD}" PER_PLATFORM_IMAGE_EXTRAS=image-extras/${TARGET_DEVICE}/
if [ -e $PER_PLATFORM_IMAGE_EXTRAS ]; then
rm -rf "${IMGTEMPDIR}" rsync -pr $PER_PLATFORM_IMAGE_EXTRAS $IMGTEMPDIR/
cp -r image-extras/common/ "${IMGTEMPDIR}"
PER_PLATFORM_IMAGE_EXTRAS="image-extras/${TARGET_DEVICE}/"
if [ -e "${PER_PLATFORM_IMAGE_EXTRAS}" ]; then
rsync -pr "${PER_PLATFORM_IMAGE_EXTRAS}" "${IMGTEMPDIR}/"
fi fi
if [ ! -e "${IMGBUILDER_DIR}" ]; then if [ ! -e ${IMGBUILDER_DIR} ]; then
pushd "${BUILD}" pushd ${BUILD}
# --no-check-certificate if needed # --no-check-certificate if needed
wget --continue "${IMGBUILDERURL}" wget --continue ${IMGBUILDERURL}
xz -d <"${IMGBUILDER_ARCHIVE}" | tar vx xz -d <${IMGBUILDER_ARCHIVE} | tar vx
popd popd
fi fi
pushd "${IMGBUILDER_DIR}" pushd ${IMGBUILDER_DIR}
# Without this the image builder fails.
export SOURCE_DATE_EPOCH=$(git show -s --format=%ct HEAD)
make image PROFILE=${TARGET_DEVICE} PACKAGES="${PREINSTALLED_PACKAGES}" FILES=${IMGTEMPDIR} make image PROFILE=${TARGET_DEVICE} PACKAGES="${PREINSTALLED_PACKAGES}" FILES=${IMGTEMPDIR}
pushd "bin/targets/${TARGET_ARCHITECTURE}/" pushd bin/targets/${TARGET_ARCHITECTURE}/
ln -sf ../../../packages . ln -s ../../../packages .
popd popd
popd popd

View File

@@ -10,42 +10,33 @@ rootUUID=05d615b3-bef8-460c-9a23-52db8d09e000
dataUUID=05d615b3-bef8-460c-9a23-52db8d09e001 dataUUID=05d615b3-bef8-460c-9a23-52db8d09e001
swapUUID=05d615b3-bef8-460c-9a23-52db8d09e002 swapUUID=05d615b3-bef8-460c-9a23-52db8d09e002
. /lib/functions.sh if [ -f /lib/ar71xx.sh ]; then
. /lib/ar71xx.sh
# let's attempt to define some defaults... # let's attempt to define some defaults...
autoprovisionUSBLed="green:usb" autoprovisionUSBLed="tp-link:green:usb"
autoprovisionStatusLed="green:qss" autoprovisionStatusLed="tp-link:green:qss"
echo Board name is [$(board_name)]
# CUSTOMIZE
case $(board_name) in
*tl-wr1043nd*)
autoprovisionUSBLed="green:usb"
autoprovisionStatusLed="green:qss"
;;
*tl-mr3020*)
autoprovisionUSBLed="green:wps"
autoprovisionStatusLed="green:wlan"
;;
*tl-wr2543n*)
autoprovisionUSBLed="green:wps"
autoprovisionStatusLed="green:wlan5g"
;;
*tl-wdr3600* | *tl-wdr4300*)
autoprovisionUSBLed="green:wlan2g"
autoprovisionStatusLed="green:wlan5g"
;;
*mynet-n750*)
autoprovisionUSBLed="blue:wps"
autoprovisionStatusLed="blue:wireless"
;;
*archer-c7-v1*)
autoprovisionUSBLed="green:wlan2g"
autoprovisionStatusLed="green:wlan5g"
;;
esac
# CUSTOMIZE
case $(ar71xx_board_name) in
"tl-wr1043nd")
autoprovisionUSBLed="tp-link:green:usb"
autoprovisionStatusLed="tp-link:green:qss"
;;
"tl-mr3020")
autoprovisionUSBLed="tp-link:green:wps"
autoprovisionStatusLed="tp-link:green:wlan"
;;
"tl-wr2543n")
autoprovisionUSBLed="tp-link:green:wps"
autoprovisionStatusLed="tp-link:green:wlan5g"
;;
"tl-wdr4300")
autoprovisionUSBLed="tp-link:blue:wan"
autoprovisionStatusLed="tp-link:blue:qss"
;;
esac
fi
log() log()
{ {

View File

@@ -23,7 +23,7 @@ getPendriveSize()
hasBigEnoughPendrive() hasBigEnoughPendrive()
{ {
local size=$(getPendriveSize) local size=$(getPendriveSize)
if [ $size -ge 100000 ]; then if [ $size -ge 600000 ]; then
log "Found a pendrive of size: $(($size / 2 / 1024)) MB" log "Found a pendrive of size: $(($size / 2 / 1024)) MB"
return 0 return 0
else else
@@ -31,24 +31,14 @@ hasBigEnoughPendrive()
fi fi
} }
rereadPartitionTable()
{
log "Rereading partition table"
blockdev --rereadpt /dev/sda
}
setupPendrivePartitions() setupPendrivePartitions()
{ {
log "Erasing partition table"
# erase partition table # erase partition table
dd if=/dev/zero of=/dev/sda bs=1k count=256 dd if=/dev/zero of=/dev/sda bs=1k count=256
rereadPartitionTable
log "Creating partitions"
# sda1 is 'swap' # sda1 is 'swap'
# sda2 is 'root' # sda2 is 'root'
# sda3 is 'data', if there's any space left # sda3 is 'data'
fdisk /dev/sda <<EOF fdisk /dev/sda <<EOF
o o
n n
@@ -74,7 +64,7 @@ q
EOF EOF
log "Finished partitioning /dev/sda using fdisk" log "Finished partitioning /dev/sda using fdisk"
rereadPartitionTable sleep 2
until [ -e /dev/sda1 ] until [ -e /dev/sda1 ]
do do
@@ -83,8 +73,8 @@ EOF
done done
mkswap -L swap -U $swapUUID /dev/sda1 mkswap -L swap -U $swapUUID /dev/sda1
mkfs.ext4 -F -L root -U $rootUUID /dev/sda2 mkfs.ext4 -L root -U $rootUUID /dev/sda2
mkfs.ext4 -F -L data -U $dataUUID /dev/sda3 mkfs.ext4 -L data -U $dataUUID /dev/sda3
log "Finished setting up filesystems" log "Finished setting up filesystems"
} }

View File

@@ -9,11 +9,9 @@ installPackages()
signalAutoprovisionWaitingForUser signalAutoprovisionWaitingForUser
until (opkg update) until (opkg update)
do do
log "opkg update failed. No internet connection? Retrying in 15 seconds..." log "opkg update failed. No internet connection? Retrying in 15 seconds..."
sleep 15 sleep 15
# Initiate a synchronous time update.
ntpd -d -q -n -p openwrt.pool.ntp.org
done done
signalAutoprovisionWorking signalAutoprovisionWorking
@@ -32,12 +30,12 @@ installPackages()
# CUSTOMIZE # CUSTOMIZE
# install some more packages that don't need any extra steps # install some more packages that don't need any extra steps
opkg install lua luci ppp-mod-pppoe screen mc unzip logrotate opkg install lua luci ppp-mod-pppoe screen mc zip unzip logrotate
# this is needed for the vlans on tp-link 3020 with only a single hw ethernet port # this is needed for the vlans on tp-link 3020 with only a single hw ethernet port
opkg install kmod-macvlan ip opkg install kmod-macvlan ip
# just in case if we were run in a firmware that didn't already have luci # just in case if we were run in a firmware that didn't already had luci
/etc/init.d/uhttpd enable /etc/init.d/uhttpd enable
} }
@@ -52,10 +50,6 @@ autoprovisionStage2()
else else
signalAutoprovisionWorking signalAutoprovisionWorking
log "Starting ntpd to update system time; otherwise the openwrt.org certificates are rejected as not yet valid."
# Added -l hoping that it may help against ntpd quitting.
ntpd -l -N -p openwrt.pool.ntp.org
# CUSTOMIZE: with an empty argument it will set a random password and only ssh key based login will work. # CUSTOMIZE: with an empty argument it will set a random password and only ssh key based login will work.
# please note that stage2 requires internet connection to install packages and you most probably want to log in # please note that stage2 requires internet connection to install packages and you most probably want to log in
# on the GUI to set up a WAN connection. but on the other hand you don't want to end up using a publically # on the GUI to set up a WAN connection. but on the other hand you don't want to end up using a publically

26
manifest.scm Normal file
View File

@@ -0,0 +1,26 @@
;; This is the complete list of Guix packages necessary for building.
;;
;; The following shell command will run the tests:
;;
;; guix shell -m manifest.scm --pure -- ./build.sh ath79 generic tplink_tl-wdr4300-v1
;;
;; TODO ...ideally. some dependencies are not listed, and it fails when using --pure
;;
;; Quircks on Guix: the check for git fails, must edit
;; build/openwrt-imagebuilder-19.07.9-ath79-generic.Linux-x86_64/include/prereq-build.mk
;; and comment out the git check.
;;
(specifications->manifest
'("coreutils"
"bash"
"make"
"perl"
"python2"
"gcc-toolchain"
"git"
"git:gui"
;; "man-pages"
"less"
"time"))