-
Notifications
You must be signed in to change notification settings - Fork 115
Expand file tree
/
Copy pathbuild_system.sh
More file actions
executable file
·139 lines (112 loc) · 4.35 KB
/
Copy pathbuild_system.sh
File metadata and controls
executable file
·139 lines (112 loc) · 4.35 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
#!/usr/bin/env bash
set -eo pipefail
UBUNTU_BASE_URL="https://cdimage.ubuntu.com/ubuntu-base/releases/24.04/release/"
UBUNTU_FILE="ubuntu-base-24.04.3-base-arm64.tar.gz"
UBUNTU_FILE_CHECKSUM="7b2dced6dd56ad5e4a813fa25c8de307b655fdabc6ea9213175a92c48dabb048"
# Make sure we're in the correct spot
DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" >/dev/null && pwd)"
cd $DIR
BUILD_DIR="$DIR/build"
OUTPUT_DIR="$DIR/output"
ROOTFS_DIR="$BUILD_DIR/agnos-rootfs"
ROOTFS_IMAGE="$BUILD_DIR/system.img"
OUT_IMAGE="$OUTPUT_DIR/system.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=4500M
# Create temp dir if non-existent
mkdir -p $BUILD_DIR $OUTPUT_DIR
# Download Ubuntu Base if not done already
if [ ! -f $UBUNTU_FILE ]; then
echo -e "Downloading Ubuntu Base: $UBUNTU_FILE"
if ! curl -C - -o $UBUNTU_FILE $UBUNTU_BASE_URL/$UBUNTU_FILE --silent --remote-time --fail; then
echo "Download failed, please check Ubuntu releases: $UBUNTU_BASE_URL"
exit 1
fi
fi
# Check SHA256 sum
if [ "$(shasum -a 256 "$UBUNTU_FILE" | awk '{print $1}')" != "$UBUNTU_FILE_CHECKSUM" ]; then
echo "Checksum mismatch, please check Ubuntu releases: $UBUNTU_BASE_URL"
exit 1
fi
# Setup qemu multiarch
if [ "$(uname -m)" = "x86_64" ]; then
echo "Registering emulator"
docker run --rm --privileged tonistiigi/binfmt --install all
fi
# Check agnos-builder Dockerfile
export DOCKER_BUILDKIT=1
docker buildx build -f Dockerfile.agnos --check $DIR
# Check agnos-meta-builder Dockerfile
docker buildx build --load -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 buildx build --load -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 $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 $MOUNT_CONTAINER_ID" EXIT
echo "Building and extracting agnos-builder docker image"
BUILD="docker buildx build"
if [ ! -z "$NS" ]; then
BUILD="nsc build"
fi
$BUILD -f Dockerfile.agnos \
--output "type=tar,dest=-" \
--provenance=false \
--build-arg UBUNTU_BASE_IMAGE=$UBUNTU_FILE \
--platform=linux/arm64 \
"$DIR" | docker exec -i $MOUNT_CONTAINER_ID tar -xf - -C $ROOTFS_DIR
# 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\n\" > BUILD"
}
GIT_HASH=${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
# Sparsify system image
exec_as_user img2simg $ROOTFS_IMAGE $OUT_IMAGE
echo "Done!"