From 84bf08c3dcb53233b3eb2fbeda1694e423541b4c Mon Sep 17 00:00:00 2001 From: Attila Lendvai Date: Wed, 3 Dec 2014 00:31:57 +0100 Subject: [PATCH] initial. broken because it expects UUID support from mount which is not compiled in by default --- .gitignore | 1 + README.md | 6 +- build.sh | 46 ++++++ image-extras.TLMR3020/etc/config/network | 11 ++ image-extras/etc/config/fstab | 27 ++++ image-extras/etc/dropbear/authorized_keys | 1 + image-extras/etc/logrotate.d/syslog.conf | 10 ++ image-extras/etc/rc.local | 6 + image-extras/root/autoprovision-functions.sh | 93 ++++++++++++ image-extras/root/autoprovision-stage1.sh | 142 +++++++++++++++++++ image-extras/root/autoprovision-stage2.sh | 72 ++++++++++ 11 files changed, 412 insertions(+), 3 deletions(-) create mode 100644 .gitignore create mode 100755 build.sh create mode 100644 image-extras.TLMR3020/etc/config/network create mode 100644 image-extras/etc/config/fstab create mode 100644 image-extras/etc/dropbear/authorized_keys create mode 100644 image-extras/etc/logrotate.d/syslog.conf create mode 100644 image-extras/etc/rc.local create mode 100755 image-extras/root/autoprovision-functions.sh create mode 100755 image-extras/root/autoprovision-stage1.sh create mode 100755 image-extras/root/autoprovision-stage2.sh diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..567609b --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +build/ diff --git a/README.md b/README.md index a73c283..f4fbd25 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -openwrt-auto-extroot -==================== +* This is more of a template than something standalone -Use OpenWRT ImageBuilder to build a firmware that automatically formats and moves extroot to any inserted pendrive +I've extracted this from another project, but I think it's useful +enough for making it public. diff --git a/build.sh b/build.sh new file mode 100755 index 0000000..d24060c --- /dev/null +++ b/build.sh @@ -0,0 +1,46 @@ +#!/bin/bash + +absolutize () +{ + if [ ! -d "$1" ]; then + echo + echo "ERROR: '$1' doesn't exist or not a directory!" + exit -1 + fi + + pushd "$1" >/dev/null + echo `pwd` + popd >/dev/null +} + +TARGET_PLATFORM=$1 +BUILD=`dirname "$0"`"/build/" +BUILD=`absolutize $BUILD` +IMGTEMPDIR="${BUILD}/openwrt-build-image-extras" +IMGBUILDERDIR="${BUILD}/OpenWrt-ImageBuilder-ar71xx_generic-for-linux-x86_64" +IMGBUILDERURL="https://downloads.openwrt.org/barrier_breaker/14.07/ar71xx/generic/OpenWrt-ImageBuilder-ar71xx_generic-for-linux-x86_64.tar.bz2" + +mkdir --parents ${BUILD} + +rm -rf $IMGTEMPDIR +cp -r image-extras $IMGTEMPDIR +if [ -e image-extras.$TARGET_PLATFORM/ ]; then + rsync -pr image-extras.$TARGET_PLATFORM/ $IMGTEMPDIR/ +fi + +if [ ! -e ${IMGBUILDERDIR} ]; then + pushd ${BUILD} + wget --continue ${IMGBUILDERURL} + tar jvxf OpenWrt-ImageBuilder*.tar.bz2 + popd +fi + +pushd ${IMGBUILDERDIR} + +make image PROFILE=$TARGET_PLATFORM PACKAGES="wireless-tools firewall iptables fdisk blkid block-mount e2fsprogs kmod-fs-ext4 kmod-usb2 kmod-usb-uhci kmod-usb-ohci kmod-usb-storage kmod-usb-storage-extras luci kmod-mmc mount-utils ppp ppp-mod-pppoe ppp-mod-pppol2tp ppp-mod-pptp kmod-ppp kmod-pppoe" FILES=${IMGTEMPDIR} + +pushd bin/ar71xx/ +ln -s ../../packages . +popd + +popd diff --git a/image-extras.TLMR3020/etc/config/network b/image-extras.TLMR3020/etc/config/network new file mode 100644 index 0000000..7208bd1 --- /dev/null +++ b/image-extras.TLMR3020/etc/config/network @@ -0,0 +1,11 @@ + +config interface 'loopback' + option ifname 'lo' + option proto 'static' + option ipaddr '127.0.0.1' + option netmask '255.0.0.0' + +config interface 'lan' + option ifname 'eth0' + option type 'bridge' + option proto 'dhcp' diff --git a/image-extras/etc/config/fstab b/image-extras/etc/config/fstab new file mode 100644 index 0000000..ea1d80c --- /dev/null +++ b/image-extras/etc/config/fstab @@ -0,0 +1,27 @@ +config global 'automount' + option from_fstab '0' + option anon_mount '0' + +config global 'autoswap' + option from_fstab '0' + option anon_swap '0' + +config swap + option uuid '05d615b3-bef8-460c-9a23-52db8d09e002' + option enabled '1' + +config mount + option target '/overlay' + option uuid '05d615b3-bef8-460c-9a23-52db8d09e000' + option fstype 'ext4' + option options 'rw,noatime' + option enabled '1' + option enabled_fsck '0' + +config mount + option target '/mnt/data' + option uuid '05d615b3-bef8-460c-9a23-52db8d09e001' + option fstype 'ext4' + option options 'rw,noatime' + option enabled '1' + option enabled_fsck '0' diff --git a/image-extras/etc/dropbear/authorized_keys b/image-extras/etc/dropbear/authorized_keys new file mode 100644 index 0000000..e8e88d6 --- /dev/null +++ b/image-extras/etc/dropbear/authorized_keys @@ -0,0 +1 @@ +ssh-rsa AAAAB3NzaC1yc2EAAAABIwAAAQEAu9Nwb8tr91hvChHSjEbyS3P0c1+jKtKAdaFCRkyUjVwgCpuzDxiq0auuNulYIfD2oc+THJ6zymJUjWNrVipeUo8BmKkDSMgN0Qf5PlwcSiIj9vDbLqxmVnnvB6xGEROO215Y8XzMOgq8r3Z3WqRUZIeFDHC2sSwJKO3INgsLZd6IoDiM7Dza8pKzYPfY7jJ19JmK4S8lHG3YsoxTy2zkcwCI20sBekJU0iDGvOOJq5UbIumKsAm2uJkMKsKlxkDQr0Y+2J1l0iWBrUHonja6CieO5yNBWluA3DCqxa0pQW3dcOju3mGCQl0j8+3Iblu8lCGoQVSLQ3rUhekmz+cB2Q== alendvai laptop ssh key diff --git a/image-extras/etc/logrotate.d/syslog.conf b/image-extras/etc/logrotate.d/syslog.conf new file mode 100644 index 0000000..568856c --- /dev/null +++ b/image-extras/etc/logrotate.d/syslog.conf @@ -0,0 +1,10 @@ +/var/log/syslog +{ + olddir archive + rotate 30 + daily + dateext + notifempty + missingok + copytruncate +} diff --git a/image-extras/etc/rc.local b/image-extras/etc/rc.local new file mode 100644 index 0000000..ba11777 --- /dev/null +++ b/image-extras/etc/rc.local @@ -0,0 +1,6 @@ +# Put your custom commands here that should be executed once +# the system init finished. By default this file does nothing. + +/root/autoprovision-stage1.sh + +exit 0 diff --git a/image-extras/root/autoprovision-functions.sh b/image-extras/root/autoprovision-functions.sh new file mode 100755 index 0000000..bab2819 --- /dev/null +++ b/image-extras/root/autoprovision-functions.sh @@ -0,0 +1,93 @@ +#!/bin/sh + +# utility functions for the various stages of autoprovisioning + +# these are also copy-pasted into other scripts and config files! +rootUUID=05d615b3-bef8-460c-9a23-52db8d09e000 +dataUUID=05d615b3-bef8-460c-9a23-52db8d09e001 +swapUUID=05d615b3-bef8-460c-9a23-52db8d09e002 + +. /lib/ar71xx.sh + +# let's try some defaults... +autoprovisionUSBLed="tp-link:green:usb" +autoprovisionStatusLed="tp-link:green:qss" + +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:green:usb1" + autoprovisionStatusLed="tp-link:blue:qss" + ;; +esac + +log() +{ + /usr/bin/logger -t autoprov -s $* +} + +setLedAttribute() +{ + [ -f "/sys/class/leds/$1/$2" ] && echo "$3" > "/sys/class/leds/$1/$2" +} + +signalAutoprovisionWorking() +{ + setLedAttribute ${autoprovisionStatusLed} trigger none + setLedAttribute ${autoprovisionStatusLed} trigger timer + setLedAttribute ${autoprovisionStatusLed} delay_on 2000 + setLedAttribute ${autoprovisionStatusLed} delay_off 2000 +} + +signalAutoprovisionWaitingForUser() +{ + setLedAttribute ${autoprovisionStatusLed} trigger none + setLedAttribute ${autoprovisionStatusLed} trigger timer + setLedAttribute ${autoprovisionStatusLed} delay_on 200 + setLedAttribute ${autoprovisionStatusLed} delay_off 300 +} + +signalWaitingForPendrive() +{ + setLedAttribute ${autoprovisionUSBLed} trigger none + setLedAttribute ${autoprovisionUSBLed} trigger timer + setLedAttribute ${autoprovisionUSBLed} delay_on 200 + setLedAttribute ${autoprovisionUSBLed} delay_off 300 +} + +signalFormatting() +{ + setLedAttribute ${autoprovisionUSBLed} trigger none + setLedAttribute ${autoprovisionUSBLed} trigger timer + setLedAttribute ${autoprovisionUSBLed} delay_on 1000 + setLedAttribute ${autoprovisionUSBLed} delay_off 1000 +} + +stopSignallingAnything() +{ + setLedAttribute ${autoprovisionStatusLed} trigger none + setLedAttribute ${autoprovisionUSBLed} trigger usbdev +} + +setRootPassword() +{ + local password=$1 + if [ "$password" == "" ]; then + # set and forget a random password merely to disable telnet. login will go through ssh keys. + password=$(/dev/null + fi + + if (grep -q sda /proc/partitions) then + cat /sys/block/sda/size + else + echo 0 + fi +} + +hasBigEnoughPendrive() +{ + local size=$(getPendriveSize) + if [ $size -ge 2000000 ]; then + log "Found a pendrive of size: $(($size / 2 / 1024)) MB" + return 0 + else + return 1 + fi +} + +setupPendrivePartitions() +{ + # erase partition table + dd if=/dev/zero of=/dev/sda bs=1M count=1 + + # first is 'swap' + # second is 'root' + # the rest is 'data' + fdisk /dev/sda </mnt/extroot/etc/rc.local < /tmp symlink with the extroot, so that /var is permanent + mkdir -p /mnt/extroot/var + # KLUDGE: but /var/state is assumed to be transient, see https://dev.openwrt.org/ticket/12228 + cd /mnt/extroot/var + ln -s /tmp state + cd - + + log "Finished setting up extroot" +} + +autoprovisionStage1() +{ + signalAutoprovisionWorking + + # this way it will set a random password and only ssh key based login will work + setRootPassword "" + + signalAutoprovisionWaitingForUser + signalWaitingForPendrive + + until hasBigEnoughPendrive + do + echo "Waiting for a pendrive to be inserted" + sleep 3 + done + + signalAutoprovisionWorking # to make it flash in sync with the USB led + signalFormatting + + sleep 1 + + setupPendrivePartitions + sleep 1 + setupExtroot + + sync + stopSignallingAnything + reboot +} + +autoprovisionStage1 diff --git a/image-extras/root/autoprovision-stage2.sh b/image-extras/root/autoprovision-stage2.sh new file mode 100755 index 0000000..3d06768 --- /dev/null +++ b/image-extras/root/autoprovision-stage2.sh @@ -0,0 +1,72 @@ +#!/bin/sh + +# autoprovision stage 2: this script will be executed upon boot if the extroot was successfully mounted (i.e. rc.local is run from the extroot overlay) + +. /root/autoprovision-functions.sh + +installPackages() +{ + signalAutoprovisionWaitingForUser + + until (opkg update) + do + log "opkg update failed. No internet connection? Retrying in 15 seconds..." + sleep 15 + done + + signalAutoprovisionWorking + + log "Autoprovisioning stage2 is about to install packages" + + # switch ssh from dropbear to openssh (needed to install sshtunnel) + #opkg remove dropbear + #opkg install openssh-server openssh-sftp-server sshtunnel + + #/etc/init.d/sshd enable + #mkdir /root/.ssh + #chmod 0700 /root/.ssh + #mv /etc/dropbear/authorized_keys /root/.ssh/ + #rm -rf /etc/dropbear + + # install some more packages that don't need any extra steps + 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 + opkg install kmod-macvlan ip + + # just in case if we were run in a firmware that didn't already had luci + /etc/init.d/uhttpd enable +} + +autoprovisionStage2() +{ + log "Autoprovisioning stage2 speaking" + signalAutoprovisionWorking + + # it's not the nicest way to test whether stage2 has been done already, but this is a shell script... + if [ $(uci get system.@system[0].log_type) == "file" ]; then + log "Seems like autoprovisioning stage2 has been done already. Running stage3." + #/root/autoprovision-stage3.py + else + installPackages + + crontab - <