#!/bin/bash | |
IN=$1 | |
OUT=build/$1 | |
# Password below is set on for Pi Zeros default password AND controller | |
PASSWORD=clusterhat | |
# Cleanup any previous attempts | |
rm -i $OUT | |
dd if=/dev/zero bs=1G seek=5 count=0 of=$OUT | |
parted $OUT --script -- mklabel msdos | |
parted $OUT --script -- mkpart primary fat32 0% 64M | |
parted $OUT --script -- mkpart primary 64M 100% | |
which kpartx >/dev/null 2>&1 | |
if [ $? -eq 1 ];then | |
apt-get install -u kpartx | |
fi | |
LOOP=`losetup -f --show $OUT` | |
sleep 5 | |
kpartx -av $LOOP | |
sleep 5 | |
mkdosfs -F 32 -n BOOT -v `echo $LOOP|sed s#dev#dev/mapper#`p1 | |
mkfs.ext4 -m 1 -L ROOT `echo $LOOP|sed s#dev#dev/mapper#`p2 | |
mkdir mnt | |
mkdir mntimg | |
mount `echo $LOOP|sed s#dev#dev/mapper#`p2 mnt | |
mkdir mnt/boot | |
mount `echo $LOOP|sed s#dev#dev/mapper#`p1 mnt/boot | |
LOOP2=`losetup -f --show $IN` | |
sleep 5 | |
kpartx -av $LOOP2 | |
sleep 5 | |
mount -o ro `echo $LOOP2|sed s#dev#dev/mapper#`p2 mntimg | |
mount -o ro `echo $LOOP2|sed s#dev#dev/mapper#`p1 mntimg/boot | |
# Copy controller filesystem over to new image | |
(tar -cC mntimg .)|(tar -C mnt -x) | |
# Fix fstab/cmdline on the controller | |
# Get partial PARTUUID | |
LOOPN=`echo $LOOP|sed "s#.*/##"` | |
PARTUUID=`blkid /dev/mapper/${LOOPN}p1|sed "s/ /\n/g"|grep PART|sed 's/.*"\(.*\)-..".*/\1/'` | |
sed -i "s#root=PARTUUID=.*-02 #root=PARTUUID=$PARTUUID-02 #" mnt/boot/cmdline.txt | |
sed -i "s#^PARTUUID=.*-#PARTUUID=$PARTUUID-#" mnt/etc/fstab | |
# Get any updates / install and remove pacakges | |
chroot mnt /bin/bash -c 'apt-get update' | |
chroot mnt /bin/bash -c 'APT_LISTCHANGES_FRONTEND=none apt-get -y dist-upgrade' | |
chroot mnt /bin/bash -c 'apt-get -y install bridge-utils wiringpi screen minicom git libusb-1.0-0-dev kpartx nfs-kernel-server' | |
echo 8021q >> mnt/etc/modules | |
sed -i "s#auto lo br0#auto lo brint brext#" mnt/etc/network/interfaces | |
sed -i '/iface br0 inet manual/,$d' "mnt/etc/network/interfaces" | |
cat << EOF >> "mnt/etc/network/interfaces" | |
# Internal network (untagged on Pi Zeros) | |
auto brint | |
iface brint inet static | |
bridge_ports none | |
address 172.19.180.254 | |
netmask 255.255.255.0 | |
bridge_stp off | |
bridge_waitport 0 | |
bridge_fd 0 | |
# External network (VLAN10 on Pi Zeros) | |
iface brext inet manual | |
bridge_ports eth0 | |
bridge_stp off | |
bridge_waitport 0 | |
bridge_fd 0 | |
EOF | |
sed -i "s#denyinterface.*#denyinterfaces eth0 ethpi1 ethpi2 ethpi3 ethpi4 ethpi*.10 brint#" mnt/etc/dhcpcd.conf | |
sed -i 's#"net", #"net", SUBSYSTEMS=="usb", #' mnt/etc/udev/rules.d/90-clusterhat.rules | |
I=0 | |
while [ $I -lt 256 ];do | |
echo "auto ethpi$I ethpi$I.10 | |
allow-hotplug ethpi$I | |
allow-hotplug ethpi$I.10 | |
# Internal network untagged | |
iface ethpi$I inet manual | |
pre-up brctl addif brint ethpi$I | |
up ifconfig ethpi$I up | |
post-up ifup ethpi$I.10 | |
# External network (VLAN 10) | |
iface ethpi$I.10 inet manual | |
pre-up brctl addif brext ethpi$I.10 | |
up ifconfig ethpi$I.10 up | |
post-up ifup ethpi$I.10" | |
echo | |
let I=$I+1 | |
done > mnt/etc/network/interfaces.d/clusterhat | |
mkdir -p mnt/var/lib/clusterhat/nfs/{p1,p2,p3,p4} | |
mkdir mnt/var/lib/clusterhat/boot | |
# Copy the controller image into NFS roots | |
tar -cC mntimg .|tee >(tar -xC mnt/var/lib/clusterhat/nfs/p1/) >(tar -xC mnt/var/lib/clusterhat/nfs/p2/) >(tar -xC mnt/var/lib/clusterhat/nfs/p3/) | tar -xC mnt/var/lib/clusterhat/nfs/p4/ | |
for I in 1 2 3 4 ; do | |
cp "mnt/usr/share/clusterhat/cmdline.p$I" mnt/var/lib/clusterhat/nfs/p$I/boot/cmdline.txt | |
cp -f "mnt/usr/share/clusterhat/interfaces.p" mnt/var/lib/clusterhat/nfs/p$I/etc/network/interfaces | |
cp -f "mnt/usr/share/clusterhat/issue.p" mnt/var/lib/clusterhat/nfs/p$I/etc/issue | |
sed -i "s#^denyinterfaces.*#denyinterfaces eth0 ethpi1 ethpi2 ethpi3 ethpi4 usb0.10 usb0#" mnt/var/lib/clusterhat/nfs/p$I/etc/dhcpcd.conf | |
sed -i "s#^auto usb0#auto usb0.10#" mnt/var/lib/clusterhat/nfs/p$I/etc/network/interfaces | |
sed -i "s#^allow-hotplug usb0#allow-hotplug usb0.10#" mnt/var/lib/clusterhat/nfs/p$I/etc/network/interfaces | |
sed -i "s#^iface usb0 inet dhcp#iface usb0.10 inet dhcp#" mnt/var/lib/clusterhat/nfs/p$I/etc/network/interfaces | |
sed -i "s/^PARTUUID.*//" mnt/var/lib/clusterhat/nfs/p$I/etc/fstab | |
sed -i "s#^127.0.1.1.*#127.0.1.1\tp$I#g" mnt/var/lib/clusterhat/nfs/p$I/etc/hosts | |
sed -i "s/^#dtoverlay=dwc2$/dtoverlay=dwc2/" mnt/var/lib/clusterhat/nfs/p$I/boot/config.txt | |
echo "p$I" > mnt/var/lib/clusterhat/nfs/p$I/etc/hostname | |
sed -i "s#root=.* rootfstype=ext4#root=/dev/nfs nfsroot=172.19.180.254:/var/lib/clusterhat/nfs/p$I rw ip=172.19.180.$I:172.19.180.254::255.255.255.0:p$I:usb0:static#" mnt/var/lib/clusterhat/nfs/p$I/boot/cmdline.txt | |
sed -i "s#MODULES=most#MODULES=netboot#" mnt/var/lib/clusterhat/nfs/p$I/etc/initramfs-tools/initramfs.conf | |
echo "BOOT=nfs" >> mnt/var/lib/clusterhat/nfs/p$I/etc/initramfs-tools/initramfs.conf | |
echo -e "dwc2\ng_cdc\nuio_pdrv_genirq\nuio\nusb_f_acm\nu_serial\nusb_f_ecm\nu_ether\nlibcomposite\nudc_core\nipv6\n" >> mnt/var/lib/clusterhat/nfs/p$I/etc/initramfs-tools/modules | |
chroot mnt/var/lib/clusterhat/nfs/p$I/ /bin/bash -c 'mkinitramfs -o /boot/initramfs.img 4.9.35+' | |
echo "initramfs initramfs.img" >> mnt/var/lib/clusterhat/nfs/p$I/boot/config.txt | |
echo "/var/lib/clusterhat/nfs/p$I 172.19.180.$I(rw,sync,no_subtree_check,no_root_squash)" >> mnt/etc/exports | |
touch mnt/var/lib/clusterhat/nfs/p$I/boot/ssh | |
chroot mnt/var/lib/clusterhat/nfs/p$I/ /bin/bash -c "echo "pi:$PASSWORD" |chpasswd" | |
# Enable serial console on Pi Zeros | |
lua - enable_uart 1 mnt/var/lib/clusterhat/nfs/p$I/boot/config.txt <<EOF > mnt/var/lib/clusterhat/nfs/p$I/boot/config.txt.bak | |
local key=assert(arg[1]) | |
local value=assert(arg[2]) | |
local fn=assert(arg[3]) | |
local file=assert(io.open(fn)) | |
local made_change=false | |
for line in file:lines() do | |
if line:match("^#?%s*"..key.."=.*$") then | |
line=key.."="..value | |
made_change=true | |
end | |
print(line) | |
end | |
if not made_change then | |
print(key.."="..value) | |
end | |
EOF | |
mv mnt/var/lib/clusterhat/nfs/p$I/boot/config.txt.bak mnt/var/lib/clusterhat/nfs/p$I/boot/config.txt | |
done | |
chroot mnt systemctl enable rpcbind | |
chroot mnt systemctl enable nfs-kernel-server | |
chroot mnt /bin/bash -c 'mkdir /var/lib/clusterhat;cd /var/lib/clusterhat;git clone https://github.com/burtyb/usbboot;cd usbboot;make' | |
chroot mnt /bin/bash -c "echo "pi:$PASSWORD" |chpasswd" | |
touch mnt/boot/ssh | |
# TODO Start in screen | |
# Enable serial console (on controller) | |
lua - enable_uart 1 mnt/boot/config.txt <<EOF > mnt/boot/config.txt.bak | |
local key=assert(arg[1]) | |
local value=assert(arg[2]) | |
local fn=assert(arg[3]) | |
local file=assert(io.open(fn)) | |
local made_change=false | |
for line in file:lines() do | |
if line:match("^#?%s*"..key.."=.*$") then | |
line=key.."="..value | |
made_change=true | |
end | |
print(line) | |
end | |
if not made_change then | |
print(key.."="..value) | |
end | |
EOF | |
mv mnt/boot/config.txt.bak mnt/boot/config.txt | |
(cd mnt/var/lib/clusterhat/;cp -r nfs/p1/boot .) | |
(cd mnt/var/lib/clusterhat/;ln -s ../nfs/p4/boot/ boot/1-1.2.1) | |
(cd mnt/var/lib/clusterhat/;ln -s ../nfs/p3/boot/ boot/1-1.2.2) | |
(cd mnt/var/lib/clusterhat/;ln -s ../nfs/p2/boot/ boot/1-1.2.3) | |
(cd mnt/var/lib/clusterhat/;ln -s ../nfs/p1/boot/ boot/1-1.2.4) | |
# NFS doesn't start properly on boot, append to etc/rc.local | |
sed -i "s#^exit 0#/bin/systemctl restart rpcbind\n/bin/systemctl restart nfs-kernel-server\n/usr/bin/screen -S rpiboot -d -m /var/lib/clusterhat/usbboot/rpiboot -d /var/lib/clusterhat/boot/ -o -l -v\n\nexit 0#" mnt/etc/rc.local | |
# Cleanup | |
umount mnt/boot | |
umount mnt | |
umount mntimg/boot | |
umount mntimg | |
kpartx -dv $LOOP | |
losetup -d $LOOP | |
kpartx -dv $LOOP2 | |
losetup -d $LOOP2 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment