#!/bin/bash

#LXC wrapper to download and deploy system images.
#By Frank Endres <frankendres@tuxfamily.org> - disabled, use first@last.fr
#Copyright 2023-04-30, under CeCILL / GPL licence

ARCH=amd64

function usage() {
	echo "usage: $0 --dist ... --release ... container_name"
	echo "example: $0 --dist debian --release bullseye deb"
	echo -e "\nDIST   RELEASE   (https://uk.lxd.images.canonical.com):"
	{ if [ -f /etc/slackware-version ]; then echo -e "slackware 15.0\nslackware current"; fi
	wget -O - https://uk.lxd.images.canonical.com/ 2>/dev/null | grep -e "^<tr><td>.*amd64" | sed -e 's@<tr><td>@@' -e 's@</td><td>@ @g' | cut -f1-2 -d' ' | \
		sed -e /^alt/d -e/^apertis/d -e '/too /d' -e /openeuler/d -e /plamo/d -e /busybox/d | \
		sed -e /centos/d -e/oracle/d -e /amazonlinux/d -e /devuan/d -e /openwrt/d -e /springdalelinux/d -e/^pld/d | \
		sed -e /bionic/d -e /xenial/d -e /focal/d -e '/almalinux 8/d' -e /buster/d -e '/fedora 36/d' | \
		sed -e /mint/d -e /alpine/d -e /voidlinux/d -e /kali/d -e /opensuse/d -e /rockylinux/d #-e '/alpine 3.1[456]/d'
	} | sort -u
}


if (( $(id -u) != 0 )); then
	echo "error: $0 should be run as root"
	exit 1
fi

