840 lines
28 KiB
Bash
840 lines
28 KiB
Bash
#!/usr/bin/env zsh
|
|
# shellcheck shell=bash
|
|
# Copyright (c) 2016-2021 Ivan J. <parazyd@dyne.org>
|
|
# This file is part of libdevuansdk
|
|
#
|
|
# This source code is free software: you can redistribute it and/or modify
|
|
# it under the terms of the GNU General Public License as published by
|
|
# the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This software is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this source code. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
build_metal_dist() {
|
|
fn build_metal_dist
|
|
req=(arch)
|
|
req+=(workdir strapdir disk_name)
|
|
ckreq || return 1
|
|
|
|
notice "installing complete dist"
|
|
act "add release symlink to debootstrap scripts."
|
|
if [[ ! -f /usr/share/debootstrap/scripts/${release} ]]; then
|
|
ln -sf /usr/share/debootstrap/scripts/ceres \
|
|
/usr/share/debootstrap/scripts/${release}
|
|
fi
|
|
|
|
image_partition_disk_zfs || { zerr; wrapup }
|
|
image_format_partitions_zfs || { zerr; wrapup }
|
|
bootstrap_complete_base || { zerr; wrapup }
|
|
blend_preinst || { zerr; wrapup }
|
|
blend_postinst || { zerr; wrapup }
|
|
}
|
|
|
|
|
|
# Overide the post 'debootstrap stage 2' placeholder function of zlib/debootstrap bootstrap_complete_base.
|
|
# The default is just to return 0
|
|
blend_bootstrap_setup() {
|
|
fn blend_bootstrap_setup "noop"
|
|
return 0
|
|
}
|
|
|
|
## Override the helper function:
|
|
# takes the 'apt-get -f' out of the loop so that dependency provided by other debs can be resolved.
|
|
# inside the loop it just uninstalls the deb because of unfullfilled deps.
|
|
install-custdebs() {
|
|
fn install-custdebs "(override)"
|
|
req=(R strapdir custom_deb_packages)
|
|
ckreq || return 1
|
|
|
|
sudo mkdir -p ${strapdir}/debs
|
|
sudo cp $R/extra/custom-packages/*.deb ${strapdir}/debs/
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/install-debs >/dev/null
|
|
#!/bin/sh
|
|
cd /debs
|
|
for deb in ${custom_deb_packages}; do
|
|
dpkg -i \$deb
|
|
done
|
|
apt-get --yes --force-yes -f install
|
|
cd /
|
|
apt-get --yes --force-yes autoremove
|
|
#rm -rf /debs
|
|
EOF
|
|
chroot-script -d install-debs
|
|
}
|
|
|
|
## Added function:
|
|
# In the style of install-custdebs above but for a collection of arbitrary scripts placed in a
|
|
# directory alongside the blend custom debs called automate.
|
|
# The scripts are copied from the blends scripts directory to extra/custom-scripts in blend_preinst() above.
|
|
# Called after install-customdebs because some need checkinstall which disappears from archives.
|
|
install-custscripts() {
|
|
fn install-custscripts
|
|
req=(R strapdir custom_scripts)
|
|
ckreq || return 1
|
|
|
|
sudo mkdir -p ${strapdir}/var/tmp/automate
|
|
sudo cp $R/extra/custom-scripts/*.sh ${strapdir}/var/tmp/automate/
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/install-scripts >/dev/null
|
|
#!/bin/sh
|
|
cd /var/tmp/automate
|
|
for script in ${custom_scripts}; do
|
|
touch \${script}.log
|
|
bash \$script
|
|
done
|
|
apt-get --yes --force-yes -f install
|
|
cd /
|
|
apt-get --yes --force-yes autoremove
|
|
#rm -rf /var/tmp/automate
|
|
EOF
|
|
chroot-script -d install-scripts
|
|
}
|
|
|
|
## Override the helper function:
|
|
# Allow an alternative skel directory
|
|
add-user() {
|
|
fn add-user $*
|
|
local user="$1"
|
|
local pass="$2"
|
|
local skel="$3"
|
|
req=(strapdir user pass skel)
|
|
ckreq || return 1
|
|
|
|
notice "adding user $user:$pass using $skel"
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/adduser >/dev/null
|
|
#!/bin/sh
|
|
set -x
|
|
if [ $(id -u ${user} 2>&1 >/dev/null) ]; then
|
|
echo "user not present, creating account."
|
|
useradd -m ${user} -k ${userskel:-/etc/skel}
|
|
|
|
echo "${user}:${pass}" | chpasswd
|
|
fi
|
|
EOF
|
|
chroot-script adduser || { zerr; return 0; }
|
|
}
|
|
|
|
|
|
## apt related functions
|
|
# point apt at a local apt-proxy like apt-cacher-ng
|
|
enable_apt-proxy() {
|
|
fn enable_apt-proxy
|
|
req=(strapdir apt_proxy)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/add_apt-proxy
|
|
#!/bin/sh
|
|
|
|
cat > '/etc/apt/apt.conf.d/02proxy' << 'FOE'
|
|
Acquire::http { Proxy "${apt_proxy}"; };
|
|
FOE
|
|
EOF
|
|
chroot-script add_apt-proxy || zerr
|
|
}
|
|
|
|
disable_apt-proxy() {
|
|
fn disable_apt-proxy
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/del_apt-proxy
|
|
#!/bin/sh
|
|
rm -f /etc/apt/apt.conf.d/02proxy
|
|
EOF
|
|
chroot-script del_apt-proxy || zerr
|
|
}
|
|
|
|
|
|
|
|
# When the release changes its suite (ie. from stable to oldstable) by default apt asks for explicite acceptance, which you might not want in your image, turn this on and off.
|
|
enable_apt-allow-releaseinfo-change() {
|
|
fn enable_apt-allow-releaseinfo-change
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/add_apt-releaseinfo-change
|
|
#!/bin/sh
|
|
|
|
cat > '/etc/apt/apt.conf.d/10no-check-valid-until' << 'FOE'
|
|
Acquire::AllowReleaseInfoChange::Suite "true";
|
|
FOE
|
|
EOF
|
|
chroot-script add_apt-releaseinfo-change || zerr
|
|
}
|
|
|
|
disable_apt-allow-releaseinfo-change() {
|
|
fn disable_apt-allow-releaseinfo-change
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/del_apt-allow-releaseinfo-change
|
|
#!/bin/sh
|
|
#
|
|
rm -f /etc/apt/apt.conf.d/10no-check-valid-until
|
|
EOF
|
|
chroot-script del_apt-allow-releaseinfo-change || zerr
|
|
}
|
|
|
|
# apt checks the valid-util and refuses to install from repositories that are too old, which you might not want if building an old release, turn this on or off.
|
|
disable_apt-valid-until() {
|
|
fn disable_apt-valid-until
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/add_apt-check-valid
|
|
#!/bin/sh
|
|
|
|
cat > '/etc/apt/apt.conf.d/10no-check-valid-until' << 'FOE'
|
|
Acquire::Check-Valid-Until "false";
|
|
FOE
|
|
EOF
|
|
chroot-script add_apt-check-valid || zerr
|
|
}
|
|
|
|
enable_apt-valid-until() {
|
|
fn enable_apt-valid-until
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/del_apt-check-valid
|
|
#!/bin/sh
|
|
rm -f /etc/apt/apt.conf.d/10no-check-valid-until
|
|
EOF
|
|
chroot-script del_apt-check-valid || zerr
|
|
}
|
|
|
|
# Overide the sdk version of this function to prevent deletion
|
|
# prior to unpacking the cpio as we have mountpoints in place
|
|
# when installing to hardrive.
|
|
bootstrap_cpio_unpack()
|
|
{
|
|
fn bootstrap_cpio_unpack "$*"
|
|
req=(_bootstrap_cpio strapdir)
|
|
local _bootstrap_cpio="$1"
|
|
ckreq || return 1
|
|
|
|
notice "Unpacking bootstrap cpio archive: $_bootstrap_cpio"
|
|
|
|
#sudo rm -rf "${strapdir}"/*
|
|
|
|
pushd "$strapdir" || { zerr; return 1; }
|
|
zcat "$_bootstrap_cpio" | sudo cpio -idmn --format=newc || { zerr; return 1; }
|
|
popd
|
|
|
|
sudo mkdir -p "$strapdir"/{boot,dev,proc,sys}
|
|
}
|
|
|
|
image_partition_disk_zfs() {
|
|
fn image_partition_disk_zfs
|
|
req=(strapdir disk_name efi_start efi_part_size swap_part_size boot_part_size available_disks)
|
|
ckreq || return 1
|
|
|
|
notice "partitioning disks"
|
|
|
|
# See: https://didrocks.fr/2020/06/11/zfs-focus-on-ubuntu-20.04-lts-zsys-partition-layout/
|
|
for disk in "${available_disks[@]}"; do
|
|
TARGET="/dev/disk/by-id/${disk}"
|
|
|
|
act "partitioning ${TARGET}"
|
|
/sbin/sgdisk --zap-all ${TARGET}
|
|
|
|
act "Partition 1 - Create partition using start and end values for partitioning the 'Bios boot' partition."
|
|
FIRST_USABLE_SECTOR=34
|
|
((ENDSECTOR = ${efi_start} - 1))
|
|
/sbin/sgdisk --print --set-alignment=1 --new=1:${FIRST_USABLE_SECTOR}:${ENDSECTOR} ${TARGET}
|
|
/sbin/sgdisk --print --change-name=1:"BIOS_Boot_Partition" --typecode=1:EF02 ${TARGET}
|
|
|
|
act "Partition 2 - Create partition using start and end values for partitioning the 'EFI' partition."
|
|
STARTSECTOR=${efi_start}
|
|
/sbin/sgdisk --print --set-alignment=${STARTSECTOR} --mbrtogpt --new=2:${STARTSECTOR}:+${efi_part_size} ${TARGET}
|
|
/sbin/sgdisk --print --change-name=2:"EFI_System_Partition" --typecode=2:EF00 ${TARGET}
|
|
|
|
act "Partition 3 - Create partition using start and end values for partitioning the 'swap' partition."
|
|
STARTSECTOR=`/sbin/sgdisk --first-in-largest ${TARGET}|sed -sn 2p`
|
|
/sbin/sgdisk --print --new=3:${STARTSECTOR}:+${swap_part_size} ${TARGET}
|
|
/sbin/sgdisk --print --change-name=3:"Linux_swap" --typecode=3:8200 ${TARGET}
|
|
|
|
act "Partition 4 - upto 2GB partition for boot."
|
|
STARTSECTOR=`/sbin/sgdisk --first-in-largest ${TARGET}|sed -sn 2p`
|
|
/sbin/sgdisk --print --new=4:${STARTSECTOR}:+${boot_part_size} ${TARGET}
|
|
/sbin/sgdisk --print --change-name=4:boot --typecode=4:BE00 ${TARGET}
|
|
|
|
act "Partition 5 - the main partition for root."
|
|
/sbin/sgdisk --print --largest-new=5 ${TARGET}
|
|
/sbin/sgdisk --print --change-name=5:root --typecode=5:BF00 ${TARGET}
|
|
|
|
act "Reread the current partition tables with partprobe."
|
|
# the second drive fails to update the kernel until reboot so added 2>
|
|
#partprobe ${TARGET} 2>/dev/null || true
|
|
hdparm -z ${TARGET}
|
|
done
|
|
}
|
|
|
|
image_format_partitions_zfs() {
|
|
fn image_format_partitions_zfs
|
|
req=(disk_name available_disks efi_partitions swap_partitions root_part_number boot_part_number rpool_name bpool_name zpool_cache_dir strapdir)
|
|
ckreq || return 1
|
|
|
|
act "format available efi partitions to vfat."
|
|
for efi_partition in "${efi_partitions[@]}"; do
|
|
act "format the efi partition to vfat."
|
|
mkfs.fat -F32 ${efi_partition}
|
|
done
|
|
|
|
act "mkswap on available swap partitions."
|
|
for swap_partition in "${swap_partitions[@]}"; do
|
|
notice "making swap on ${swap_partition}"
|
|
mkswap ${swap_partition}
|
|
done
|
|
|
|
notice "formatting zfs partitions..."
|
|
|
|
for disk in "${available_disks[@]}"; do
|
|
gdisk -l /dev/disk/by-id/${disk}
|
|
done
|
|
|
|
act "udev is slow recognize new partition so trigger sleep for 10 seconds"
|
|
sleep 10
|
|
|
|
|
|
# create a separate boot pool for /boot with the features limited to only those that GRUB supports
|
|
# allowing the root pool to use any/all features.
|
|
|
|
if [[ ${raid} == "mirror" ]]; then
|
|
mirror_disk=${available_disks[2]};
|
|
fi
|
|
|
|
act "create the zfs boot pool"
|
|
#zpool create -f -m none \
|
|
zpool create -f \
|
|
-o cachefile=${zpool_cache_dir}/zpool.cache \
|
|
-o ashift=${ashift} -d \
|
|
-o feature@async_destroy=enabled \
|
|
-o feature@bookmarks=enabled \
|
|
-o feature@embedded_data=enabled \
|
|
-o feature@empty_bpobj=enabled \
|
|
-o feature@enabled_txg=enabled \
|
|
-o feature@extensible_dataset=enabled \
|
|
-o feature@filesystem_limits=enabled \
|
|
-o feature@hole_birth=enabled \
|
|
-o feature@large_blocks=enabled \
|
|
-o feature@lz4_compress=enabled \
|
|
-o feature@spacemap_histogram=enabled \
|
|
-o feature@zpool_checkpoint=enabled \
|
|
-O acltype=posixacl \
|
|
-O canmount=off \
|
|
-O compression=lz4 \
|
|
-O devices=off \
|
|
-O normalization=formD \
|
|
-O relatime=on \
|
|
-O xattr=sa \
|
|
-O mountpoint=/boot -o altroot=${strapdir} \
|
|
${bpool_name} ${raid} /dev/disk/by-id/${disk_name}-part${boot_part_number} ${mirror_disk}
|
|
|
|
|
|
act "create the zfs root pool"
|
|
|
|
zpool create -f \
|
|
-o cachefile=${zpool_cache_dir}/zpool.cache \
|
|
-o ashift=${ashift} \
|
|
-O acltype=posixacl \
|
|
-O canmount=off \
|
|
-O compression=lz4 \
|
|
-O dnodesize=auto \
|
|
-O normalization=formD \
|
|
-O relatime=on \
|
|
-O xattr=sa \
|
|
-O mountpoint=/ -o altroot=${strapdir} \
|
|
${rpool_name} ${raid} /dev/disk/by-id/${disk_name}-part${root_part_number} ${mirror_disk}
|
|
|
|
|
|
## Physical swap used instead.
|
|
#act "create the zfs zvol for swap"
|
|
#zfs create -V ${swap_part_size} -b $(getconf PAGESIZE) \
|
|
# -o compression=zle \
|
|
# -o logbias=throughput \
|
|
# -o sync=always \
|
|
# -o primarycache=metadata \
|
|
# -o secondarycache=none \
|
|
# -o com.sun:auto-snapshot=false \
|
|
# ${rpool_name}/swap
|
|
#mkswap -f -L "Linux swap" /dev/zvol/${rpool_name}/swap
|
|
|
|
notice "zfs system installation"
|
|
act "create filesystem datasets to act as containers"
|
|
zfs create -o canmount=off -o mountpoint=none ${rpool_name}/ROOT
|
|
zfs create -o canmount=off -o mountpoint=none ${bpool_name}/BOOT
|
|
|
|
act "create filesystem datasets for the root and boot filesystems"
|
|
# Create the initial boot environment and mount ${rpool_name} at /${rpool_name}
|
|
zfs create -o canmount=noauto -o mountpoint=/ ${rpool_name}/ROOT/${root_name}
|
|
zfs mount ${rpool_name}/ROOT/${root_name}
|
|
|
|
#zfs create -o canmount=noauto -o mountpoint=/boot ${bpool_name}/BOOT/${root_name}
|
|
zfs create -o mountpoint=/boot ${bpool_name}/BOOT/${root_name}
|
|
|
|
# At this point rpool directory is created in the workdir
|
|
#zfs set mountpoint=/${rpool_name} ${rpool_name}
|
|
|
|
TMP_EXEC_STATE=on
|
|
VAR_TMP_EXEC_STATE=on
|
|
|
|
notice "create datasets"
|
|
act "create zfs datasets for $rpool_name"
|
|
zfs create -o mountpoint=/home ${rpool_name}/home
|
|
zfs create -o mountpoint=/root ${rpool_name}/home/root
|
|
zfs create -o mountpoint=/space ${rpool_name}/space
|
|
zfs create -o mountpoint=/opt ${rpool_name}/opt
|
|
zfs create -o mountpoint=/srv ${rpool_name}/srv
|
|
|
|
zfs create -o mountpoint=/usr \
|
|
-o canmount=off \
|
|
${rpool_name}/usr
|
|
|
|
zfs create -o mountpoint=/usr/share ${rpool_name}/usr/share
|
|
zfs create -o mountpoint=/usr/local ${rpool_name}/usr/local
|
|
|
|
zfs create -o mountpoint=/tmp \
|
|
-o setuid=off \
|
|
-o exec=${TMP_EXEC_STATE} \
|
|
-o com.sun:autosnapshot=false \
|
|
${rpool_name}/tmp
|
|
|
|
zfs create -o mountpoint=/var \
|
|
-o canmount=off \
|
|
${rpool_name}/var
|
|
|
|
zfs create -o mountpoint=/var/lib ${rpool_name}/var/lib
|
|
|
|
zfs create -o mountpoint=/var/lib/virt ${rpool_name}/var/lib/virt
|
|
|
|
zfs create -o mountpoint=/var/tmp \
|
|
-o setuid=off \
|
|
-o com.sun:auto-snapshot=false \
|
|
-o exec=${VAR_TMP_EXEC_STATE} \
|
|
${rpool_name}/var/tmp
|
|
|
|
zfs create -o mountpoint=/var/cache \
|
|
-o com.sun:auto-snapshot=false \
|
|
${rpool_name}/var/cache
|
|
|
|
zfs create \
|
|
-o mountpoint=/var/lib/docker \
|
|
-o com.sun:autosnapshot=false \
|
|
${rpool_name}/docker
|
|
|
|
zfs create -o mountpoint=/var/log ${rpool_name}/var/log
|
|
zfs create -o mountpoint=/var/snap ${rpool_name}/var/snap
|
|
zfs create -o mountpoint=/var/spool ${rpool_name}/var/spool
|
|
zfs create -o mountpoint=/var/www ${rpool_name}/var/www
|
|
|
|
|
|
zfs list -t all -o name,type,mountpoint,compress,exec,setuid,atime,relatime
|
|
|
|
chmod 700 ${strapdir}/root
|
|
chmod 1777 ${strapdir}/tmp
|
|
#chmod 1777 ${strapdir}/var/tmp
|
|
|
|
act "mount the efi partition on ${grub_mount} before debootstrap."
|
|
mount /dev/disk/by-id/${disk_name}-part${efi_part_number} -t vfat ${strapdir}${grub_mount}
|
|
|
|
act "create zpool cache file"
|
|
mkdir -p ${strapdir}/etc/zfs
|
|
cp ${zpool_cache_dir}/zpool.cache ${strapdir}/etc/zfs/
|
|
}
|
|
|
|
use_swap_partition() {
|
|
fn use_swap_partition
|
|
req=(swap_partitions)
|
|
ckreq || return 1
|
|
|
|
for swap_partition in "${swap_partitions[@]}"; do
|
|
act "Using swapon on ${swap_partition}"
|
|
swapon ${swap_partition}
|
|
done
|
|
}
|
|
|
|
image_zfs_mount() {
|
|
fn image_zfs_mount
|
|
req=(strapdir disk_name rpool_name bpool_name grub_mount)
|
|
ckreq || return 1
|
|
|
|
notice "image_zfs_mount"
|
|
|
|
act "importing zfs pools without mounting the filesystem"
|
|
zpool import -N -R ${strapdir} ${rpool_name}
|
|
zpool import -N -R ${strapdir} ${bpool_name}
|
|
|
|
if [[ -n $encrypt ]]; then
|
|
act "loading encryption keys of ZFS datasets from imported pools"
|
|
zfs load-key -a
|
|
fi
|
|
|
|
act "mounting zfs datasets"
|
|
zfs mount -v ${rpool_name}/ROOT/${root_name}
|
|
zfs mount -v ${bpool_name}/BOOT/${root_name}
|
|
zfs mount -v -a
|
|
|
|
act "mount efi partition to /boot/grub"
|
|
mkdir -p ${strapdir}${grub_mount}
|
|
mount /dev/disk/by-id/${disk_name}-part${efi_part_number} -t vfat ${strapdir}${grub_mount}
|
|
|
|
act "mount system directories"
|
|
devprocsys mount ${strapdir}
|
|
}
|
|
|
|
image_zfs_umount() {
|
|
fn image_zfs_umount
|
|
req=(workdir strapdir rpool_name bpool_name)
|
|
ckreq || return 1
|
|
|
|
notice "umount system directories"
|
|
devprocsys umount ${strapdir}
|
|
|
|
act "reaping chroot processes"
|
|
PREFIX=${strapdir}
|
|
FOUND=0
|
|
|
|
reap() {
|
|
for ROOT in /proc/*/root; do
|
|
LINK=$(readlink $ROOT)
|
|
if [[ "x${LINK}" != "x" ]]; then
|
|
if [[ "x${LINK:0:${#PREFIX}}" = "x${PREFIX}" ]]; then
|
|
PID=$(basename $(dirname "$ROOT"))
|
|
act "this process is in the chroot... $PID"
|
|
kill -9 "$PID"
|
|
FOUND=1
|
|
fi
|
|
fi
|
|
done
|
|
}
|
|
|
|
reap
|
|
|
|
if [[ "x$FOUND" = "x1" ]]; then
|
|
reap
|
|
fi
|
|
|
|
act "umount efi partition"
|
|
efi_path=/dev/disk/by-id/${disk_name}-part${efi_part_number}
|
|
if [[ $(/bin/mountpoint -q -- ${efi_path}) ]]; then
|
|
umount --lazy ${efi_path}
|
|
fi
|
|
|
|
act "umount zfs partitions"
|
|
COUNT=0
|
|
|
|
while grep -q "$PREFIX" /proc/mounts; do
|
|
COUNT=$(($COUNT+1))
|
|
if [ $COUNT -ge 20 ]; then
|
|
echo "failed to umount $PREFIX"
|
|
if [ -x /usr/bin/lsof ]; then
|
|
/usr/bin/lsof "$PREFIX"
|
|
fi
|
|
exit 1
|
|
fi
|
|
grep "$PREFIX" /proc/mounts | \
|
|
cut -d\ -f2 | LANG=C sort -r | xargs -r -n 1 umount || sleep 1
|
|
done
|
|
|
|
act "export zfs pools."
|
|
zpool export ${bpool_name}
|
|
zpool export ${rpool_name}
|
|
}
|
|
|
|
get_selections() {
|
|
fn get_selections
|
|
req=(strapdir blend_release_path)
|
|
ckreq || return 1
|
|
|
|
notice "generating package list files to ${blend_release_path}"
|
|
pushd "${blend_release_path}"
|
|
dpkg --get-selections > packages.list
|
|
debconf-get-selections > debconf-settings.list
|
|
update-alternatives --get-selections > /var/tmp/alternatives-settings.list
|
|
/usr/bin/apt-mark showauto > pkgs_auto.lst
|
|
/usr/bin/apt-mark showmanual > pkgs_manual.lst
|
|
popd
|
|
}
|
|
|
|
set_selections() {
|
|
fn set_selections
|
|
req=(strapdir blend_release_path)
|
|
ckreq || return 1
|
|
pushd "${blend_release_path}"
|
|
notice "copying set selections related files to ${strapdir}/var/tmp"
|
|
if [[ -f ./packages.list ]]; then
|
|
cp ./packages.list ${strapdir}/var/tmp
|
|
else
|
|
act "no package.list found in ${blend_release_path} "
|
|
exit 0
|
|
fi
|
|
if [[ -f ./debconf-settings.list ]]; then
|
|
cp ./debconf-settings.list ${strapdir}/var/tmp
|
|
else
|
|
act "no debconf-settings.list found in ${blend_release_path} "
|
|
exit 0
|
|
fi
|
|
if [[ -f ./alternatives-settings.list ]]; then
|
|
cp ./alternatives-settings.list ${strapdir}/var/tmp
|
|
else
|
|
act "no alternatives-settings.list found in ${blend_release_path} "
|
|
exit 0
|
|
fi
|
|
if [[ -f ./pkgs_auto.lst ]]; then
|
|
cp ./pkgs_auto.lst ${strapdir}/var/tmp
|
|
else
|
|
act "no pkgs_auto.lst found in ${blend_release_path}"
|
|
fi
|
|
if [[ -f ./pkgs_auto.lst ]]; then
|
|
cp ./pkgs_manual.lst ${strapdir}/var/tmp
|
|
else
|
|
act "no pkgs_manual.lst found in ${blend_release_path}"
|
|
fi
|
|
popd
|
|
|
|
notice "upgrading using dselect"
|
|
cat <<-EOF | sudo tee "$strapdir/install-set-selections" >/dev/null
|
|
#!/bin/sh
|
|
dpkg --set-selections 2>&1 < /var/tmp/packages.list
|
|
debconfig-set-selections 2>&1 < /var/tmp/debconf-settings.list
|
|
update-alternatives --set-selections 2>&1 < /var/tmp/alternatives-settings.list
|
|
apt-get -y -u dselect-upgrade
|
|
|
|
if [[ -f /var/tmp/pkgs_auto.lst ]]; then
|
|
apt-mark auto $(cat /var/tmp/pkgs_auto.lst)
|
|
fi
|
|
if [[ -f /var/tmp/pkgs_manual.lst ]]; then
|
|
apt-mark manual $(cat /var/tmp/pkgs_manual.lst)
|
|
fi
|
|
EOF
|
|
chroot-script -d install-set-selections || { zerr; return 1; }
|
|
}
|
|
|
|
enablessh() {
|
|
fn enablessh
|
|
req=(strapdir)
|
|
ckreq || return 1
|
|
|
|
notice "enabling ssh access without password."
|
|
act "Use ssh-copy-id default@192.168.1.x to login on reboot."
|
|
|
|
act "adding or creating keys (place keys in /etc/ssh/ssh_host_rsa_key.pub)"
|
|
cat <<-EOF | sudo tee "$strapdir/etc/rc.local" >/dev/null
|
|
#!/bin/sh
|
|
# rc.local for base images
|
|
|
|
[ -f /etc/ssh/ssh_host_rsa_key.pub ] || ssh-keygen -A
|
|
|
|
exit 0
|
|
EOF
|
|
|
|
sudo chmod +x "$strapdir/etc/rc.local"
|
|
|
|
cat <<-EOF | sudo tee "$strapdir/enablessh" >/dev/null
|
|
#!/usr/bin/env zsh
|
|
set -x ; exec 2>${PWD}/enablessh.log
|
|
|
|
config_file="/tmp/sshd_config"
|
|
|
|
typeset -A rules
|
|
rules=(
|
|
"LoginGraceTime" "1m"
|
|
"PermitRootLogin" "yes"
|
|
"PasswordAuthentication" "no"
|
|
"AllowUsers" "${username}"
|
|
)
|
|
EOF
|
|
|
|
cat <<-'EOF' | sudo tee -a "$strapdir/enablessh" >/dev/null
|
|
|
|
for rule in "${(@k)rules}"; do
|
|
regex="s/^#\?\(${rule}\s*\).*$/\1 ${rules[${rule}]}/"
|
|
sed -i "${regex}" ${config_file};
|
|
done
|
|
EOF
|
|
chroot-script -d enablessh || { zerr; return 1; }
|
|
}
|
|
|
|
install_kernel_headers() {
|
|
fn install_kernel_headers
|
|
req=(strapdir kernel_version arch)
|
|
ckreq || return 1
|
|
|
|
# could go in blends/devuan-desktop-live/config $extra_packages and
|
|
# remove headers in blends/devuan-desktop-live/chimaera/config $purge_packages
|
|
|
|
notice "install kernel headers"
|
|
cat <<-EOF | sudo tee "$strapdir/install-kernel-headers" >/dev/null
|
|
#!/bin/sh
|
|
apt-get install -y linux-image-${kernel_version}-${arch}
|
|
apt-get install -y linux-headers-${kernel_version}-${arch}
|
|
apt-get -y -f install
|
|
EOF
|
|
chroot-script -d install-kernel-headers || { zerr; return 1; }
|
|
}
|
|
|
|
install_zfs() {
|
|
fn install_zfs
|
|
req=(strapdir rpool_name bpool_name root_name grubversion)
|
|
ckreq || return 1
|
|
|
|
act "install zfs to the $strapdir"
|
|
act "install the zfs packages in the correct order before dselect upgrade"
|
|
cat <<-EOF | sudo tee "$strapdir/install-zfs" >/dev/null
|
|
#!/bin/sh
|
|
apt-get remove -y live-config && apt-get -y autoremove
|
|
apt-get install -y spl-dkms dh-autoreconf
|
|
apt-get install -y zfs-dkms zfs-initramfs zfsnap zfsutils-linux ${grubversion} busybox console-setup
|
|
apt-get -y -f install
|
|
|
|
# add nouveau graphics setting before updating initramfs: add to the grub commandline with
|
|
update-initramfs -u
|
|
|
|
# zfs_autoimport_disable is now compiled as set to 1/true by default
|
|
# At module load 0=read zpool.cache 1=do not read zpool.cache
|
|
#echo '# https://openzfs.github.io/openzfs-docs/Performance and Tuning/Module Parameters.html' > /etc/modprobe.d/zfs.conf
|
|
#echo 'options zfs zfs_autoimport_disable=0' >> /etc/modprobe.d/zfs.conf
|
|
|
|
echo 'options zfs l2arc_write_max=50331648' >> /etc/modprobe.d/zfs.conf
|
|
echo 'options zfs l2arc_write_boost=100663296' >> /etc/modprobe.d/zfs.conf
|
|
|
|
# Additional datasets to /etc/default/zfs not created under ROOT
|
|
sed -i "s/#ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\"/" /etc/default/zfs
|
|
#
|
|
sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/home\"/" /etc/default/zfs
|
|
sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/space\"/" /etc/default/zfs
|
|
sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/tmp\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/opt\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/usr_share\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/usr_local\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var_lib\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var_lib_docker\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var_lib_virt\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var_tmp\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/usr\"/" /etc/default/zfs
|
|
#sed -i "s/ZFS_INITRD_ADDITIONAL_DATASETS=\"\(.*\)\"/ZFS_INITRD_ADDITIONAL_DATASETS=\"\1 ${rpool_name}\/ROOT\/${root_name}\/var\"/" /etc/default/zfs
|
|
EOF
|
|
chroot-script -d install-zfs || { zerr; return 1; }
|
|
}
|
|
|
|
install_grub(){
|
|
fn install_grub
|
|
req=(strapdir disk_name efi_partitions swap_part_number rpool_name bpool_name root_name grub_mount grub_theme grub_gfxmode)
|
|
ckreq || return 1
|
|
|
|
notice "installing grub."
|
|
|
|
act "move the grub theme to the grub partition, stops 'update-alternatives desktop-grub-theme' from working."
|
|
mkdir -p /boot/grub/grub-themes
|
|
cp -a /usr/share/desktop-base/grub-themes/${grub_theme} /boot/grub/grub-themes/
|
|
|
|
|
|
act "replace the pool name detection with zdb command in /etc/grub.d/10_linux."
|
|
sed -i "s|rpool=.*|rpool=\`zdb -l \${GRUB_DEVICE} \| grep -E '[[:blank:]]name' \| cut -d\\\' -f 2\`|" $strapdir/etc/grub.d/10_linux
|
|
|
|
|
|
act "change the grub kernel commandline"
|
|
cat <<-EOF | sudo tee "$strapdir/write-default-grub" >/dev/null
|
|
#!/bin/sh
|
|
set -x
|
|
# GRUB_CMDLINE_LINUX_DEFAULT="quiet resume=/dev/zvol/rpool/swap radeon:modeset=1 i915:modeset=1 cgroup_enable=memory swapaccount=1 net.ifnames=0
|
|
|
|
# set boot filesystem - duplicated by grub but misses rpool_name when grub-probe fails to read filesystem type.
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 zfs=${rpool_name}\"|" /etc/default/grub
|
|
|
|
# set swap as the resume partition.
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 resume=/dev/disk/by-id/${disk_name}-part${swap_part_number}\"|" /etc/default/grub
|
|
|
|
# set root - Not needed as the kernel and root are set before /etc/default/grub is added
|
|
#sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 root=ZFS=${rpool_name}\/ROOT\/${root_name}\"|" /etc/default/grub
|
|
|
|
# init_on_alloc=1 is a security hardening mechanism preventing a class of security issues from being exploitable.
|
|
# init_on_alloc=1 causes big performance regression for zfs: ubuntu +bug/1862822
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 init_on_alloc=0\"|" /etc/default/grub
|
|
|
|
# enable udev "info" logging for block devices
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 rd.log.block=info\"|" /etc/default/grub
|
|
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 cgroup_enable=memory\"|" /etc/default/grub
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 swapaccount=1\"|" /etc/default/grub
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 net.ifnames=0\"|" /etc/default/grub
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 nouveau.modeset=1\"|" /etc/default/grub
|
|
#sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 i915.modeset=1\"|" /etc/default/grub
|
|
#sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 radeon.modeset=1\"|" /etc/default/grub
|
|
sed -i "s|^GRUB_CMDLINE_LINUX_DEFAULT=\"\(.*\)\"|GRUB_CMDLINE_LINUX_DEFAULT=\"\1 noplymouth nosplash\"|" /etc/default/grub
|
|
sed -i '/^#GRUB_DISABLE_LINUX_UUID=.*/ s/.*/&\nGRUB_DISABLE_LINUX_UUID=true/' /etc/default/grub
|
|
sed -i '/^#GRUB_TIMEOUT=.*/ s/.*/&\nGRUB_RECORDFAIL_TIMEOUT=5/' /etc/default/grub
|
|
#sed -i "s|^#GRUB_DISABLE_LINUX_UUID=\"\(.*\)\"|GRUB_DISABLE_LINUX_UUID=\"\1 true\"|" /etc/default/grub
|
|
echo "" >> /etc/default/grub
|
|
echo "# Preload modules so that they are not missed." >> /etc/default/grub
|
|
echo "GRUB_PRELOAD_MODULES=part_gpt" >> /etc/default/grub
|
|
|
|
sed -i "s|^\(GRUB_GFXMODE=\).*|\1\"$grub_gfxmode\"|" /etc/default/grub
|
|
sed -i '/^GRUB_GFXMODE=.*/ s/.*/&\nGRUB_GFXPAYLOAD_LINUX=\"keep\"/' /etc/default/grub
|
|
|
|
sed -i "s|^\(GRUB_THEME=\).&|\1\"/boot/grub/grub-themes/${grub_theme}/theme.txt\"|" /etc/default/grub
|
|
|
|
# debug grub
|
|
sed -i "s/quiet//" /etc/default/grub
|
|
#sed -i "s/#GRUB_TERMINAL/GRUB_TERMINAL/" /etc/default/grub
|
|
EOF
|
|
chroot-script -d write-default-grub || { zerr; return 1; }
|
|
|
|
#umount -q ${strapdir}${grub_mount}
|
|
if [[ -v $efi ]]; then
|
|
mkdir -p ${grub_mount}
|
|
act "write grub-efi to available efi partitions."
|
|
for efi_partition in "${efi_partitions[@]}"; do
|
|
notice "writing to efi partitions: ${efi_partitions}"
|
|
act "mount the primary disks efi partition under ${grub_mount}"
|
|
mount ${disk_path}/${disk_name}-part${efi_part_number} ${strapdir}${grub_mount}
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/update-grub_${disk_name} > /dev/null
|
|
#!/bin/sh
|
|
|
|
echo "populate the ${grub_mount} with update-grub."
|
|
grub-mkconfig -o ${grub_mount}/grub.cfg
|
|
|
|
echo "install grub to disk name ${disk_name}, efi partition ${efi_partition}"
|
|
grub-install --target=${grub_efi_target} \
|
|
--no-uefi-secure-boot \
|
|
--efi-directory=${grub_mount} \
|
|
--bootloader-id="Devuan ${release} (RAID disk ${disk_name})"
|
|
--recheck \
|
|
--no-floppy
|
|
EOF
|
|
chroot-script -d update-grub_${disk_name} || { zerr; return 1; }
|
|
umount ${strapdir}${grub_mount}
|
|
done
|
|
else
|
|
mkdir -p ${grub_mount}
|
|
for disk_name in "${available_disks[@]}"; do
|
|
notice "writing grub to available disks:"
|
|
act "mount the primary disks efi partition under ${grub_mount}"
|
|
mount ${disk_path}/${disk_name}-part${efi_part_number} ${strapdir}${grub_mount}
|
|
|
|
cat <<-EOF | sudo tee ${strapdir}/update-grub_${disk_name} > /dev/null
|
|
#!/bin/sh
|
|
|
|
echo "populate the ${grub_mount} with update-grub."
|
|
grub-mkconfig -o ${grub_mount}/grub.cfg
|
|
|
|
echo "install grub-pc to ${disk_name}"
|
|
grub-install --target=i386-pc /dev/disk/by-id/${disk_name}
|
|
EOF
|
|
chroot-script -d update-grub_${disk_name} || { zerr; return 1; }
|
|
umount ${strapdir}${grub_mount}
|
|
done
|
|
|
|
fi
|
|
}
|