Skip to content

Instantly share code, notes, and snippets.

@Phill93
Last active October 15, 2017 18:04
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Phill93/30710d0b664648d9289b89ac7e188405 to your computer and use it in GitHub Desktop.
Save Phill93/30710d0b664648d9289b89ac7e188405 to your computer and use it in GitHub Desktop.
#!/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