jean-cloud-services/installing/debootstrap_ordis_portables.sh
2024-04-18 16:22:32 +02:00

333 lines
9.0 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/bin/bash
# Ce script est une base quil faut sûrement améliorer.
# Il sert à installer un debian dordi portable JC pour le cluster SHLAGO
# Le but est dinstaller juste ce quil faut pour le le serveur tourne, le reste est laissé à ansible.
# Il génère une clé SSH qui permettra daccéder à la machine. Cest peut-être con, il faudrait plutôt le remplir de nos ssh publiques.
# https://github.com/adrianamaglio/driglibash
declare -A usage
declare -A varia
export driglibash_run_retry=true
version="alpha nightly 0.0.1 pre-release unstable"
summary="$0 [options]"
usage[m]="Path of the temporar mount point"
varia[m]=mnt
mnt="temporary_mount_point"
usage[a]="The architecture of installed system as supported by debootstrap"
varia[a]=arch
arch="amd64"
usage[r]="The release of installed system as supported by debootstrap"
varia[r]=release
release="bullseye"
usage[s]="Source repository of installed system"
varia[s]=repo
#repo=
repo="http://ftp.fr.debian.org/debian"
#repo="http://localhost:3142/ftp.fr.debian.org/debian"
usage[S]="Additional sources to add in source.list. Newline separated."
varia[S]=repos
repos="deb http://ftp.fr.debian.org/debian stable main contrib non-free"
usage[n]="The hostname"
varia[n]=hostname
hostname=""
usage[b]="The device where grub will be installed"
varia[b]=boot_device
boot_device=
usage[B]="Boot partition"
varia[B]=boot_part
boot_part=
usage[R]="The device where the system will be installed"
varia[R]=root_device
root_device=
usage[l]="System locale"
varia[l]=locale
locale="en_US.UTF-8 UTF-8\nfr_FR.UTF-8 UTF-8"
usage[w]="Wireguard IP last number (4 for 1.2.3.4)"
varia[w]=wireguard_number
wireguard_number=
usage[J]="Just mount and chroot it. No installation"
varia[J]=just_mount
just_mount=false
usage[i]="Packages to install. space separated"
varia[i]=install
install=
usage[u]="Install grub as UEFI (not working)"
varia[u]=uefi
uefi=false
usage[I]="Interractive mode. Ask questions if needed."
varia[I]=interractive
interractive=false
usage[D]="Data Device. Will be encrypted."
varia[D]=data_device
data_device=
. driglibash-args
secret_dir=secrets
secret_dir="$(realpath -m "$secret_dir/$hostname")"
install="$install linux-image-amd64 console-data grub2 locales vim openssh-server git nginx smartmontools tcpdump netcat-openbsd wireguard"
debootstrap_done_marker="$mnt/etc/debootstrap_done"
uefi_mountpoint=/boot/efi
dependancies="cryptsetup locales openssh-server wireguard-tools grub2"
###############################################################################
# Actual script
###############################################################################
chroot_run(){
run chroot "$mnt" $@
if [ "$?" -ne 0 ] && [ "$?" != '0' ] ; then
die "Error, chroot command [$@] exited with code '$?'"
fi
}
wait_for_user(){
section "Time for a pause"
run echo "Press 'Enter' to continue"
read
}
mount_misc(){
run mkdir -p "$mnt"/{proc,dev,sys}
run mount -t proc /proc "$mnt/proc"
#clean "umount '$(realpath "$mnt/proc")'"
# To access physical devices
run mount --rbind --make-rslave /dev "$mnt/dev"
# even explicitly mounting /dev/pts makes apt cry for its absence…
#clean "umount -R '$(realpath "$mnt/dev")'"
run mount --rbind --make-rslave /sys "$mnt/sys"
#clean "umount -R '$(realpath "$mnt/sys")'"
if "$uefi" ; then
run mkdir -p "$mnt$uefi_mountpoint"
run mount "$boot_device" "$mnt$uefi_mountpoint"
fi
clean "umount -R '$mnt'"
}
if [ -z "$hostname" ] ; then
die "Hostname arg needed"
fi
root_or_die
section "Testing for existing secrets"
if ! [ -d "$secret_dir" ] ; then
run mkdir -p "$secret_dir"
run chown -R root:root "$secret_dir"
run chmod 700 "$secret_dir"
fi
section "Mounting additionnal items"
if [ -n "$(df | grep "$root_device")" ] ; then
run umount "$root_device"
fi
run mkdir -p "$mnt"
run mount --make-private "$root_device" "$mnt"
# bug in driglibash-base. If $mnt got spaces it breaks
if [ -n "$boot_part" ] ; then
run mkdir -p "$mnt/boot"
run mount "$boot_part" "$mnt/boot"
fi
clean "umount -R $mnt"
if [ "$just_mount" != false ] ; then
echo 'Mounted. Exit shell to unmount.'
chroot_run
die 'You asked to just mount then exit.'
fi
section "debootstraping"
if [ ! -f "$debootstrap_done_marker" ] ; then
# Debootstrap may fail when the target is an existing system
if [ -n "$(ls -A $mnt | grep -vi -e 'lost+found' -e boot)" ]; then
yell "Root dir '$mnt' is not empty."
if "$interractive" ; then
read -p 'Press enter to continue anyway'
else
die "Wont debootstrap it. Is this installation broken?"
fi
fi
run debootstrap --verbose --arch "$arch" "$release" "$mnt" "$repo"
touch "$debootstrap_done_marker"
else
yell "Already done"
fi
mount_misc
section "Installing selected software"
echo "$repos" >> "$mnt/etc/apt/sources.list"
run chroot "$mnt" <<EOF
export DEBIAN_FRONTEND=noninteractive
apt-get update -q -y
apt-get install -q -y $install
EOF
# TODO watershed ?
section "Generating locales"
echo -e "$locale" > "$mnt/etc/locale.gen"
chroot_run locale-gen
if [ -n "$data_device" ] ; then
section "Mounting and encrypting data dir"
run cryptsetup create --type plain dmcrypt-jeancloud "$data_device"
run mkfs.ext4 dmcrypt-jeancloud
uuid="$(blkid | grep dmcrypt-jeancloud | grep -o 'UUID="[^"]\+"')"
if [ -z "$uuid" ] ; then
die "Error, unexpected empty uuid"
fi
line_in_file "$uuid /data ext4 rw,nofail 0 1" "$mnt/etc/fstab"
fi
section "Configuring new system"
uuid=$(blkid | grep "$root_device" | cut -d ' ' -f 2)
line_in_file "$uuid / ext4 errors=remount-ro 0 1" "$mnt/etc/fstab"
line_in_file "proc /proc proc defaults" "$mnt/etc/fstab"
# TODO set noauto to /boot if needed
# Set hostname
run echo "$hostname" > "$mnt/etc/hostname"
# Prenvent suspend on lid close
line_in_file HandleLidSwitch=ignore "$mnt/etc/systemd/logind.conf"
# Inform futur scripts that /data is not mounted
touch "$mnt/data/mounted"
# Fix path
run cat > "$mnt/root/.bashrc" <<EOF
PATH=$PATH:/usr/bin:/bin:/sbin:/usr/sbin:/sbin
setterm -powerdown 0
EOF
# Be sure this fucking beep is gone
echo 'set bell-style none' >> "$mnt/etc/inputrc"
# TODO find a second method to kill this doomed beep
line_in_file '@reboot root shutdownscreen.sh' "$mnt/etc/crontab"
# boot crypted
#section "Installing cryptsetup in initramfs"
#run echo 'CRYPTSETUP=y' >> /etc/cryptsetup-initramfs/conf-hook
#run cp key "$mnt/root/"
#run echo 'FILES="/root/key"' >> /etc/initramfs-tools/initramfs.conf
#run update-initramfs -ut
#echo "$mnt/etc/initramfs-tools/conf.d/cryptsetup" <<EOF
## This will setup non-us keyboards in early userspace,
## necessary for punching in passphrases.
#KEYMAP=y
#
## force busybox and cryptsetup on initramfs
#BUSYBOX=y
#CRYPTSETUP=y
#
## and for systems using plymouth instead, use the new option
#FRAMEBUFFER=y
#EOF
#echo 'export CRYPTSETUP=y' >> "$mnt/etc/environment"
#echo 'export FILES="./key"' >> "$mnt/etc/initramfs-tools/initramfs.conf"
#chroot_run 'update-initramfs -ut'
section "Set up networking"
# Disable the unpredictable naming (since we are not on the future host)
if [ ! -L "$mnt/etc/udev/rules.d/80-net-setup-link.rules" ] ; then
run ln -s /dev/null "$mnt/etc/udev/rules.d/80-net-setup-link.rules"
fi
run cat >> "$mnt/etc/network/interfaces" <<EOF
allow-hotplug eth0
iface eth0 inet dhcp
EOF
#iface eth0 inet6 dhcp
# TODO add dyndn service
section "Creating root SSH key to connect"
if [ -n "$(ls -A $secret_dir)" ]; then
#die "Secret dir '$secret_dir' is not empty"
yell "Secret dir is not empty. May erase key."
fi
run export HOSTNAME="$hostname" && ssh-keygen -b 4096 -f "$secret_dir/id_rsa" -P '' -C "access@$hostname"
run mkdir -p "$mnt/root/.ssh/"
cat "$secret_dir/id_rsa.pub" >> "$mnt/root/.ssh/authorized_keys"
chroot_run systemctl enable ssh
section "Creating wireguard conf"
if [ -n "$wireguard_number" ] ; then
run cat >> "$mnt/etc/wireguard/jeancloud.conf" <<EOF
[Interface]
PrivateKey = $(wg genkey)
ListenPort = 51812
Address = 10.98.1.$wireguard_number/32
[Peer] # debug
PublicKey = OpENQI1ElPuVdNssMySffO8iZEyJsOaSQ9bQLU6Uz2E=
AllowedIPs = 10.98.1.254/32
Endpoint = 193.33.56.94:51812
PersistentKeepalive = 25
EOF
wireguard_pubkey="$(cat "$mnt/etc/wireguard/jeancloud.conf" | grep -oP '^PrivateKey = \K.*' | wg pubkey)"
run cat > "$secret_dir/wg_conf_part" <<EOF
[Peer] # $hostname
PublicKey = $wireguard_pubkey
AllowedIPs = 10.98.1.$wireguard_number/32
EOF
chroot_run systemctl enable wg-quick@jeancloud.service
else
yell "Passing"
fi
section "Installing grub"
# Disable predictable interfaces name since we are not on the target host
run sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="net.ifnames=0 biosdevname=0"/g' "$mnt/etc/default/grub"
chroot_run update-grub
if $uefi ; then
chroot_run grub-install --efi-directory="$uefi_mountpoint" --recheck "$boot_device"
else
chroot_run grub-install --recheck "$boot_device"
fi
if [ "$arg_test" != "false" ] ; then
section "Testing installed system"
run qemu-system-x86_64 -m 1024M "$boot_device"
fi
echo "To test the system with qemu type:"
echo "qemu-system-x86_64 -m 1024M '$boot_device'"
clean