#!/bin/bash
set -e

# install-ubuntu.sh - installs ubuntu in a chroot
# ed <irc.rizon.net>, MIT-licensed, 2020-01-06, v1.0
# https://ocv.me/dev/?install-ubuntu.sh

##
## config

# repo mirror
umirror="https://mirrors.edge.kernel.org/ubuntu"

# version to grab
uver=eoan

# architecture
uarch=i386
uarch=amd64


##
## helper methods

msg() { printf '\033[1;30m>\033[0;34m>\033[1m>\033[0m %s\n' "$1" >&2; }
inf() { printf '\n\033[1;30m>\033[0;32m>\033[1m>\033[0;32m %s\033[0m\n' "$1" >&2; }
wrn() { printf '\n\033[1;30m>\033[0;33m>\033[1m>\033[0;33m %s\033[0m\n' "$1" >&2; }
err() { printf '\n\033[1;30m>\033[0;31m>\033[1m>\033[0;31m %s\033[0m\n' "$1" >&2; }


##
## ensure dependencies

miss=''
for cmd in wget awk sed
do
	command -v "$cmd" >/dev/null ||
		miss="$miss $cmd"
done

[ -z "$miss" ] || {
	err "missing programs: $miss"
	exit 1
}


download() {
	# check that it's safe to continue
	[ -e "$cr" ] &&
	{
		err "chroot exists, aborting"
		exit 1
	}

	command -v apk && apk add -i debootstrap debian-archive-keyring ubuntu-archive-keyring@test
	command -v pacman && pacman -S --needed debootstrap debian-archive-keyring ubuntu-archive-keyring
	mkdir -p /var/cache/debootstrap "${cr%/*}"
	
	#[ -e /usr/share/debootstrap/scripts/$uver ] ||
	#	(cd /usr/share/debootstrap/scripts && ln -s gutsy $uver)
	
	sed -r 's/apt-transport-https//' </usr/share/debootstrap/scripts/gutsy >/dev/shm/dbs-$uver

	debootstrap \
		--force-check-gpg \
		--cache-dir=/var/cache/debootstrap \
		--include=apt,gpg,ca-certificates \
		--arch=$uarch $uver "$cr" $umirror/ \
		/dev/shm/dbs-$uver
}


addscripts() {
	echo
	msg "adding activate"
	
	# enable bindmount of /home
	home1='home'
	home2='|home'
	
	# or not
	home1=
	home2=
	
	cat >"${cr%/*}/activate-${cr##*/}" <<EOF
#!/bin/bash
set -e

# sans trailing slash
cr="$cr"

echo chroot prep >&2

#mount |
#grep -qF " on \$cr " ||
#	mount --bind "\$cr" "\$cr"

mount |
grep -qF " on \$cr/tmp " ||
	mount -t tmpfs tmpfs "\$cr/tmp"

cd "\$cr"
# OPTIONAL: home

{
	printf '/%s\n' sys dev proc run $home1;
	mount | sed -r 's/[^ ]+ on //;s/ .*//'
} |
grep -E '^/(sys|dev|proc|run$home2)(/|$)' |
cut -c2- |
LC_ALL=C sort |
uniq |
while IFS= read d
do
	#printf 'mount [%s] ' "\$d" >&2;
	[ -e "\$d" ] && [ -e "/\$d" ] ||
		{ printf 'mount [%s] NG\n' "\$d" >&2; continue; }
	
	#printf 'ok\n' >&2;
	
	mount |
	grep -qF " on \$cr/\$d " ||
		mount --make-rslave --bind /\$d \$d
		#mount --make-rslave --rbind /\$d \$d
done

rm -f etc/resolv.conf
cp -p /etc/resolv.conf etc/
chmod 1777 /dev/shm

# OPTIONAL: collect Xorg session key
xauth list > /dev/shm/Xauth || true

# OPTIONAL: allow access to the sound card from other users through unix socket only
sudo -u ed pactl load-module module-native-protocol-unix auth-anonymous=1 socket=/dev/shm/pulse-socket 2>/dev/null || true

echo chroot activate >&2
rv=0
[ -z "\$1" ] && { chroot "\$cr" /bin/bash || rv=\$?; }
[ -z "\$1" ] || { chroot "\$cr" "\$@"     || rv=\$?; }

[ \$rv -eq 0 ] ||
{
	printf "\033[1;31m\n[!] left chroot with exit code \$rv\033[0m\n\n" >&2
	exit \$rv
}

printf '\033[1;30m'
find /proc/ -mindepth 2 -maxdepth 2 -name exe -printf '%l\n' 2>/dev/null |
grep -F "\$cr/" &&
{
	printf '\033[33mother shells using the chroot; will not deactivate\033[0m\n' >&2
} ||
{
	"\${cr%/*}/deactivate-\${cr##*/}"
}
printf '\033[0m'
EOF

	msg "adding deactivate"
	cat >"${cr%/*}/deactivate-${cr##*/}" <<EOF
#!/bin/bash
set -e

# sans trailing slash
cr="$cr"
ecr="\$(
	printf '%s\n' "\$cr" |
	sed -e 's/[]\/\$*.^|?+(){}[]/\\\&/g'
)"

