#!/usr/bin/env zsh # shellcheck shell=bash # Copyright (c) 2016-2021 Ivan J. # 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 . 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 </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 </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 < #include 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 }