1#!/bin/bash 2# 3# Copyright (C) 2018 The Android Open Source Project 4# 5# Licensed under the Apache License, Version 2.0 (the "License"); 6# you may not use this file except in compliance with the License. 7# You may obtain a copy of the License at 8# 9# http://www.apache.org/licenses/LICENSE-2.0 10# 11# Unless required by applicable law or agreed to in writing, software 12# distributed under the License is distributed on an "AS IS" BASIS, 13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14# See the License for the specific language governing permissions and 15# limitations under the License. 16# 17 18set -e 19 20SCRIPT_DIR=$(CDPATH= cd -- "$(dirname -- "$0")" && pwd -P) 21 22# Make sure we're in C locale so build inside chroot does not complain 23# about missing files 24unset LANG LANGUAGE \ 25 LC_ADDRESS LC_ALL LC_COLLATE LC_CTYPE LC_IDENTIFICATION LC_MEASUREMENT \ 26 LC_MESSAGES LC_MONETARY LC_NAME LC_NUMERIC LC_PAPER LC_TELEPHONE LC_TIME 27export LC_ALL=C 28 29usage() { 30 echo -n "usage: $0 [-h] [-s bullseye] [-a i386|amd64|armhf|arm64] " 31 echo "[-m http://mirror/debian] [-n net_test.rootfs.`date +%Y%m%d`]" 32 exit 1 33} 34 35mirror=http://ftp.debian.org/debian 36debootstrap=debootstrap 37suite=bullseye 38arch=amd64 39 40while getopts ":hs:a:m:n:" opt; do 41 case $opt in 42 h) 43 usage 44 ;; 45 s) 46 if [[ "$OPTARG" != "bullseye" ]]; then 47 echo "Invalid suite: $OPTARG" >&2 48 usage 49 fi 50 suite="${OPTARG}" 51 ;; 52 a) 53 case "${OPTARG}" in 54 i386|amd64|armhf|arm64) 55 arch="${OPTARG}" 56 ;; 57 *) 58 echo "Invalid arch: ${OPTARG}" >&2 59 usage 60 ;; 61 esac 62 ;; 63 m) 64 mirror=$OPTARG 65 ;; 66 n) 67 name=$OPTARG 68 ;; 69 \?) 70 echo "Invalid option: $OPTARG" >&2 71 usage 72 ;; 73 :) 74 echo "Invalid option: $OPTARG requires an argument" >&2 75 usage 76 ;; 77 esac 78done 79 80if [[ -z "${name}" ]]; then 81 name=net_test.rootfs.${arch}.${suite}.`date +%Y%m%d` 82fi 83 84# Switch to qemu-debootstrap for incompatible architectures 85if [ "$arch" = "arm64" ]; then 86 debootstrap=qemu-debootstrap 87fi 88 89# Sometimes it isn't obvious when the script fails 90failure() { 91 echo "Filesystem generation process failed." >&2 92} 93trap failure ERR 94 95# Import the package list for this release 96packages=`cat $SCRIPT_DIR/rootfs/$suite.list | xargs | tr -s ' ' ','` 97 98# For the debootstrap intermediates 99tmpdir=`mktemp -d` 100tmpdir_remove() { 101 echo "Removing temporary files.." >&2 102 sudo rm -rf "${tmpdir}" 103} 104trap tmpdir_remove EXIT 105 106workdir="${tmpdir}/_" 107 108mkdir "${workdir}" 109chmod 0755 "${workdir}" 110sudo chown root:root "${workdir}" 111 112# Run the debootstrap first 113cd $workdir 114sudo $debootstrap --arch=$arch --variant=minbase --include=$packages \ 115 $suite . $mirror 116# Workarounds for bugs in the debootstrap suite scripts 117for mount in `cat /proc/mounts | cut -d' ' -f2 | grep -e ^$workdir`; do 118 echo "Unmounting mountpoint $mount.." >&2 119 sudo umount $mount 120done 121# Copy the chroot preparation scripts, and enter the chroot 122for file in $suite.sh common.sh net_test.sh; do 123 sudo cp -a $SCRIPT_DIR/rootfs/$file root/$file 124 sudo chown root:root root/$file 125done 126sudo chroot . /root/$suite.sh 127 128# Leave the workdir, to build the filesystem 129cd - 130 131# For the final image mount 132mount=`mktemp -d` 133mount_remove() { 134 rmdir $mount 135 tmpdir_remove 136} 137trap mount_remove EXIT 138 139# Create a 1G empty ext3 filesystem 140truncate -s 1G $name 141mke2fs -F -t ext3 -L ROOT $name 142 143# Mount the new filesystem locally 144sudo mount -o loop -t ext3 $name $mount 145image_unmount() { 146 sudo umount $mount 147 mount_remove 148} 149trap image_unmount EXIT 150 151# Copy the patched debootstrap results into the new filesystem 152sudo cp -a $workdir/* $mount 153 154# Fill the rest of the space with zeroes, to optimize compression 155sudo dd if=/dev/zero of=$mount/sparse bs=1M 2>/dev/null || true 156sudo rm -f $mount/sparse 157 158echo "Debian $suite for $arch filesystem generated at '$name'." 159