deactivate()
{
	printf '\033[33munmounting chroot stuff\033[0m\n'
	mount |
	awk '/[^ ]+ on '"\$ecr"'[/ ]/ && v[\$3]++==0 {print \$3}' |
	LC_ALL=C sort -r |
	# tee /dev/stderr |
	tr '\n' '\0' |
	xargs -0 umount
}

deactivate ||
deactivate ||
deactivate ||
echo "giving up, just reboot"
EOF

	chmod 755 "${cr%/*}/"*activate-"${cr##*/}"
}


fixup() {
	cd "$cr"
	
	[ -e var/lib/dbus/ ] &&
		cat /var/lib/dbus/machine-id > var/lib/dbus/machine-id || true
    
	cp -pv ~ed/.{bashrc,tmux.conf}* . ||
		wget https://ocv.me/dot/.{bashrc,tmux.conf}
	
	cat >etc/apt/sources.list <<EOF
deb $umirror/ $uver main restricted
deb $umirror/ $uver-updates main restricted
deb $umirror/ $uver universe
deb $umirror/ $uver-updates universe
deb $umirror/ $uver multiverse
deb $umirror/ $uver-updates multiverse
deb $umirror/ $uver-backports main restricted universe multiverse
deb $umirror/ $uver-security main restricted
deb $umirror/ $uver-security universe
deb $umirror/ $uver-security multiverse
EOF
	
	sed -ri 's/\\h\\$/\\h-ubu\\/' .bashrc
	mv .{bashrc,tmux.conf}* root/
}


inst() {
	cat >"$cr/t.sh" <<'EOF'
m() { printf '\n\n\n\033[1;37;44m[ %s ]\033[0m\n' "$*"; "$@"; }
w() { read -u1 -r -p 'press enter'; }

m /sbin/useradd -m -p k -s /bin/bash -u 1000 ed
m /sbin/useradd -m -p k -s /bin/bash -u 1984 nope

m find /var/cache/apt/archives -name '*.deb' -delete
m rm /var/cache/apt/* || true
m rm /var/lib/apt/lists/* || true

m df -h
EOF

	"${cr%/*}/activate-${cr##*/}" /bin/bash /t.sh
	rm "$cr/t.sh"
}


# chroot location
cr="$1"
[ -z "$cr" ] && {
	err "need argument 1: location to create chroot at"
	exit 1
}

# ensure no trailing slash in the chroot path
cr="${cr%/}"

# do it
download
addscripts
( fixup )
inst

cp -pv "$0" "$cr/root/"
inf "ready: ${cr%/*}/activate-${cr##*/}"

exit 0
