#!/bin/bash
set -e
self="$(realpath "$0")"

# install alpine in sys-mode on raspberry pi 3 (or pi 4)
# ed <irc.rizon.net>, MIT-licensed fwiw, 2021-03-18
# https://ocv.me/doc/?alpine/rpi-sysinst.sh

# choose one below, last assignment wins:
arch=armhf   # all older models (pi zero, compute module 2, pi 1)
arch=armv7   # initial pi 2 model b revisions
arch=aarch64 # all newer models (pi 2 model b v1.2, compute 3)

alpine_tar="alpine-rpi-3.11.4-$arch.tar.gz"
alpine_url="https://mirrors.edge.kernel.org/alpine/v3.11/releases/$arch/$alpine_tar"
ssh_keys="https://ocv.me/authorized_keys"

# if your host is debian:
#   apt install xfsprogs
#
# if your host is systemd and something claims the disk is in use,
#   umount /dev/sdx*

stage="$1"
[ -z "$stage" ] && {
	echo "need arg 1: stage"
	echo "   stage a: on laptop, prepare sd and unpack alpine"
	echo "   stage b: on rpi, perform the install"
	exit 1
}

[ "$stage" = a ] &&
{
	blk="$2"
	[ -z "$blk" ] || [ ! -e "$blk" ] && {
		echo "need arg 2: blockdevice to format"
		echo "   example: /dev/sda"
		exit 1
	}
	
	miss=
	for c in wget git fdisk sfdisk mkfs.vfat mkfs.xfs; do
		command -v $c >/dev/null ||
			miss="$miss $c"
	done
	[ -z "$miss" ] || {
		echo "need these programs:$miss"
		exit 1
	}
	
	mkdir -p ~/alpine-rpi/
	
	[ -e ~/alpine-rpi/"$alpine_tar" ] ||
		(cd ~/alpine-rpi/ && wget "$alpine_url")
	
	mkdir -p /media/usb
	mount | grep /media/usb && {
		echo "something is mounted on /media/usb"
		exit 1
	}

	[ -e ~/alpine-rpi/firmware-nonfree ] ||
		(cd ~/alpine-rpi && git clone --depth 1 https://github.com/RPi-Distro/firmware-nonfree.git)

	fdisk -l "$blk"
	printf '\n\nthis is gonna get shredded'
	while true
	do
		printf '\ntype yes and hit enter: '
		read -u1 -r
		[ "$REPLY" = "yes" ] && break
	done

	# 256MB fat32, remaining linux, no need for bootflag
	printf ',256M,c\n,,83\n' | sfdisk "$blk"
	partprobe "$blk"
	while true; do
		mkfs.vfat -n RPINEB "${blk}1" && break
		sleep 1
	done
	while true; do
		mkfs.xfs -f -L rpined "${blk}2" && break
		sleep 1
	done
	mount "${blk}1" /media/usb/
	cd /media/usb/
	echo "unpacking ~/alpine-rpi/$alpine_tar ..."
	tar -xf ~/alpine-rpi/"$alpine_tar" --no-same-owner || true
	cat > usercfg.txt <<"EOF"
boot_delay=0
disable_splash=1
disable_overscan=1
gpu_mem=256
gpu_mem_256=16
gpu_mem_512=32
hdmi_group=2
hdmi_mode=16
dtparam=audio=on
# [pi3]
dtoverlay=vc4-kms-v3d
EOF
	mkdir -p /media/usb/firmware/brcm
	cp --preserve=timestamps \
		~/alpine-rpi/firmware-nonfree/brcm/* \
		/media/usb/firmware/brcm/
	cd
	cp -v --preserve=timestamps "$self" /media/usb/
	umount /media/usb
	sync
	udisksctl power-off -b "${blk}" || true

	echo unplug the sd card and boot the pi, then run:
	echo   ash /media/mmc*/rpi-sysinst* b
	exit 0
}

[ "$stage" = b ] || {
	echo "invalid stage: [$stage]"
	exit 1
}

cat <<'EOF'

about to run the alpine installer,
all choices are up to you except for this question:
-- Enter where to store configs: none

ok here we go
EOF
setup-alpine

cd
mkdir .ssh
wget "$ssh_keys" -O .ssh/authorized_keys

apk add util-linux xfsprogs wpa_supplicant mesa-dri-vc4 haveged
rc-update add wpa_supplicant boot

mount /dev/mmcblk0p2 /mnt/
ROOTFS=xfs /sbin/setup-disk -m sys -s 0 /mnt || true

# the following errors are expected and ok:
#
# ERROR: unsatisfiable constraints:
#   syslinux (missing):
#     required by: world[syslinux]
# Installing system on /dev/mmcblk0p2:
# sed: /etc/update-extlinux.conf: No such file or directory
# /sbin/setup-disk: line 340: extlinux: not found

# mount boot partition, move in the new initramfs
mount -o remount,rw /media/mmcblk0p1
rm -f /media/mmcblk0p1/boot/*
cd /mnt
rm boot/boot
mv boot/* /media/mmcblk0p1/boot/

# make rootfs boot a symlink into the fat32 partition
rm -rf boot/
mkdir media/mmcblk0p1
ln -s media/mmcblk0p1/boot boot
echo "/dev/mmcblk0p1 /media/mmcblk0p1 vfat defaults 0 0" >> etc/fstab
#echo "/media/mmcblk0p1/boot /boot none defaults,bind 0 0" >> etc/fstab

# there is no hwclock and usually few entropy sources
rc-update add swclock boot
rc-update del hwclock boot || true
rc-update add haveged boot

# then it's just misc cleanup
sed -i '/cdrom/d; /floppy/d' etc/fstab
sed -ri 's@^#(.+[0-9]/community)$@\1@' etc/apk/repositories
cp -pvR ~/.ssh root/

cd /media/mmcblk0p1
sed -ri 's@(^modules=[^ ]+)@\1,xfs@' cmdline.txt
sed -ri 's@(^modules=)@root=/dev/mmcblk0p2 \1@' cmdline.txt

reboot
exit 0





##
## unfinished stuff below

# note that xfce runs hella slow on pi 3b under alpine 3.11 / linux 5.4? idk which



# essential software
apk add bash bzip2 coreutils diffutils dosfstools e2fsprogs e2fsprogs-extra findutils grep gzip htop iputils less lm_sensors lshw man mc mosh nano ncdu net-tools nmap-ncat openssh p7zip pigz pm-utils powertop pv python3 rsync smartmontools socat strace sudo tar tmux tmux-doc upower util-linux vim wget wireless-tools xz zip 
apk add mpv ffmpeg rtorrent sshfs nmap ntfs-3g pciutils pngquant
bash
cd
wget https://ocv.me/dot/.{bashrc,Xresources,tmux.conf}
bash

# xfce
setup-xorg-base
apk add xfce4 lxdm xfce4-terminal xf86-input-{keyboard,mouse,synaptics} acpi
apk add greybird-themes faenza-icon-theme adwaita-icon-theme
rc-update add dbus
service dbus start
service lxdm start

# autologin after logging in successfully once
cd /etc/lxdm
echo [base] >> lxdm.conf
echo autologin=ed >> lxdm.conf
rc-update add lxdm

