├── .gitignore
├── LICENSE
├── README.md
├── build.sh
├── default.nix
├── image-extras
├── TLMR3020
│ └── etc
│ │ └── config
│ │ └── placeholder
└── common
│ ├── etc
│ ├── config
│ │ └── fstab
│ ├── dropbear
│ │ └── .gitignore
│ ├── logrotate.d
│ │ └── syslog.conf
│ └── rc.local
│ └── root
│ ├── autoprovision-functions.sh
│ ├── autoprovision-stage1.sh
│ └── autoprovision-stage2.sh
└── manifest.scm
/.gitignore:
--------------------------------------------------------------------------------
1 | notes.txt
2 | build/
3 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2014 Attila Lendvai
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
23 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # What
2 |
3 | It's a script to build a customized
4 | [OpenWrt](https://openwrt.org/docs/guide-user/start)
5 | firmware image using
6 | [ImageBuilder](https://openwrt.org/docs/guide-user/additional-software/imagebuilder).
7 |
8 | If the generated image is flashed on a router, then during its boot
9 | process it will try to set up
10 | [extroot](https://openwrt.org/docs/guide-user/additional-software/extroot_configuration)
11 | on **any (!)** storage device plugged into the USB port. Put another
12 | way, it unconditionally reformats `/dev/sda` if it fails to mount an
13 | extroot early in the boot process.
14 |
15 | # Why
16 |
17 | So that e.g. customers can buy a router on their own, download and flash our custom
18 | firmware, plug in a pendrive, and manage their SIP (telephony) node
19 | from our webapp.
20 |
21 | I've extracted the generic parts from the above mentioned auto-provision
22 | project because I thought it's useful enough for making it public.
23 |
24 | It also serves me well on my own routers ever since then.
25 |
26 | # How
27 |
28 | You can read more about the underlying technology on the OpenWrt wiki: see e.g. the
29 | [ImageBuilder](https://openwrt.org/docs/guide-user/additional-software/imagebuilder)
30 | page, or the page that lists some other
31 | [ImageBuilder frontends](https://openwrt.org/docs/guide-developer/imagebuilder_frontends).
32 |
33 | As for the actual mechanism: custom scripts are baked into the boot
34 | process of the flashed firmware. If the extroot overlay is properly
35 | set up, then these scripts get hidden by it; i.e. they will only be run
36 | when the extroot has failed to mount early in the boot process.
37 |
38 | Keep in mind that **this will automatically erase/format any inserted
39 | storage device while the router is in the initial setup phase**!
40 | Unfortunately there's little that can be done at that point to ask the
41 | user for confirmation.
42 |
43 | ### Building
44 |
45 | OpenWrt's ImageBuilder only works on Linux x86_64. To build a firmware, issue the following command:
46 | `./build.sh architecture variant device-profile`, e.g.:
47 |
48 | * `./build.sh ath79 generic tplink_tl-wr1043nd-v1`
49 | * `./build.sh ath79 generic tplink_archer-c6-v2`
50 | * `./build.sh ath79 generic tplink_tl-wdr4300-v1`
51 | * `./build.sh bcm53xx generic dlink_dir-885l`
52 |
53 | Results will be under `build/openwrt-imagebuilder-${release}-${architecture}-${variant}.Linux-x86_64/bin/`.
54 |
55 | To see a list of available targets, run `make info` in the ImageBuilder dir.
56 |
57 | If you want to change which OpenWrt version is used, then try editing
58 | the relevant variable(s) in `build.sh`. It's not guaranteed to work
59 | across OpenWrt releases, therefore we keep git branches for the past
60 | releases.
61 |
62 | ### Setup stages
63 |
64 | Blinking leds show which phase the extroot setup scripts are in. Consult the
65 | sources for details: [autoprovision-functions.sh](image-extras/common/root/autoprovision-functions.sh#L49).
66 |
67 | #### Stage 1: setup extroot
68 |
69 | When the custom firmware first boots, the autoprovision script will
70 | wait for anything (!) in `/dev/sda` to show up (that is >= 512M), then erase
71 | it and set up a `swap`, an `extroot`, and a `data`filesystem (for the remaining
72 | space), and then reboot.
73 |
74 | #### Stage 2: download and install some packages from the internet
75 |
76 | Once it rebooted into the new extroot, it will continuously keep trying to install
77 | some OpenWrt packages until an internet connection is set up on the router. You
78 | need to do that manually either by using ssh or the web UI (LuCI).
79 |
80 | #### Stage 3, optional
81 |
82 | We also have a 3rd stage, written in Python, but it's commented out here.
83 | Search for `autoprovision-stage3.py` to see how it's done.
84 |
85 | ### Login
86 |
87 | After flashing the firmware the router will have the standard
88 | `192.168.1.1` IP address.
89 |
90 | By default the root passwd is not set, so the router will start telnet with
91 | no password. If you want to set up a password, then edit the stage 2 script:
92 | [autoprovision-stage2.sh](image-extras/common/root/autoprovision-stage2.sh#L53).
93 |
94 | If a password is set, then telnet is disabled by OpenWrt and SSH will listen
95 | using the keys specified in [authorized_keys](image-extras/common/etc/dropbear/authorized_keys).
96 |
97 | Once connected, you can read the log with `logread -f`.
98 |
99 | ### Upgrading
100 |
101 | I have kinda succeeded to upgrade an installation from `24.10.0-rc4`
102 | to `24.10.1` using the following steps:
103 |
104 |
105 |
106 | - build a new image.bin using openwrt-auto-extroot: `./build.sh ath79 generic tplink_tl-wdr4300-v1`
107 |
108 | - `scp image.bin root@router.lan:/tmp/`
109 |
110 | - `sysupgrage -c -o /tmp/image.bin`
111 |
112 | - the new version came back online (into a non-trivial network setup
113 | with vlans!)
114 |
115 | - Edit the version of the `kernel` package in the opkg database: `nano
116 | /usr/lib/opkg/status` and edit the entry for `Package: kernel`:
117 | update the version to the new one,
118 | `6.6.86~64576e1418bd4546fdb49285deb3b11c-r1` in this case. I looked
119 | up the new version by `find . | grep kernel` in the ImageBuilder
120 | directory. Without this step the `kmod-*` packages fail to upgrade
121 | due to the missing kernel dependency. The kernel package itself is
122 | not listed in the opkg package database, because you need to use
123 | sysupgrade to update the kernel.
124 |
125 | - `opkg update`
126 |
127 | - `opkg list-upgradable | cut -f 1 -d ' ' | xargs -r opkg upgrade`
128 |
129 | - ?! somehow once the extroot disappeared (got unmounted?), but then
130 | it came back after a reboot.
131 |
132 | - most things worked fine, but e.g. usteer failed to start (`Command
133 | failed: Request timed out`), and opkg was printing strange errors
134 | (`* pkg_get_installed_files: Failed to open
135 | //usr/lib/opkg/info/libuci20130104.list: No such file or
136 | directory.`).
137 |
138 | - At this point I have decided to reinstall the router using my uci
139 | based script. Patches are welcome for the upgrade instructions.
140 |
141 |
142 | # Status
143 |
144 | This is more of a template than something standalone, but I use it for
145 | my home routers as is for years now. For more specific applications
146 | you most probably want to customize this script here and there; search
147 | for `CUSTOMIZE` for places of interest.
148 |
149 | Most importantly, **set up a password and maybe add your ssh key** by
150 | adding it to `image-extras/common/etc/dropbear/authorized_keys`.
151 |
152 | None of this script is hardware specific except `setLedAttribute`,
153 | which is used to provide feedback about the progress of the initial
154 | setup phase. At the time of writing it only works on a few routers
155 | (mostly `ath79` ones), but without this everything should work fine,
156 | if only a bit less convenient.
157 |
158 | # Troubleshooting
159 |
160 | ## Which file should I flash?
161 |
162 | You should consult the [OpenWrt documentation](https://openwrt.org/docs/guide-user/start).
163 | The produced firmware files should be somewhere around
164 | ```./build/openwrt-imagebuilder-21.02.0-ath79-generic.Linux-x86_64/bin/targets/ath79/generic/```.
165 |
166 | In short:
167 |
168 | * You need a file with the name ```-factory.bin``` or ```-sysupgrade.bin```. The former is to
169 | be used when you first install OpenWrt, the latter is when you upgrade an already installed
170 | OpenWrt.
171 |
172 | * You must carefully pick the proper firmware file for your **hardware version**! I advise you
173 | to look up the wiki page for your hardware on the [OpenWrt wiki](https://openwrt.org),
174 | because most of them have a table of the released hardware versions with comments on their
175 | status (sometimes new hardware revisions are only supported by the latest OpenWrt, which is
176 | not released yet).
177 |
178 | ## Help! The build has finished but there's no firmware file!
179 |
180 | If the build doesn't yield a firmware file (```*-factory.bin``` and/or ```*-sysupgrade.bin```):
181 | when there's not enough space in the flash memory of the target device to install everything
182 | then the OpenWrt ImageBuilder prints a hardly visible error into its flow of output and
183 | silently continues. Look into [build.sh](build.sh#L31) and try to remove some packages
184 | that you can live without.
185 |
186 | ## Extroot is not mounted after a `sysupgrade`
187 |
188 | In short, this is an OpenWrt issue, and the solution is to mount the extroot
189 | somewhere, and delete `/etc/.extroot-uuid`. More details are available in
190 | [this issue](https://github.com/attila-lendvai/openwrt-auto-extroot/issues/12),
191 | and a way to deal with it can be found in
192 | [this blog post](https://blog.mbirth.de/archives/2014/05/26/openwrt-sysupgrade-with-extroot.html).
193 | You may also want to check out the
194 | [official OpenWrt wiki](https://openwrt.org/docs/guide-user/additional-software/extroot_configuration#system_upgrade)
195 | on this topic.
196 |
--------------------------------------------------------------------------------
/build.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | # Note: this runs as-is, pretty much without external
4 | # dependencies. The OpenWrt ImageBuilder contains the toolchain and
5 | # everything that is needed to build the firmware images.
6 |
7 | set -e
8 |
9 | TARGET_ARCHITECTURE=$1
10 | TARGET_VARIANT=$2
11 | TARGET_DEVICE=$3
12 |
13 | BUILD="$(dirname "${0}")/build/"
14 | BUILD="$(readlink -f "${BUILD}")"
15 |
16 | ###
17 | ### chose a release
18 | ###
19 | RELEASE="24.10.1"
20 |
21 | IMGBUILDER_NAME="openwrt-imagebuilder-${RELEASE}-${TARGET_ARCHITECTURE}-${TARGET_VARIANT}.Linux-x86_64"
22 | IMGBUILDER_DIR="${BUILD}/${IMGBUILDER_NAME}"
23 | IMGBUILDER_ARCHIVE="${IMGBUILDER_NAME}.tar.zst"
24 |
25 | IMGTEMPDIR="${BUILD}/image-extras"
26 | # see this feature request:
27 | # FS#1670 - consistent naming convention for the imagebuilder.tar.xz URL
28 | # https://bugs.openwrt.org/index.php?do=details&task_id=1670
29 | IMGBUILDERURL="https://downloads.openwrt.org/releases/${RELEASE}/targets/${TARGET_ARCHITECTURE}/${TARGET_VARIANT}/${IMGBUILDER_ARCHIVE}"
30 |
31 | if [ -z ${TARGET_DEVICE} ]; then
32 | echo "Usage: $0 architecture variant device-profile"
33 | echo " e.g.: $0 ath79 generic tplink_tl-wr1043nd-v1"
34 | echo " $0 ath79 generic tplink_archer-c6-v2"
35 | echo " $0 ath79 generic tplink_tl-wdr4300-v1"
36 | echo " $0 bcm53xx generic dlink_dir-885l"
37 | echo " to get a list of supported devices issue a 'make info' in the OpenWRT image builder directory:"
38 | echo " '${IMGBUILDER_DIR}'"
39 | echo " the build results will be under '${IMGBUILDER_DIR}/bin/targets/'"
40 | kill -INT $$
41 | fi
42 |
43 | # the absolute minimum for extroot to work at all (i.e. when the disk is already set up, for example by hand).
44 | # this list may be smaller and/or different for your router, but it works with my ath79.
45 | # blockdev is needed to re-read the partition table using `blockdev --rereadpt /dev/sdX`
46 | PREINSTALLED_PACKAGES="block-mount kmod-fs-ext4 kmod-usb-storage blockdev"
47 |
48 | # some kernel modules may also be needed for your hardware
49 | #PREINSTALLED_PACKAGES+=" kmod-usb-uhci kmod-usb-ohci"
50 |
51 | # these are needed for the proper functioning of the auto extroot scripts
52 | PREINSTALLED_PACKAGES+=" blkid mount-utils swap-utils e2fsprogs fdisk"
53 |
54 | # the following packages are optional, feel free to (un)comment them
55 | PREINSTALLED_PACKAGES+=" firewall4"
56 | #PREINSTALLED_PACKAGES+=" wireless-tools"
57 | #PREINSTALLED_PACKAGES+=" kmod-usb-storage-extras kmod-mmc"
58 | #PREINSTALLED_PACKAGES+=" ppp ppp-mod-pppoe ppp-mod-pppol2tp ppp-mod-pptp kmod-ppp kmod-pppoe"
59 | PREINSTALLED_PACKAGES+=" luci"
60 |
61 | # you exclude packages with this to shrink the image for
62 | # routers with smaller flash storage.
63 | # SAVE_SPACE_PACKAGES=" -ppp -ppp-mod-pppoe -ip6tables -odhcp6c -kmod-ipv6 -kmod-ip6tables -ath10k"
64 | SAVE_SPACE_PACKAGES=""
65 |
66 | PREINSTALLED_PACKAGES+=${SAVE_SPACE_PACKAGES}
67 |
68 | mkdir -pv "${BUILD}"
69 |
70 | rm -rf "${IMGTEMPDIR}"
71 | cp -r image-extras/common/ "${IMGTEMPDIR}"
72 | PER_PLATFORM_IMAGE_EXTRAS="image-extras/${TARGET_DEVICE}/"
73 | if [ -e "${PER_PLATFORM_IMAGE_EXTRAS}" ]; then
74 | rsync -pr "${PER_PLATFORM_IMAGE_EXTRAS}" "${IMGTEMPDIR}/"
75 | fi
76 |
77 | if [ ! -e "${IMGBUILDER_DIR}" ]; then
78 | pushd "${BUILD}"
79 | # --no-check-certificate if needed
80 | wget --continue "${IMGBUILDERURL}"
81 | zstd --decompress <"${IMGBUILDER_ARCHIVE}" | tar vx
82 | popd
83 | fi
84 |
85 | pushd "${IMGBUILDER_DIR}"
86 |
87 | make image PROFILE=${TARGET_DEVICE} PACKAGES="${PREINSTALLED_PACKAGES}" FILES=${IMGTEMPDIR}
88 |
89 | pushd "bin/targets/${TARGET_ARCHITECTURE}/"
90 | ln -sf ../../../packages .
91 | popd
92 |
93 | popd
94 |
--------------------------------------------------------------------------------
/default.nix:
--------------------------------------------------------------------------------
1 | { pkgs ? import {} }:
2 |
3 | pkgs.mkShell {
4 | buildInputs = with pkgs; [
5 | coreutils posix_man_pages bash-completion less
6 | gitFull diffutils
7 | gnumake which
8 | ncurses perl python2 python3
9 |
10 | # keep this line if you use bash
11 | bashInteractive
12 | ];
13 |
14 | shellHook =
15 | ''
16 | alias ..='cd ..'
17 | alias ...='cd ../..'
18 | '';
19 | }
20 |
--------------------------------------------------------------------------------
/image-extras/TLMR3020/etc/config/placeholder:
--------------------------------------------------------------------------------
1 | # this is just a file to show how platform specific image extras can be specified
2 |
--------------------------------------------------------------------------------
/image-extras/common/etc/config/fstab:
--------------------------------------------------------------------------------
1 | config global
2 | option anon_swap '0'
3 | option anon_mount '0'
4 | option auto_swap '0'
5 | option auto_mount '0'
6 | option delay_root '3'
7 | option check_fs '0'
8 |
9 | config swap
10 | option uuid '05d615b3-bef8-460c-9a23-52db8d09e002'
11 | option enabled '1'
12 |
13 | config mount 'extroot'
14 | option target '/overlay'
15 | option uuid '05d615b3-bef8-460c-9a23-52db8d09e000'
16 | option fstype 'ext4'
17 | option options 'rw,noatime'
18 | option enabled '1'
19 | option enabled_fsck '0'
20 |
21 | config mount 'data'
22 | option target '/mnt/data'
23 | option uuid '05d615b3-bef8-460c-9a23-52db8d09e001'
24 | option fstype 'ext4'
25 | option options 'rw,noatime'
26 | option enabled '1'
27 | option enabled_fsck '0'
28 |
--------------------------------------------------------------------------------
/image-extras/common/etc/dropbear/.gitignore:
--------------------------------------------------------------------------------
1 | # you can put your ssh public key into authorized_keys,
2 | # but we don't ever want it to be committed to the repo
3 | authorized_keys
4 |
--------------------------------------------------------------------------------
/image-extras/common/etc/logrotate.d/syslog.conf:
--------------------------------------------------------------------------------
1 | /var/log/syslog
2 | {
3 | olddir archive
4 | rotate 30
5 | daily
6 | dateext
7 | notifempty
8 | missingok
9 | copytruncate
10 | }
11 |
--------------------------------------------------------------------------------
/image-extras/common/etc/rc.local:
--------------------------------------------------------------------------------
1 | # Put your custom commands here that should be executed once
2 | # the system init finished. By default this file does nothing.
3 |
4 | /root/autoprovision-stage1.sh
5 |
6 | exit 0
7 |
--------------------------------------------------------------------------------
/image-extras/common/root/autoprovision-functions.sh:
--------------------------------------------------------------------------------
1 | #!/bin/sh
2 |
3 | # utility functions for the various stages of autoprovisioning
4 |
5 | # make sure that installed packages take precedence over busybox. see https://dev.openwrt.org/ticket/18523
6 | PATH="/usr/bin:/usr/sbin:/bin:/sbin"
7 |
8 | # these are also copy-pasted into other scripts and config files!
9 | rootUUID=05d615b3-bef8-460c-9a23-52db8d09e000
10 | dataUUID=05d615b3-bef8-460c-9a23-52db8d09e001
11 | swapUUID=05d615b3-bef8-460c-9a23-52db8d09e002
12 |
13 | . /lib/functions.sh
14 |
15 | # let's attempt to define some defaults...
16 | autoprovisionUSBLed="green:usb"
17 | autoprovisionStatusLed="green:qss"
18 |
19 | echo Board name is [$(board_name)]
20 |
21 | # CUSTOMIZE
22 | case $(board_name) in
23 | *tl-wr1043nd*)
24 | autoprovisionUSBLed="green:usb"
25 | autoprovisionStatusLed="green:qss"
26 | ;;
27 | *tl-mr3020*)
28 | autoprovisionUSBLed="green:wps"
29 | autoprovisionStatusLed="green:wlan"
30 | ;;
31 | *tl-wr2543n*)
32 | autoprovisionUSBLed="green:wps"
33 | autoprovisionStatusLed="green:wlan5g"
34 | ;;
35 | *tl-wdr3600* | *tl-wdr4300*)
36 | autoprovisionUSBLed="green:wlan2g"
37 | autoprovisionStatusLed="green:wlan5g"
38 | ;;
39 | *mynet-n750*)
40 | autoprovisionUSBLed="blue:wps"
41 | autoprovisionStatusLed="blue:wireless"
42 | ;;
43 | *archer-c7-v1*)
44 | autoprovisionUSBLed="green:wlan2g"
45 | autoprovisionStatusLed="green:wlan5g"
46 | ;;
47 | esac
48 |
49 |
50 | log()
51 | {
52 | /usr/bin/logger -t autoprov -s $*
53 | }
54 |
55 | setLedAttribute()
56 | {
57 | [ -f "/sys/class/leds/$1/$2" ] && echo "$3" > "/sys/class/leds/$1/$2"
58 | }
59 |
60 | signalAutoprovisionWorking()
61 | {
62 | setLedAttribute ${autoprovisionStatusLed} trigger none
63 | setLedAttribute ${autoprovisionStatusLed} trigger timer
64 | setLedAttribute ${autoprovisionStatusLed} delay_on 2000
65 | setLedAttribute ${autoprovisionStatusLed} delay_off 2000
66 | }
67 |
68 | signalAutoprovisionWaitingForUser()
69 | {
70 | setLedAttribute ${autoprovisionStatusLed} trigger none
71 | setLedAttribute ${autoprovisionStatusLed} trigger timer
72 | setLedAttribute ${autoprovisionStatusLed} delay_on 200
73 | setLedAttribute ${autoprovisionStatusLed} delay_off 300
74 | }
75 |
76 | signalWaitingForPendrive()
77 | {
78 | setLedAttribute ${autoprovisionUSBLed} trigger none
79 | setLedAttribute ${autoprovisionUSBLed} trigger timer
80 | setLedAttribute ${autoprovisionUSBLed} delay_on 200
81 | setLedAttribute ${autoprovisionUSBLed} delay_off 300
82 | }
83 |
84 | signalFormatting()
85 | {
86 | setLedAttribute ${autoprovisionUSBLed} trigger none
87 | setLedAttribute ${autoprovisionUSBLed} trigger timer
88 | setLedAttribute ${autoprovisionUSBLed} delay_on 1000
89 | setLedAttribute ${autoprovisionUSBLed} delay_off 1000
90 | }
91 |
92 | stopSignallingAnything()
93 | {
94 | # TODO this is wrong, they should be restored to their original state.
95 | # but then leds are only touched in the setup stage, which is ephemeral when things work as expected...
96 | setLedAttribute ${autoprovisionStatusLed} trigger none
97 | setLedAttribute ${autoprovisionUSBLed} trigger usbdev
98 | }
99 |
100 | setRootPassword()
101 | {
102 | local password=$1
103 | if [ "$password" == "" ]; then
104 | # set and forget a random password merely to disable telnet. login will go through ssh keys.
105 | password=$(/dev/null
14 | fi
15 |
16 | if (grep -q sda /proc/partitions) then
17 | cat /sys/block/sda/size
18 | else
19 | echo 0
20 | fi
21 | }
22 |
23 | hasBigEnoughPendrive()
24 | {
25 | local size=$(getPendriveSize)
26 | if [ $size -ge 100000 ]; then
27 | log "Found a pendrive of size: $(($size / 2 / 1024)) MB"
28 | return 0
29 | else
30 | return 1
31 | fi
32 | }
33 |
34 | rereadPartitionTable()
35 | {
36 | log "Rereading partition table"
37 | blockdev --rereadpt /dev/sda
38 | }
39 |
40 | setupPendrivePartitions()
41 | {
42 | log "Erasing partition table"
43 | # TODO find a way to keep the data partition/fs when already present.
44 | # erase partition table
45 | dd if=/dev/zero of=/dev/sda bs=1k count=256
46 |
47 | rereadPartitionTable
48 |
49 | log "Creating partitions"
50 | # sda1 is 'swap'
51 | # sda2 is 'root'
52 | # sda3 is 'data', if there's any space left
53 | fdisk /dev/sda <${overlay_root}/etc/rc.local < /tmp symlink in the new extroot, so that /var becomes persistent across reboots.
113 | # mkdir -p ${overlay_root}/var
114 | # KLUDGE: /var/state is assumed to be transient, so link it to tmp, see https://dev.openwrt.org/ticket/12228
115 | # cd ${overlay_root}/var
116 | # ln -s /tmp state
117 | # cd -
118 |
119 | disableStage1
120 |
121 | log "Finished setting up extroot"
122 | }
123 |
124 | disableStage1()
125 | {
126 | # FIXME it would be more future-proof to transform the rc.local file
127 | # instead of overwriting it.
128 | cat >/etc/rc.local <manifest
10 | '("coreutils"
11 | "bash"
12 | "make"
13 | "perl"
14 | "gcc-toolchain"
15 | "git"
16 | "git:gui"
17 | ;; "man-pages"
18 | "less"
19 | "time"))
20 |
--------------------------------------------------------------------------------