blob: 899e376c16ace01b8b64ffbc3d00ac45c98f3df8 [file] [log] [blame]
Jiyong Parka128bad2024-09-20 16:53:57 +09001#!/bin/bash
2
3# This is a script to build a Debian image that can run in a VM created via AVF.
4# TODOs:
Jiyong Parka128bad2024-09-20 16:53:57 +09005# - Add Android-specific packages via a new class
6# - Use a stable release from debian-cloud-images
7
8show_help() {
maciek swiech0fdd0512024-10-11 15:12:44 +00009 echo "Usage: sudo $0 [OPTION]... [FILE]"
10 echo "Builds a debian image and save it to FILE. [sudo is required]"
11 echo "Options:"
12 echo "-h Print usage and this help message and exit."
13 echo "-a ARCH Architecture of the image [default is aarch64]"
Jeongik Cha06f4ac52024-11-12 15:56:05 +090014 echo "-r Release mode build"
Jiyong Parka128bad2024-09-20 16:53:57 +090015}
16
17check_sudo() {
18 if [ "$EUID" -ne 0 ]; then
19 echo "Please run as root."
20 exit
21 fi
22}
23
24parse_options() {
Jeongik Cha06f4ac52024-11-12 15:56:05 +090025 while getopts "hra:" option; do
Jiyong Parka128bad2024-09-20 16:53:57 +090026 case ${option} in
27 h)
28 show_help
29 exit;;
maciek swiech0fdd0512024-10-11 15:12:44 +000030 a)
31 if [[ "$OPTARG" != "aarch64" && "$OPTARG" != "x86_64" ]]; then
32 echo "Invalid architecture: $OPTARG"
33 exit
34 fi
35 arch="$OPTARG"
36 if [[ "$arch" == "x86_64" ]]; then
37 debian_arch="amd64"
38 fi
39 ;;
Jeongik Cha06f4ac52024-11-12 15:56:05 +090040 r)
41 mode=release
42 ;;
maciek swiech0fdd0512024-10-11 15:12:44 +000043 *)
44 echo "Invalid option: $OPTARG"
45 exit
46 ;;
Jiyong Parka128bad2024-09-20 16:53:57 +090047 esac
48 done
maciek swiech0fdd0512024-10-11 15:12:44 +000049 if [[ "${*:$OPTIND:1}" ]]; then
50 built_image="${*:$OPTIND:1}"
Jiyong Parka128bad2024-09-20 16:53:57 +090051 fi
52}
53
54install_prerequisites() {
Jiyong Park0e565ed2024-09-24 12:39:53 +090055 apt update
maciek swiech0fdd0512024-10-11 15:12:44 +000056 packages=(
Jeongik Cha7e7f19d2024-10-31 20:50:24 +090057 automake
maciek swiech0fdd0512024-10-11 15:12:44 +000058 binfmt-support
59 build-essential
60 ca-certificates
Jeongik Cha7e7f19d2024-10-31 20:50:24 +090061 cmake
maciek swiech0fdd0512024-10-11 15:12:44 +000062 curl
63 debsums
64 dosfstools
65 fai-server
66 fai-setup-storage
67 fdisk
Jeongik Cha7e7f19d2024-10-31 20:50:24 +090068 git
69 libjson-c-dev
70 libtool
71 libwebsockets-dev
maciek swiech0fdd0512024-10-11 15:12:44 +000072 make
Jeongik Chace3a3962024-10-12 03:47:23 +090073 protobuf-compiler
maciek swiech0fdd0512024-10-11 15:12:44 +000074 python3
75 python3-libcloud
76 python3-marshmallow
77 python3-pytest
78 python3-yaml
79 qemu-user-static
80 qemu-utils
81 sudo
82 udev
83 )
84 if [[ "$arch" == "aarch64" ]]; then
85 packages+=(
86 gcc-aarch64-linux-gnu
87 libc6-dev-arm64-cross
88 qemu-system-arm
89 )
90 else
91 packages+=(
Jeongik Cha904d9622024-10-21 11:16:37 +090092 qemu-system
Jeongik Cha8e711982024-10-20 12:45:35 +090093 )
94 fi
95
96 # TODO(b/365955006): remove these lines when uboot supports x86_64 EFI application
97 if [[ "$arch" == "x86_64" ]]; then
98 packages+=(
99 libguestfs-tools
maciek swiech0fdd0512024-10-11 15:12:44 +0000100 )
101 fi
Jiyong Park44dd28f2024-09-20 18:47:40 +0900102 DEBIAN_FRONTEND=noninteractive \
maciek swiech0fdd0512024-10-11 15:12:44 +0000103 apt install --no-install-recommends --assume-yes "${packages[@]}"
Jeongik Chab137a5f2024-10-02 12:53:05 +0900104
maciek swiech0fdd0512024-10-11 15:12:44 +0000105 if [ ! -f $"HOME"/.cargo/bin/cargo ]; then
Seungjae Yoo198a0fb2024-10-04 16:29:12 +0900106 curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y
107 fi
108
maciek swiech0fdd0512024-10-11 15:12:44 +0000109 source "$HOME"/.cargo/env
110 rustup target add "${arch}"-unknown-linux-gnu
Jeongik Cha139ddfd2024-11-01 23:16:44 +0900111 cargo install cargo-license
Jiyong Parka128bad2024-09-20 16:53:57 +0900112}
113
114download_debian_cloud_image() {
115 local ver=master
116 local prj=debian-cloud-images
maciek swiech0fdd0512024-10-11 15:12:44 +0000117 local url="https://salsa.debian.org/cloud-team/${prj}/-/archive/${ver}/${prj}-${ver}.tar.gz"
118 local outdir="${debian_cloud_image}"
Jiyong Parka128bad2024-09-20 16:53:57 +0900119
maciek swiech0fdd0512024-10-11 15:12:44 +0000120 mkdir -p "${outdir}"
121 wget -O - "${url}" | tar xz -C "${outdir}" --strip-components=1
Jiyong Parka128bad2024-09-20 16:53:57 +0900122}
123
Seungjae Yoo1cfcb582024-10-17 14:06:58 +0900124build_rust_binary_and_copy() {
125 pushd "$(dirname "$0")/../../guest/$1" > /dev/null
Jeongik Cha06f4ac52024-11-12 15:56:05 +0900126 local release_flag=
127 local artifact_mode=debug
128 if [[ "$mode" == "release" ]]; then
129 release_flag="--release"
130 artifact_mode=release
131 fi
Seungjae Yoo1cfcb582024-10-17 14:06:58 +0900132 RUSTFLAGS="-C linker=${arch}-linux-gnu-gcc" cargo build \
133 --target "${arch}-unknown-linux-gnu" \
Jeongik Cha06f4ac52024-11-12 15:56:05 +0900134 --target-dir "${workdir}/$1" ${release_flag}
Seungjae Yoo1cfcb582024-10-17 14:06:58 +0900135 mkdir -p "${dst}/files/usr/local/bin/$1"
Jeongik Cha5d399fb2024-11-12 19:44:33 +0900136 cp "${workdir}/$1/${arch}-unknown-linux-gnu/${artifact_mode}/$1" "${dst}/files/usr/local/bin/$1/AVF"
Seungjae Yoo1cfcb582024-10-17 14:06:58 +0900137 chmod 777 "${dst}/files/usr/local/bin/$1/AVF"
Jeongik Cha139ddfd2024-11-01 23:16:44 +0900138
139 mkdir -p "${dst}/files/usr/share/doc/$1"
140 cargo license > "${dst}/files/usr/share/doc/$1/copyright"
Seungjae Yoo1cfcb582024-10-17 14:06:58 +0900141 popd > /dev/null
142}
143
Jeongik Cha7e7f19d2024-10-31 20:50:24 +0900144build_ttyd() {
145 local ttyd_version=1.7.7
146 local url="https://github.com/tsl0922/ttyd/archive/refs/tags/${ttyd_version}.tar.gz"
147 cp -r $(dirname $0)/ttyd ${workdir}/ttyd
148
149 pushd "${workdir}" > /dev/null
150 wget "${url}" -O - | tar xz
151 cp ttyd/* ttyd-${ttyd_version}/scripts
152 pushd "$workdir/ttyd-${ttyd_version}" > /dev/null
153 bash -c "env BUILD_TARGET=${arch} ./scripts/cross-build.sh"
154 mkdir -p "${dst}/files/usr/local/bin/ttyd"
155 cp /tmp/stage/${arch}-linux-musl/bin/ttyd "${dst}/files/usr/local/bin/ttyd/AVF"
156 chmod 777 "${dst}/files/usr/local/bin/ttyd/AVF"
Jeongik Cha139ddfd2024-11-01 23:16:44 +0900157 mkdir -p "${dst}/files/usr/share/doc/ttyd"
158 cp LICENSE "${dst}/files/usr/share/doc/ttyd/copyright"
Jeongik Cha7e7f19d2024-10-31 20:50:24 +0900159 popd > /dev/null
160 popd > /dev/null
161}
162
Jiyong Park44dd28f2024-09-20 18:47:40 +0900163copy_android_config() {
maciek swiech0fdd0512024-10-11 15:12:44 +0000164 local src="$(dirname "$0")/fai_config"
165 local dst="${config_space}"
Jiyong Park44dd28f2024-09-20 18:47:40 +0900166
maciek swiech0fdd0512024-10-11 15:12:44 +0000167 cp -R "${src}"/* "${dst}"
168 cp "$(dirname "$0")/image.yaml" "${resources_dir}"
Jeongik Cha50952062024-09-23 18:13:38 +0900169
Jeongik Cha7e7f19d2024-10-31 20:50:24 +0900170 build_ttyd
Seungjae Yoo1cfcb582024-10-17 14:06:58 +0900171 build_rust_binary_and_copy forwarder_guest
172 build_rust_binary_and_copy forwarder_guest_launcher
173 build_rust_binary_and_copy ip_addr_reporter
Jiyong Park44dd28f2024-09-20 18:47:40 +0900174}
175
Jiyong Parka128bad2024-09-20 16:53:57 +0900176run_fai() {
maciek swiech0fdd0512024-10-11 15:12:44 +0000177 local out="${built_image}"
178 make -C "${debian_cloud_image}" "image_bookworm_nocloud_${debian_arch}"
179 mv "${debian_cloud_image}/image_bookworm_nocloud_${debian_arch}.raw" "${out}"
Jiyong Parka128bad2024-09-20 16:53:57 +0900180}
181
Mu-Le Lee955b6582024-11-01 15:40:58 +0800182extract_partitions() {
183 root_partition_num=1
184 efi_partition_num=15
185
186 loop=$(losetup -f --show --partscan image.raw)
187 dd if=${loop}p$root_partition_num of=root_part
188 dd if=${loop}p$efi_partition_num of=efi_part
189 losetup -d ${loop}
190
191 sed -i "s/{root_part_guid}/$(sfdisk --part-uuid image.raw $root_partition_num)/g" vm_config.json
192 sed -i "s/{efi_part_guid}/$(sfdisk --part-uuid image.raw $efi_partition_num)/g" vm_config.json
193}
194
Jiyong Parka128bad2024-09-20 16:53:57 +0900195clean_up() {
maciek swiech0fdd0512024-10-11 15:12:44 +0000196 rm -rf "${workdir}"
Jiyong Parka128bad2024-09-20 16:53:57 +0900197}
198
199set -e
200trap clean_up EXIT
201
202built_image=image.raw
203workdir=$(mktemp -d)
204debian_cloud_image=${workdir}/debian_cloud_image
Jiyong Park44dd28f2024-09-20 18:47:40 +0900205debian_version=bookworm
206config_space=${debian_cloud_image}/config_space/${debian_version}
Jeongik Cha37047c32024-09-20 23:09:16 +0900207resources_dir=${debian_cloud_image}/src/debian_cloud_images/resources
maciek swiech0fdd0512024-10-11 15:12:44 +0000208arch=aarch64
209debian_arch=arm64
Jeongik Cha06f4ac52024-11-12 15:56:05 +0900210mode=debug
maciek swiech0fdd0512024-10-11 15:12:44 +0000211parse_options "$@"
Jiyong Parka128bad2024-09-20 16:53:57 +0900212check_sudo
Jiyong Parka128bad2024-09-20 16:53:57 +0900213install_prerequisites
214download_debian_cloud_image
Jiyong Park44dd28f2024-09-20 18:47:40 +0900215copy_android_config
Jiyong Park0e565ed2024-09-24 12:39:53 +0900216run_fai
Jiyong Park856e3be2024-09-24 21:59:45 +0900217fdisk -l image.raw
Mu-Le Lee955b6582024-11-01 15:40:58 +0800218images=()
219
220cp $(dirname $0)/vm_config.json.${arch} vm_config.json
221
222if [[ "$arch" == "aarch64" ]]; then
223 extract_partitions
224 images+=(
225 root_part
226 efi_part
227 )
228fi
229
Jeongik Cha8e711982024-10-20 12:45:35 +0900230# TODO(b/365955006): remove these lines when uboot supports x86_64 EFI application
231if [[ "$arch" == "x86_64" ]]; then
232 virt-get-kernel -a image.raw
233 mv vmlinuz* vmlinuz
234 mv initrd.img* initrd.img
235 images+=(
Mu-Le Lee955b6582024-11-01 15:40:58 +0800236 image.raw
Jeongik Cha8e711982024-10-20 12:45:35 +0900237 vmlinuz
238 initrd.img
239 )
240fi
Jeongik Cha904d9622024-10-21 11:16:37 +0900241
Jeongik Cha8e711982024-10-20 12:45:35 +0900242# --sparse option isn't supported in apache-commons-compress
Mu-Le Lee955b6582024-11-01 15:40:58 +0800243tar czv -f images.tar.gz ${images[@]} vm_config.json