bootstrap (7442B)
1 #!/usr/bin/env zsh 2 # shellcheck shell=bash 3 # Copyright (c) 2016-2021 Ivan J. <parazyd@dyne.org> 4 # This file is part of libdevuansdk 5 # 6 # This source code is free software: you can redistribute it and/or modify 7 # it under the terms of the GNU General Public License as published by 8 # the Free Software Foundation, either version 3 of the License, or 9 # (at your option) any later version. 10 # 11 # This software is distributed in the hope that it will be useful, 12 # but WITHOUT ANY WARRANTY; without even the implied warranty of 13 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 # GNU General Public License for more details. 15 # 16 # You should have received a copy of the GNU General Public License 17 # along with this source code. If not, see <http://www.gnu.org/licenses/>. 18 19 vars+=(bootstrap_cpio_stage3 bootstrap_cpio_stage4 CPIO_STAGE4) 20 21 bootstrap_complete_base() 22 { 23 fn bootstrap_complete_base "$*" 24 req=(R os arch strapdir LIBPATH release mirror) 25 ckreq || return 1 26 27 notice "Bootstrapping: ${os}:${arch} base" 28 29 export LANG=C 30 export LC_ALL=C 31 export DEBIAN_FRONTEND=noninteractive 32 export SOURCE_DATE_EPOCH=1610550434 33 34 bootstrap_cpio_stage3="$R/tmp/bootstrap-${os}-${arch}-stage3.cpio.gz" 35 bootstrap_cpio_stage4="$R/tmp/bootstrap-${os}-${arch}-stage4.cpio.gz" 36 37 if [[ -n "$CPIO_STAGE4" && -f "$bootstrap_cpio_stage4" ]]; then 38 act "Using the existing stage4 bootstrap cpio archive..." 39 bootstrap_cpio_unpack "$bootstrap_cpio_stage4" "$strapdir" || { 40 die "Failed to extract cpio archive" 41 return 1 42 } 43 bootstrap_stage4 44 return 45 elif [[ -f "$bootstrap_cpio_stage3" ]]; then 46 act "Using the existing stage3 bootstrap cpio archive..." 47 bootstrap_cpio_unpack "$bootstrap_cpio_stage3" "$strapdir" || { 48 die "Failed to extract cpio archive" 49 return 1 50 } 51 bootstrap_stage4 || { zerr; return 1; } 52 if [[ -n "$CPIO_STAGE4" ]]; then 53 bootstrap_cpio_pack "$bootstrap_cpio_stage4" || { zerr; return 1; } 54 fi 55 return 56 fi 57 58 notice "Running stage1 debootstrap" 59 60 sudo debootstrap \ 61 --keyring="$LIBPATH/extra/devuan-keyring/keyrings/devuan-archive-keyring.gpg" \ 62 --include=devuan-keyring,wget,ca-certificates \ 63 --foreign \ 64 --arch "$arch" "$release" "$strapdir" "$mirror" || { zerr; return 1; } 65 66 if [[ "$arch" =~ "^arm.." ]]; then 67 qemu_install_user "$strapdir" || { zerr; return 1; } 68 fi 69 70 notice "Running stage2 debootstrap" 71 72 sudo chroot "$strapdir" /debootstrap/debootstrap --second-stage || { zerr; return 1; } 73 74 # TODO: sys config as function 75 conf_print_fstab | sudo tee "$strapdir/etc/fstab" >/dev/null 76 conf_print_hostname | sudo tee "$strapdir/etc/hostname" >/dev/null 77 conf_print_hosts | sudo tee "$strapdir/etc/hosts" >/dev/null 78 conf_print_netifaces | sudo tee "$strapdir/etc/network/interfaces" >/dev/null 79 conf_print_resolvconf | sudo tee "$strapdir/etc/resolv.conf" >/dev/null 80 conf_print_sourceslist | sudo tee "$strapdir/etc/apt/sources.list" >/dev/null 81 82 blend_bootstrap_setup || { zerr; return 1; } 83 84 bootstrap_stage3 || { zerr; return 1; } 85 bootstrap_cpio_pack "$bootstrap_cpio_stage3" || { zerr; return 1; } 86 87 bootstrap_stage4 || { zerr; return 1; } 88 if [[ -n "$CPIO_STAGE4" ]]; then 89 bootstrap_cpio_pack "$bootstrap_cpio_stage4" || { zerr; return 1; } 90 fi 91 92 return 93 } 94 95 bootstrap_stage3() 96 { 97 fn bootstrap_stage3 98 req=(core_packages base_packages rootcredentials) 99 ckreq || return 1 100 101 cat <<EOF | sudo tee "$strapdir/thirdstage" >/dev/null 102 #!/bin/sh 103 apt-get update 104 apt-get --yes --force-yes install ${core_packages_option} ${core_packages} || exit 1 105 apt-get --yes --force-yes install ${base_packages_option} ${base_packages} || exit 1 106 apt-get --yes --force-yes purge ${purge_packages_option} ${purge_packages} || exit 1 107 apt-get --yes --force-yes --purge autoremove || exit 1 108 apt-get clean 109 110 echo "${rootcredentials}" | chpasswd 111 112 rm -f /etc/ssh/ssh_host_* 113 rm -f /root/.bash_history 114 EOF 115 116 chroot-script -d thirdstage || { zerr; return 1; } 117 } 118 119 bootstrap_stage4() 120 { 121 fn bootstrap_stage4 122 req=(strapdir extra_packages) 123 ckreq || return 1 124 125 sudo mkdir -p "$strapdir"/{boot,dev,proc,sys} 126 127 cat <<EOF | sudo tee "$strapdir/fourthstage" >/dev/null 128 #!/bin/sh 129 apt-get update 130 131 # check if all our extra_packages exist 132 allpkgs="\$(apt-cache search '.' | cut -d' ' -f1)" 133 for i in ${extra_packages}; do 134 printf "%s" "\$allpkgs" | grep -q "^\$i$" || { 135 case "\$i" in 136 --*) continue;; 137 *) missing="\$missing \$i" ;; 138 esac 139 } 140 done 141 142 if [ -n "\$missing" ]; then 143 printf "\033[1;31m[!!] Some extra packages don't exist:\033[0m\n" 144 printf "%s\n" "\$missing" 145 exit 1 146 fi 147 148 apt-get --yes --force-yes upgrade || exit 1 149 apt-get --yes --force-yes install ${extra_packages_option} ${extra_packages} || exit 1 150 apt-get --yes --force-yes --purge autoremove || exit 1 151 apt-get clean 152 EOF 153 154 chroot-script -d fourthstage || { zerr; return 1; } 155 156 for i in $inittab; do 157 grep -q "$^i" "$strapdir/etc/inittab" && continue 158 echo "$i" | sudo tee -a "$strapdir/etc/inittab" >/dev/null 159 done || true 160 161 for i in $custmodules; do 162 grep -q "^$i" "$strapdir/etc/modules" && continue 163 echo "$i" | sudo tee -a "$strapdir/etc/modules" >/dev/null 164 done || true 165 } 166 167 qemu_install_user() 168 { 169 fn qemu_install_user "$*" 170 req=(arch _target) 171 local _target="$1" 172 ckreq || return 1 173 174 case "$(uname -m)" in 175 arm*|aarch*) 176 return 177 ;; 178 esac 179 180 notice "Installing qemu-user-static" 181 182 if [[ -f "/etc/gentoo-release" ]] && [[ "$arch" = armhf ]]; then 183 cat <<EOF | gcc -O3 -static -o /tmp/qemu-wrapper -x c - 184 #include <string.h> 185 #include <unistd.h> 186 int main(int argc, char **argv, char **envp) { 187 char *newargv[argc+3]; 188 newargv[0] = argv[0]; 189 newargv[1] = "-cpu"; 190 newargv[2] = "cortex-a8"; 191 memcpy(&newargv[3], &argv[1], sizeof(*argv) * (argc-1)); 192 newargv[argc+2] = NULL; 193 return execve("${armhf_qemu_bin}", newargv, envp); 194 } 195 EOF 196 sudo mv /tmp/qemu-wrapper "$_target" || { zerr; return 1 ; } 197 fi 198 199 case "$arch" in 200 armel) 201 sudo cp -a "$armel_qemu_bin" "$_target/usr/bin/" || { zerr; return 1; } 202 ;; 203 armhf) 204 sudo cp -a "$armhf_qemu_bin" "$_target/usr/bin/" || { zerr; return 1; } 205 ;; 206 arm64) 207 sudo cp -a "$arm64_qemu_bin" "$_target/usr/bin/" || { zerr; return 1; } 208 ;; 209 esac 210 } 211 212 bootstrap_cpio_pack() 213 { 214 fn bootstrap_cpio_pack "$*" 215 req=(_bootstrap_cpio strapdir) 216 local _bootstrap_cpio="$1" 217 ckreq || return 1 218 219 local _dest="$(dirname "$_bootstrap_cpio")" 220 if [[ -f "$_bootstrap_cpio" ]]; then 221 notice "cpio archive already found in $_dest" 222 return 223 fi 224 225 notice "Creating bootstrap cpio archive: $_bootstrap_cpio" 226 silly 227 228 pushd "$strapdir" 229 mkdir -p "$_dest" 230 sudo find . \ 231 -not -path "./dev/*" \ 232 -a -not -path "./proc/*" \ 233 -a -not -path "./sys/*" \ 234 | sudo cpio -oa --reproducible --format=newc \ 235 | gzip - > "$_bootstrap_cpio" || { zerr; return 1; } 236 popd 237 } 238 239 bootstrap_cpio_unpack() 240 { 241 fn bootstrap_cpio_unpack "$*" 242 req=(_bootstrap_cpio strapdir) 243 local _bootstrap_cpio="$1" 244 ckreq || return 1 245 246 notice "Unpacking bootstrap cpio archive: $_bootstrap_cpio" 247 silly 248 249 # Danger Will Robinson 250 # Check for (bind) mounts as sudo rm -rf will trash the host 251 for m in sys proc dev; do 252 if [[ $(mountpoint -q "${strapdir}/$m") ]]; then 253 zerr 254 return 1 255 fi 256 done 257 # remove everything, including .dotdirfiles 258 sudo rm -rf "$strapdir" 259 mkdir -p "$strapdir" 260 261 pushd "$strapdir" || { zerr; return 1; } 262 zcat "$_bootstrap_cpio" | sudo cpio -idmn --format=newc 2>>/dev/null || { zerr; return 1; } 263 popd 264 265 sudo mkdir -p "$strapdir"/{boot,dev,proc,sys} 266 } 267 268 blend_bootstrap_setup() 269 { 270 fn blend_bootstrap_setup "(noop)" 271 return 272 }