scripts/debian/chroot.install

344 lines
13 KiB
Bash
Executable File
Raw 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.

#!/bin/sh
# Vars
## Define the hard drive to use
if [ -b '/dev/sda' ]; then
hdd="/dev/sda"
else
printf '%b\n' "Please check the hard drive to use"
exit 0
fi
## Which version of Debian should be installed
debian_version="buster"
## Computer hostname
## If empty, the script will try to get one with nslookup
new_hostname=""
## Volume Group name to use for LVM
vgname="${new_hostname}vg"
## If the script should manage the partitions (delete, add,…)
manage_part=0
## If the script should use BTRFS
manage_btrfs=1
## If the script should create extra volume (eg. backup, virt, Proxmox,…)
manage_extra_lv=0
## If the script should cipher data with LUKS
manage_luks=1
## You need to set a new passphrase after the installation or at least change this one
luks_passphrase="generic key"
luks_key_file="/tmp/luks.keyfile.temp"
luks_pv_name=$(basename "${hdd}"_crypt)
## If the script should manage everything (partition, package,…) related to grub
manage_grub=0
## Colors definition {{{
BLACK='\033[49;30m'
BLACKB='\033[49;90m'
RED='\033[0;31m'
REDB='\033[1;31m'
GREEN='\033[0;32m'
YELLOW='\033[0;33m'
BLUE='\033[94;49m'
MAGENTA='\033[0;35m'
CYAN='\033[36;49m'
WHITE='\033[0;37m'
BOLD='\033[1m'
RESET='\033[0m'
## }}}
## Package to exclude from debootstrap install
dbs_pkg_exclude="vim-tiny"
## Package to include to debootstrap install
dbs_pkg_include="aptitude,btrfs-progs,bzip2,cryptsetup,debconf-i18n,dialog,dmsetup,htop,isc-dhcp-client,isc-dhcp-common,locales,lvm2,openssh-server,pciutils,thin-provisioning-tools,tmux,vim-nox,wget,zsh"
# Prepare host system {{{
apt update
apt install -y coreutils debootstrap e2fsprogs gawk ipcalc lvm2 thin-provisioning-tools parted util-linux wget || exit 1
# }}}
# Partitionning {{{
if [ "${manage_part}" -eq 0 ]; then
## Remove all old partitions {{{
for part_number in 1 2 3 4 5 6 7 8; do
[ -b "${hdd}""${part_number}" ] && parted "${hdd}" rm "${part_number}"
done
## }}}
## Recreate partition (/boot and LV) {{{
### Partition type
parted "${hdd}" mklabel gpt || exit 1
if [ "${manage_grub}" -eq 0 ]; then
### /boot
parted "${hdd}" mkpart primary 0% 512MB || exit 1
parted "${hdd}" set 1 boot on
sleep 2
mkfs.ext3 -F -L boot -- "${hdd}"1 || exit 4
### LV
root_part_id="2"
parted "${hdd}" mkpart primary 512MB 100% || exit 1
parted "${hdd}" set "${root_part_id}" lvm on
sleep 2
else
### LV
root_part_id="1"
parted "${hdd}" mkpart primary 0% 100% || exit 1
parted "${hdd}" set "${root_part_id}" lvm on
sleep 2
fi
if [ "${manage_luks}" -eq 0 ]; then
rm -f -- "${luks_key_file}" && printf '%b' "${luks_passphrase}" > "${luks_key_file}"
cryptsetup -c aes-xts-plain64 -s 512 --use-random -y luksFormat "${hdd}${root_part_id}" "${luks_passphrase}" --key-file "${luks_key_file}" || exit 2
cryptsetup luksOpen "${hdd}${root_part_id}" "${luks_pv_name}" --key-file "${luks_key_file}" || exit 2
pvcreate /dev/mapper/"${luks_pv_name}" || exit 3
vgcreate "${vgname}" /dev/mapper/"${luks_pv_name}" || exit 3
else
pvcreate "${hdd}${root_part_id}" || exit 3
vgcreate "${vgname}" "${hdd}${root_part_id}" || exit 3
fi
## }}}
## Create Logical Volumes {{{
if [ "${manage_btrfs}" -eq 0 ]; then
### Create only 1 LV for btrfs base system
[ ! -b /dev/mapper/"${vgname}"-root ] && lvcreate -n root -L 70g "${vgname}"
else
### Otherwise create differents LVs
[ ! -b /dev/mapper/"${vgname}"-home ] && lvcreate -n home -L 20g "${vgname}"
[ ! -b /dev/mapper/"${vgname}"-opt ] && lvcreate -n opt -L 2g "${vgname}"
[ ! -b /dev/mapper/"${vgname}"-root ] && lvcreate -n root -L 5g "${vgname}"
[ ! -b /dev/mapper/"${vgname}"-srv ] && lvcreate -n srv -L 2g "${vgname}"
[ ! -b /dev/mapper/"${vgname}"-tmp ] && lvcreate -n tmp -L 10g "${vgname}"
[ ! -b /dev/mapper/"${vgname}"-usr ] && lvcreate -n usr -L 15g "${vgname}"
[ ! -b /dev/mapper/"${vgname}"-var ] && lvcreate -n var -L 10g "${vgname}"
fi
### Create extra LVs
if [ "${manage_extra_lv}" -eq 0 ]; then
[ ! -b /dev/mapper/"${vgname}"-vz ] && lvcreate -n vz -L 150g "${vgname}"
[ ! -b /dev/mapper/"${vgname}"-bkp ] && lvcreate -n bkp -L 150g "${vgname}"
fi
[ ! -b /dev/mapper/"${vgname}"-swap ] && lvcreate -n swap -L 4g "${vgname}"
## }}}
## Format Logical Volumes {{{
### Format LVs in ext4
cd -- /dev/"${vgname}" || exit 1
for lvname in *; do
mkfs.ext4 -F -L "${lvname}" -- "${lvname}" || exit 4
done
cd -- - || exit 1
### (re)format Btrfs LV
if [ "${manage_btrfs}" -eq 0 ]; then
### Ensure to format Btrfs LV
mkfs.btrfs --force -L root -- /dev/"${vgname}"/root || exit 4
fi
### And format the swap
mkswap -L sw01 -- /dev/mapper/"${vgname}"-swap || exit 4
## }}}
fi
# }}}
# Debootstrap {{{
## Create and mount the system {{{
### Root
mkdir -p -- /target
mountpoint -q /target || mount -- /dev/mapper/"${vgname}"-root /target
if [ "${manage_grub}" -eq 0 ]; then
### boot - grub
mkdir -p -- /target/boot
mountpoint -q /target/boot || mount -- ${hdd}1 /target/boot
boot_uuid=$(blkid | grep "${hdd}1" | sed 's/.*1.*UUID="\(.*\)" TYPE.*/\1/')
### Prepare an fstab file
printf '%b\n' "UUID=${boot_uuid} /boot ext3 defaults 0 0" > /tmp/target.fstab
fi
### Prepare the base system tree according to the expected file system
if [ "${manage_btrfs}" -eq 0 ]; then
#### Download an extra script for Btrfs
wget -O /tmp/part.btrfs.sh "https://git.101010.fr/gardouille-dotfiles/scripts/raw/master/debian/part.btrfs.sh"
#### Create several subvolumes
chmod +x /tmp/part.btrfs.sh && /tmp/part.btrfs.sh
#### root
grep "btrfs" /etc/mtab >> /tmp/target.fstab
else ### Or for ext4, create mountpoint and mount LV
#### root
printf '%b\n' "/dev/mapper/${vgname}-root / ext4 defaults 0 0" >> /tmp/target.fstab
#### home LV
mkdir -p -- /target/home
mountpoint -q /target/home || mount -- /dev/mapper/"${vgname}"-home /target/home
printf '%b\n' "/dev/mapper/${vgname}-home /home ext4 defaults 0 0" >> /tmp/target.fstab
#### opt LV
mkdir -p -- /target/opt
mountpoint -q /target/opt || mount -- /dev/mapper/"${vgname}"-opt /target/opt
printf '%b\n' "/dev/mapper/${vgname}-opt /opt ext4 defaults 0 0" >> /tmp/target.fstab
#### srv LV
mkdir -p -- /target/srv
mountpoint -q /target/srv || mount -- /dev/mapper/"${vgname}"-srv /target/srv
printf '%b\n' "/dev/mapper/${vgname}-srv /srv ext4 defaults 0 0" >> /tmp/target.fstab
#### tmp LV
mkdir -p -- /target/tmp
chmod 0777 -- /target/tmp
mountpoint -q /target/tmp || mount -- /dev/mapper/"${vgname}"-tmp /target/tmp
printf '%b\n' "/dev/mapper/${vgname}-tmp /tmp ext4 defaults 0 0" >> /tmp/target.fstab
#### usr LV
mkdir -p -- /target/usr
mountpoint -q /target/usr || mount -- /dev/mapper/"${vgname}"-usr /target/usr
printf '%b\n' "/dev/mapper/${vgname}-usr /usr ext4 defaults 0 0" >> /tmp/target.fstab
#### var LV
mkdir -p -- /target/var
mountpoint -q /target/var || mount -- /dev/mapper/"${vgname}"-var /target/var
printf '%b\n' "/dev/mapper/${vgname}-var /var ext4 defaults 0 0" >> /tmp/target.fstab
fi
### Ensure to remove any occurence to /target mountpoint
sed -i 's;target/;;' /tmp/target.fstab
sed -i 's;target;;' /tmp/target.fstab
if [ "${manage_extra_lv}" -eq 0 ]; then
### Extra bkp LV
mkdir -p -- /target/srv/backup
mountpoint -q /target/srv/backup || mount -- /dev/mapper/"${vgname}"-bkp /target/srv/backup
printf '%b\n' "/dev/mapper/${vgname}-bkp /srv/backup ext4 defaults 0 0" >> /tmp/target.fstab
### Extra vz LV
mkdir -p -- /target/var/lib/vz
mountpoint -q /target/var/lib/vz || mount -- /dev/mapper/"${vgname}"-vz /target/var/lib/vz
printf '%b\n' "/dev/mapper/${vgname}-vz /var/lib/vz ext4 defaults 0 0" >> /tmp/target.fstab
fi
### Swap
swapon -- /dev/mapper/"${vgname}"-swap
## }}}
## Run debootstrap
debootstrap --arch amd64 --include="${dbs_pkg_include}" --exclude="${dbs_pkg_exclude}" "${debian_version}" /target http://ftp.fr.debian.org/debian || exit 1
# }}}
# Configure system {{{
## Fstab {{{
### Copy the temp fstab file to target
cp -- /tmp/target.fstab /target/etc/fstab
## }}}
## Ensure to (re)mount devices for chroot {{{
mkdir -p -- /target/dev
mountpoint -q /target/dev || mount -t devtmpfs -- none /target/dev
mkdir -p -- /target/dev/pts
mountpoint -q /target/dev/pts || mount -t devpts -- /dev/pts /target/dev/pts
mkdir -p -- /target/proc
mountpoint -q /target/proc || mount -t proc -- none /target/proc
mkdir -p -- /target/sys
mountpoint -q /target/sys || mount -t sysfs -- none /target/sys
### FIXME: /run/lvm needs to be manually set in debootstrap|chroot for Buster {{{
### See:
### https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=918590
### https://bbs.archlinux.org/viewtopic.php?pid=1820949#p1820949
mkdir -p -- /target/run/lvm
mountpoint -q /target/run/lvm || mount --bind -- /run/lvm /target/run/lvm
mkdir -p -- /target/run/udev
mountpoint -q /target/run/udev || mount --bind -- /run/udev /target/run/udev
### }}}
## }}}
## Luks {{{
if [ "${manage_luks}" -eq 0 ]; then
luks_part_uuid=$(blkid | grep "${hdd}2.*TYPE=\"crypto_LUKS\"" | sed 's/.*UUID="\(.*\)" TYPE.*/\1/')
### Ensure crypttab file contains the LUKS informations
printf '%b\n' "${luks_pv_name} UUID=${luks_part_uuid} none luks,discard" >> /target/etc/crypttab
fi
### Regenerate initramfs
chroot /target update-initramfs -k all -u
## }}}
## Network {{{
### Get all informations from current network configuration in rescue mode
net_device=$(ip r | grep "^default" | head -1 | cut -d" " -f5)
#### TODO: Switch to ip a to get ip address
net_address=$(ip r | grep -vE "(^default|metric)" | grep "${net_device}.*src" | head -1 | awk -F" " '{print $NF}')
read -r net_mac_address </sys/class/net/"${net_device}"/address
net_netmask=$(ipcalc "${net_address}" | awk '/Netmask:/{print $2;}')
net_netmask_cidr=$(ipcalc "${net_address}" | awk '/Netmask:/{print $4;}')
net_broadcast=$(ip a s dev "${net_device}" | awk '/inet.*brd/{print $4}')
net_network=$(ip r | grep -vE "(^default|metric)" | grep "src ${net_address}" | head -1 | cut -d"/" -f1)
net_gateway=$(ip r | grep "^default" | head -1 | cut -d" " -f3)
### Create a network unit for systemd-networkd
printf '%b' "[Match]
MACAddress=${net_mac_address}
[Network]
Description=network interface with default route without dhcp
DHCP=no
Address=${net_address}/${net_netmask_cidr}
Gateway=${net_gateway}
IPv6AcceptRA=no
DNS=80.67.169.12
" > /target/etc/systemd/network/50-default.network
### Ensure to enable systemd-networkd at startup
chroot /target systemctl enable systemd-networkd
## }}}
## Locale {{{
### Enable locale(s)
sed -i 's/^# \(en_US.UTF-8 UTF-8\)/\1/' /target/etc/locale.gen
#sed -i 's/^# \(fr_FR.UTF-8 UTF-8\)/\1/' /target/etc/locale.gen
chroot /target locale-gen
## }}}
## Timezone {{{
### Set timezone
printf '%b\n' "Europe/Paris" > /target/etc/timezone
ln -fs /usr/share/zoneinfo/Europe/Paris /target/etc/localtime
chroot /target dpkg-reconfigure --frontend noninteractive tzdata
## }}}
## Kernel and Grub {{{
### Install
if [ "${manage_grub}" -eq 0 ]; then
chroot /target aptitude install --assume-yes --without-recommends -- linux-image-amd64 grub-pc
chroot /target grub-install "${hdd}"
chroot /target update-grub
else
chroot /target aptitude install --assume-yes --without-recommends -- linux-image-amd64
fi
## }}}
## Hostname {{{
if [ -z "${new_hostname}" ]; then
lookup_hostname=$(nslookup "${net_address}" || echo "server name = new_server")
get_hostname=$(echo "${lookup_hostname}" | awk '/name =/{print $4;}' | cut -d. -f1)
printf '%b\n' "${get_hostname}" > /target/etc/hostname
else
printf '%b\n' "${new_hostname}" > /target/etc/hostname
fi
#printf '%b\n' "127.0.0.1 ${new_hostname}" >> /target/etc/hosts
## }}}
# }}}
# Finish {{{
## Call a latecommand script {{{
wget -O /tmp/latecommand.tar.gz "https://git.ipr.univ-rennes1.fr/cellinfo/tftpboot/raw/master/scripts/latecommand.tar.gz" --no-check-certificate
tar xzf /tmp/latecommand.tar.gz -C /target/tmp/
chroot /target /usr/bin/env debian_version="${debian_version}" /bin/sh /tmp/latecommand/post."${debian_version}".sh
## }}}
## SSH {{{
### Allow root connections - this should be fixed if it works
sed -i 's/\(^\|^\#\)\(PermitRootLogin\).*/\2 yes/g' /target/etc/ssh/sshd_config
### Add current authorized_keys from the rescue system if present
if [ -f /root/.ssh/authorized_keys ]; then
mkdir -p -- /target/root/.ssh
cp -- /root/.ssh/authorized_keys /target/root/.ssh/authorized_keys
else
printf '%b\n' "${REDB}You might want to define an authorized key for SSH/root in /target/etc/ssh/sshd_config${RESET}"
fi
## }}}
printf '%b\n' "${REDB}Please change the root's password:${RESET}"
chroot /target passwd
# Ensure to umount everything
#umount /target/var/lib/vz/ /target/var/ /target/usr/ /target/tmp/ /target/sys/ /target/srv/backup/ /target/srv/ /target/proc/ /target/opt/ /target/home/ /target/dev/pts/ /target/dev /target/boot/ /target/
printf '%b\n' "${GREEN}The system is still available on /target but you can now try to reboot the hardware.${RESET}"
exit 0
# }}}