libdevuansdk/zlibs/bootstrap

274 lines
7.3 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/>.
vars+=(bootstrap_cpio_stage3 bootstrap_cpio_stage4 CPIO_STAGE4)
bootstrap_complete_base()
{
fn bootstrap_complete_base "$*"
req=(R os arch strapdir LIBPATH release mirror)
ckreq || return 1
notice "Bootstrapping: ${os}:${arch} base"
export LANG=C
export LC_ALL=C
export DEBIAN_FRONTEND=noninteractive
export SOURCE_DATE_EPOCH=1610550434
bootstrap_cpio_stage3="$R/tmp/bootstrap-${os}-${arch}-stage3.cpio.gz"
bootstrap_cpio_stage4="$R/tmp/bootstrap-${os}-${arch}-stage4.cpio.gz"
if [[ -n "$CPIO_STAGE4" && -f "$bootstrap_cpio_stage4" ]]; then
act "Using the existing stage4 bootstrap cpio archive..."
bootstrap_cpio_unpack "$bootstrap_cpio_stage4" "$strapdir" || {
die "Failed to extract cpio archive"
return 1
}
bootstrap_stage4
return
elif [[ -f "$bootstrap_cpio_stage3" ]]; then
act "Using the existing stage3 bootstrap cpio archive..."
bootstrap_cpio_unpack "$bootstrap_cpio_stage3" "$strapdir" || {
die "Failed to extract cpio archive"
return 1
}
bootstrap_stage4 || { zerr; return 1; }
if [[ -n "$CPIO_STAGE4" ]]; then
bootstrap_cpio_pack "$bootstrap_cpio_stage4" || { zerr; return 1; }
fi
return
fi
notice "Running stage1 debootstrap"
sudo debootstrap \
--keyring="$LIBPATH/extra/devuan-keyring/keyrings/devuan-archive-keyring.gpg" \
--include=devuan-keyring,wget,ca-certificates \
--foreign \
--arch "$arch" "$release" "$strapdir" "$mirror" || { zerr; return 1; }
if [[ "$arch" =~ "^arm.." ]]; then
qemu_install_user "$strapdir" || { zerr; return 1; }
fi
notice "Running stage2 debootstrap"
sudo chroot "$strapdir" /debootstrap/debootstrap --second-stage || { zerr; return 1; }
# TODO: sys config as function
conf_print_fstab | sudo tee "$strapdir/etc/fstab" >/dev/null
conf_print_hostname | sudo tee "$strapdir/etc/hostname" >/dev/null
conf_print_hosts | sudo tee "$strapdir/etc/hosts" >/dev/null
conf_print_netifaces | sudo tee "$strapdir/etc/network/interfaces" >/dev/null
conf_print_resolvconf | sudo tee "$strapdir/etc/resolv.conf" >/dev/null
conf_print_sourceslist | sudo tee "$strapdir/etc/apt/sources.list" >/dev/null
blend_bootstrap_setup || { zerr; return 1; }
bootstrap_stage3 || { zerr; return 1; }
bootstrap_cpio_pack "$bootstrap_cpio_stage3" || { zerr; return 1; }
bootstrap_stage4 || { zerr; return 1; }
if [[ -n "$CPIO_STAGE4" ]]; then
bootstrap_cpio_pack "$bootstrap_cpio_stage4" || { zerr; return 1; }
fi
return
}
bootstrap_stage3()
{
fn bootstrap_stage3
req=(core_packages base_packages rootcredentials)
ckreq || return 1
cat <<EOF | sudo tee "$strapdir/thirdstage" >/dev/null
#!/bin/sh
apt-get update
apt-get --yes --force-yes install ${core_packages_option} ${core_packages} || exit 1
apt-get --yes --force-yes install ${base_packages_option} ${base_packages} || exit 1
apt-get --yes --force-yes purge ${purge_packages_option} ${purge_packages} || exit 1
apt-get --yes --force-yes --purge autoremove || exit 1
apt-get clean
echo "${rootcredentials}" | chpasswd
rm -f /etc/ssh/ssh_host_*
rm -f /root/.bash_history
EOF
chroot-script -d thirdstage || { zerr; return 1; }
}
bootstrap_stage4()
{
fn bootstrap_stage4
req=(strapdir extra_packages)
ckreq || return 1
sudo mkdir -p "$strapdir"/{boot,dev,proc,sys}
cat <<EOF | sudo tee "$strapdir/fourthstage" >/dev/null
#!/bin/sh
apt-get update
# check if all our extra_packages exist
allpkgs="\$(apt-cache search '.' | cut -d' ' -f1)"
for i in ${extra_packages}; do
printf "%s" "\$allpkgs" | grep -q "^\$i$" || {
case "\$i" in
--*) continue;;
*) missing="\$missing \$i" ;;
esac
}
done
if [ -n "\$missing" ]; then
printf "\033[1;31m[!!] Some extra packages don't exist:\033[0m\n"
printf "%s\n" "\$missing"
exit 1
fi
apt-get --yes --force-yes upgrade || exit 1
apt-get --yes --force-yes install ${extra_packages_option} ${extra_packages} || exit 1
apt-get --yes --force-yes purge ${purge_extra_packages} || exit 1
apt-get --yes --force-yes --purge autoremove || exit 1
apt-get clean
EOF
chroot-script -d fourthstage || { zerr; return 1; }
for i in $inittab; do
grep -q "$^i" "$strapdir/etc/inittab" && continue
echo "$i" | sudo tee -a "$strapdir/etc/inittab" >/dev/null
done || true
for i in $custmodules; do
grep -q "^$i" "$strapdir/etc/modules" && continue
echo "$i" | sudo tee -a "$strapdir/etc/modules" >/dev/null
done || true
}
qemu_install_user()
{
fn qemu_install_user "$*"
req=(arch _target)
local _target="$1"
ckreq || return 1
case "$(uname -m)" in
arm*|aarch*)
return
;;
esac
notice "Installing qemu-user-static"
if [[ -f "/etc/gentoo-release" ]] && [[ "$arch" = armhf ]]; then
cat <<EOF | gcc -O3 -static -o /tmp/qemu-wrapper -x c -
#include <string.h>
#include <unistd.h>
int main(int argc, char **argv, char **envp) {
char *newargv[argc+3];
newargv[0] = argv[0];
newargv[1] = "-cpu";
newargv[2] = "cortex-a8";
memcpy(&newargv[3], &argv[1], sizeof(*argv) * (argc-1));
newargv[argc+2] = NULL;
return execve("${armhf_qemu_bin}", newargv, envp);
}
EOF
sudo mv /tmp/qemu-wrapper "$_target" || { zerr; return 1 ; }
fi
case "$arch" in
armel)
sudo cp -a "$armel_qemu_bin" "$_target/usr/bin/" || { zerr; return 1; }
;;
armhf)
sudo cp -a "$armhf_qemu_bin" "$_target/usr/bin/" || { zerr; return 1; }
;;
arm64)
sudo cp -a "$arm64_qemu_bin" "$_target/usr/bin/" || { zerr; return 1; }
;;
esac
}
bootstrap_cpio_pack()
{
fn bootstrap_cpio_pack "$*"
req=(_bootstrap_cpio strapdir)
local _bootstrap_cpio="$1"
ckreq || return 1
local _dest="$(dirname "$_bootstrap_cpio")"
if [[ -f "$_bootstrap_cpio" ]]; then
notice "cpio archive already found in $_dest"
return
fi
notice "Creating bootstrap cpio archive: $_bootstrap_cpio"
silly
pushd "$strapdir"
mkdir -p "$_dest"
sudo find . \
-not -path "./dev/*" \
-a -not -path "./proc/*" \
-a -not -path "./sys/*" \
| sudo cpio -oa --reproducible --format=newc \
| gzip - > "$_bootstrap_cpio" || { zerr; return 1; }
popd
}
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"
silly
# Danger Will Robinson
# Check for (bind) mounts as sudo rm -rf will trash the host
for m in sys proc dev; do
if [[ $(mountpoint -q "${strapdir}/$m") ]]; then
zerr
return 1
fi
done
# remove everything, including .dotdirfiles
sudo rm -rf "$strapdir"
mkdir -p "$strapdir"
pushd "$strapdir" || { zerr; return 1; }
zcat "$_bootstrap_cpio" | sudo cpio -idmn --format=newc 2>>/dev/null || { zerr; return 1; }
popd
sudo mkdir -p "$strapdir"/{boot,dev,proc,sys}
}
blend_bootstrap_setup()
{
fn blend_bootstrap_setup "(noop)"
return
}