while (( $# > 0 )); do 
	if [ "$1" == "--dist" ] || [ "$1" == "--release" ]; then opt="$1"
	elif [ "$opt" == "--dist" ]; then DIST="$1"; opt=""
	elif [ "$opt" == "--release" ]; then RELEASE="$1"; opt=""
	else name="$1"
	fi
shift; done

if [ -z "$name" ] || [ -z "$DIST" ] || [ -z "$RELEASE" ]; then
	usage
	exit 2
fi


echo -e "\n*** Deploying $DIST system image into '$name'"
if [ "$DIST" == "slackware" ] && [ -f /etc/slackware-version ]; then
	release=$RELEASE lxc-create -t slackware -n $name || exit
else
	lxc-create -t download -n $name -- --dist $DIST --release $RELEASE --arch $ARCH --keyserver hkp://keyserver.ubuntu.com/ || exit
fi

if [ ! -z "$DOMAINS" ]; then 
	for d in $DOMAINS; do
		sed /$d/d -i /etc/hosts
	done
else
	sed /$name.local.net/d -i /etc/hosts
fi

echo -e "\n*** configuring network"
gw=$(cat /etc/default/lxc-net | grep "^LXC_ADDR" | cut -f2 -d'"')
net=$(echo $gw | cut -f1-3 -d.); msk=24 #only 255.255.255.0 is supported yet
lst=$(cat /etc/hosts | grep "$net." | cut -f4 -d. | cut -f1 -d' ' | sort | tail -n1)
if [ -z "$lst" ]; then num=1; else let num=lst+1; fi
ip="$net.$num"
echo -e "\tip = $ip/$msk"
echo -e "\tgateway = $gw"
cat >> /var/lib/lxc/$name/config << EOF
lxc.net.0.ipv4.address = $ip/$msk
lxc.net.0.ipv4.gateway = $gw
EOF

if [ ! -z "$MOUNTS" ]; then
	for mnt in ${MOUNTS[*]}; do
		host=$(echo $mnt | cut -f1 -d=)
		guest=$(echo $mnt | cut -f2 -d=)
		echo "lxc.mount.entry = $host $guest none bind 0 0" >> /var/lib/lxc/$name/config
		mkdir -p /var/lib/lxc/$name/rootfs/$guest
	done
fi

if [ "$DIST" == "debian" ] || [ "$DIST" == "ubuntu" ] || [ "$DIST" == "fedora" ]; then
	if [ "$DIST" == "debian" ]; then rm -f /var/lib/lxc/$name/rootfs/etc/systemd/network/eth0.network; fi #IP set by host
	sed 's/^#DNS=/DNS=9.9.9.9 2620:fe::fe/' -i /var/lib/lxc/$name/rootfs/etc/systemd/resolved.conf
elif [ "$DIST" == "slackware" ]; then
	chmod -x /var/lib/lxc/$name/rootfs/etc/rc.d/rc.inet1 #IP set by host
	echo -e "nameserver 9.9.9.9\nnameserver 2620:fe::fe" > /var/lib/lxc/$name/rootfs/etc/resolv.conf
fi

echo -e "\n*** configuring host name resolution (/etc/hosts)"
if [ ! -z "$DOMAINS" ]; then
	for d in $DOMAINS; do
		echo -e "\t$d -> $ip"
		echo "$ip $d" >> /etc/hosts
	done
else
	echo -e "\t$name.local.net -> $ip"
	echo "$ip $name.local.net $name" >> /etc/hosts
fi

sleep 3

SSH_PATH=$HOME/.ssh
if [ ! -z "$SUDO_USER" ]; then
	SSH_PATH=/home/$SUDO_USER/.ssh
fi
sed /$ip/d -i $SSH_PATH/known_hosts
if [ -f authorized_keys ] || [ -f $SSH_PATH/id_rsa.pub ]; then
	echo -e "\n*** configuring SSH key authentication"
	sudo mkdir -p /var/lib/lxc/$name/rootfs/root/.ssh
	if [ -f authorized_keys ]; then
		cp authorized_keys /var/lib/lxc/$name/rootfs/root/.ssh/
	else
		cp $SSH_PATH/id_rsa.pub /var/lib/lxc/$name/rootfs/root/.ssh/authorized_keys
	fi
fi

echo -e "\n*** starting container '$name'"
lxc-start -n $name
sleep 3
if [ "$DIST" == "debian" ] || [ "$DIST" == "ubuntu" ]; then
	echo -e "\n*** installing OpenSSH"
	lxc-attach -n $name -- apt install -y openssh-server
elif [ "$DIST" == "archlinux" ] || [ "$DIST" == "fedora" ] || [ "$DIST" == "almalinux" ]; then
	if [ "$DIST" == "almalinux" ]; then
		echo "\n*** fixing network configuration"
		lxc-attach -n $name -- nmcli connection modify eth0 IPv4.address $ip/$msk
		lxc-attach -n $name -- nmcli connection modify eth0 IPv4.gateway $gw
		lxc-attach -n $name -- nmcli connection modify eth0 IPv4.dns 9.9.9.9
		lxc-attach -n $name -- nmcli connection modify eth0 IPv4.method manual
		lxc-attach -n $name -- nmcli connection up eth0
	fi
	echo -e "\n*** installing OpenSSH"
	if [ "$DIST" == "archlinux" ]; then
		lxc-attach -n $name -- pacman -Syu --noconfirm openssh
	else #fedora || almalinux
		lxc-attach -n $name -- dnf -y install openssh-server
	fi
	lxc-attach -n $name -- systemctl enable sshd
	lxc-attach -n $name -- systemctl start sshd
elif [ "$DIST" == "slackware" ]; then
	echo -e "\n*** fixing slackpkg"
	sed -e 's/^\(CHECKGPG\)=on/\1=off/' -e 's/^\(BATCH\)=off/\1=on/' -e 's/^\(DEFAULT_ANSWER\)=n/\1=y/' -i /var/lib/lxc/$name/rootfs/etc/slackpkg/slackpkg.conf
	lxc-attach -n $name -- removepkg bridge-utils
	lxc-attach -n $name -- slackpkg update
	lxc-attach -n $name -- slackpkg install perl openssl
	lxc-attach -n $name -- slackpkg install ca-certificates #after perl
	lxc-attach -n $name -- slackpkg update gpg
	sed -e 's/^CHECKGPG=off/CHECKGPG=on/' -e 's/^\(BATCH\)=on/\1=off/' -e 's/^\(DEFAULT_ANSWER\)=y/\1=n/' -i /var/lib/lxc/$name/rootfs/etc/slackpkg/slackpkg.conf
fi
