-
Notifications
You must be signed in to change notification settings - Fork 98
Expand file tree
/
Copy pathbuild_system.sh
More file actions
executable file
·157 lines (126 loc) · 5.17 KB
/
build_system.sh
File metadata and controls
executable file
·157 lines (126 loc) · 5.17 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/bin/bash
set -e
UBUNTU_BASE_URL="http://cdimage.ubuntu.com/ubuntu-base/releases/24.04/release"
UBUNTU_FILE="ubuntu-base-24.04-base-arm64.tar.gz"
# Make sure we're in the correct spot
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd $DIR
ARCH=$(uname -m)
BUILD_DIR="$DIR/build"
OUTPUT_DIR="$DIR/output"
CACHE_DIR="$DIR/cache"
ROOTFS_DIR="$BUILD_DIR/agnos-rootfs"
ROOTFS_IMAGE="$BUILD_DIR/system.img"
OUT_IMAGE="$OUTPUT_DIR/system.img"
OUT_SKIP_CHUNKS_IMAGE="$OUTPUT_DIR/system-skip-chunks.img"
# the partition is 10G, but openpilot's updater didn't always handle the full size
# openpilot fix, shipped in 0.9.8 (8/18/24): https://github.com/commaai/openpilot/pull/33320
ROOTFS_IMAGE_SIZE=5G
# Create temp dir if non-existent
mkdir -p $BUILD_DIR $OUTPUT_DIR $CACHE_DIR/var_lib_apt/lists $CACHE_DIR/var_cache_apt/archives
# Copy kernel modules
if ! ls $OUTPUT_DIR/*.ko >/dev/null 2>&1; then
echo "Kernel modules missing. Run ./build_kernel.sh first"
exit 1
fi
cp $OUTPUT_DIR/wlan.ko $DIR/userspace/usr/comma
cp $OUTPUT_DIR/snd*.ko $DIR/userspace/usr/comma/sound/
# Download Ubuntu Base if not done already
if [ ! -f $UBUNTU_FILE ]; then
echo -e "${GREEN}Downloading Ubuntu: $UBUNTU_FILE ${NO_COLOR}"
curl -C - -o $UBUNTU_FILE $UBUNTU_BASE_URL/$UBUNTU_FILE --silent --remote-time
fi
# Setup qemu multiarch
if [ "$ARCH" = "x86_64" ]; then
echo "Registering qemu-user-static"
docker run --rm --privileged multiarch/qemu-user-static --reset -p yes > /dev/null
fi
# Check agnos-builder Dockerfile
docker build -f Dockerfile.agnos --check $DIR
# Start agnos-builder docker build and create container
echo "Building agnos-builder docker image"
# Docker image for agnos
docker build -f Dockerfile.agnos -t agnos-builder $DIR
# Cache image that skips the last cache deletion step
docker build -f Dockerfile.agnos --target agnos -t agnos-builder-cache $DIR
echo "Creating agnos-builder container"
CONTAINER_ID=$(docker container create --entrypoint /bin/bash agnos-builder:latest)
CACHE_CONTAINER_ID=$(docker container create --entrypoint /bin/bash agnos-builder-cache:latest)
# Check agnos-meta-builder Dockerfile
docker build -f Dockerfile.builder --check $DIR \
--build-arg UNAME=$(id -nu) \
--build-arg UID=$(id -u) \
--build-arg GID=$(id -g)
# Setup mount container for macOS and CI support (namespace.so)
echo "Building agnos-meta-builder docker image"
docker build -f Dockerfile.builder -t agnos-meta-builder $DIR \
--build-arg UNAME=$(id -nu) \
--build-arg UID=$(id -u) \
--build-arg GID=$(id -g)
echo "Starting agnos-meta-builder container"
MOUNT_CONTAINER_ID=$(docker run -d --privileged -v $DIR:$DIR agnos-meta-builder)
# Cleanup containers on possible exit
trap "echo \"Cleaning up containers:\"; \
docker container rm -f $CONTAINER_ID $MOUNT_CONTAINER_ID" EXIT
# Define functions for docker execution
exec_as_user() {
docker exec -u $(id -nu) $MOUNT_CONTAINER_ID "$@"
}
exec_as_root() {
docker exec $MOUNT_CONTAINER_ID "$@"
}
# Create filesystem ext4 image
echo "Creating empty filesystem"
exec_as_user fallocate -l $ROOTFS_IMAGE_SIZE $ROOTFS_IMAGE
exec_as_user mkfs.ext4 $ROOTFS_IMAGE &> /dev/null
# Mount filesystem
echo "Mounting empty filesystem"
exec_as_root mkdir -p $ROOTFS_DIR
exec_as_root mount $ROOTFS_IMAGE $ROOTFS_DIR
# Also unmount filesystem (overwrite previous trap)
trap "exec_as_root umount -l $ROOTFS_DIR &> /dev/null || true; \
echo \"Cleaning up containers:\"; \
docker container rm -f $CONTAINER_ID $MOUNT_CONTAINER_ID $CACHE_CONTAINER_ID" EXIT
# Extract image
echo "Extracting docker image"
docker container export -o $BUILD_DIR/filesystem.tar $CONTAINER_ID
exec_as_root tar -xf $BUILD_DIR/filesystem.tar -C $ROOTFS_DIR > /dev/null
# Extract cache
echo "Extracting cache"
docker cp $CACHE_CONTAINER_ID:/var/cache/apt/archives $CACHE_DIR/var_cache_apt/
docker cp $CACHE_CONTAINER_ID:/var/lib/apt/lists/ $CACHE_DIR/var_lib_apt/
# Avoid detecting as container
echo "Removing .dockerenv file"
exec_as_root rm -f $ROOTFS_DIR/.dockerenv
echo "Setting network stuff"
set_network_stuff() {
cd $ROOTFS_DIR
# Add hostname and hosts. This cannot be done in the docker container...
HOST=comma
bash -c "ln -sf /proc/sys/kernel/hostname etc/hostname"
bash -c "echo \"127.0.0.1 localhost.localdomain localhost\" > etc/hosts"
bash -c "echo \"127.0.0.1 $HOST\" >> etc/hosts"
# Fix resolv config
bash -c "ln -sf /run/systemd/resolve/stub-resolv.conf etc/resolv.conf"
# Set capability for ping
bash -c "setcap cap_net_raw+ep bin/ping"
# Write build info
DATETIME=$(date '+%Y-%m-%dT%H:%M:%S')
bash -c "printf \"$GIT_HASH\n$DATETIME\" > BUILD"
}
GIT_HASH=$(git --git-dir=$DIR/.git rev-parse HEAD)
exec_as_root bash -c "set -e; export ROOTFS_DIR=$ROOTFS_DIR GIT_HASH=$GIT_HASH; $(declare -f set_network_stuff); set_network_stuff"
# Unmount image
echo "Unmount filesystem"
exec_as_root umount -l $ROOTFS_DIR
# Make system image with skipped chunks
echo "Sparsifying image $(basename $OUT_SKIP_CHUNKS_IMAGE)"
exec_as_user bash -c "\
TMP_SPARSE=\$(mktemp); \
img2simg $ROOTFS_IMAGE \$TMP_SPARSE; \
TMP_SKIP=\$(mktemp); \
$DIR/tools/simg2dontcare.py \$TMP_SPARSE \$TMP_SKIP; \
mv \$TMP_SKIP $OUT_SKIP_CHUNKS_IMAGE"
# Copy system image to output
cp $ROOTFS_IMAGE $OUT_IMAGE
echo "Done!"