Repository navigation
193 lines (167 loc) · 7.37 KB
/
Copy pathfc-test.yml
File metadata and controls
193 lines (167 loc) · 7.37 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
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
name: Firecracker VM CI
on: workflow_call
jobs:
firecracker:
runs-on: ubuntu-24.04
steps:
- name: Checkout Code
uses: actions/checkout@v5
- name: Install Dependencies
run: |
sudo apt-get update
sudo apt-get install -y build-essential libseccomp-dev libcap-dev qemu-kvm
- name: Download Firecracker
run: |
FIRECRACKER_VERSION=1.10.1
curl -LO https://github.com/firecracker-microvm/firecracker/releases/download/v${FIRECRACKER_VERSION}/firecracker-v${FIRECRACKER_VERSION}-x86_64.tgz
tar -xvf firecracker-v${FIRECRACKER_VERSION}-x86_64.tgz
cp release-v${FIRECRACKER_VERSION}-x86_64/firecracker-v${FIRECRACKER_VERSION}-x86_64 firecracker
chmod +x firecracker
- name: Huge Pages
run: |
# We are not enabling Transparent Huge Pages for now, as they are not swappable and may result in slowdowns + we are not using swap right now.
# The THP are by default set to madvise
# We are allocating the hugepages at the start when the memory is not fragmented yet
echo "[Setting up huge pages]"
sudo mkdir -p /mnt/hugepages
sudo mount -t hugetlbfs none /mnt/hugepages
# Increase proactive compaction to reduce memory fragmentation for using overcomitted huge pages
available_ram=$(grep MemTotal /proc/meminfo | awk '{print $2}') # in KiB
available_ram=$(($available_ram / 1024)) # in MiB
echo "- Total memory: $available_ram MiB"
min_normal_ram=$((4 * 1024)) # 4 GiB
min_normal_percentage_ram=$(($available_ram * 16 / 100)) # 16% of the total memory
max_normal_ram=$((42 * 1024)) # 42 GiB
max() {
if (($1 > $2)); then
echo "$1"
else
echo "$2"
fi
}
min() {
if (($1 < $2)); then
echo "$1"
else
echo "$2"
fi
}
ensure_even() {
if (($1 % 2 == 0)); then
echo "$1"
else
echo $(($1 - 1))
fi
}
remove_decimal() {
echo "$(echo $1 | sed 's/\..*//')"
}
reserved_normal_ram=$(max $min_normal_ram $min_normal_percentage_ram)
reserved_normal_ram=$(min $reserved_normal_ram $max_normal_ram)
echo "- Reserved RAM: $reserved_normal_ram MiB"
# The huge pages RAM should still be usable for normal pages in most cases.
hugepages_ram=$(($available_ram - $reserved_normal_ram))
hugepages_ram=$(remove_decimal $hugepages_ram)
hugepages_ram=$(ensure_even $hugepages_ram)
echo "- RAM for hugepages: $hugepages_ram MiB"
hugepage_size_in_mib=2
echo "- Huge page size: $hugepage_size_in_mib MiB"
hugepages=$(($hugepages_ram / $hugepage_size_in_mib))
# This percentage will be permanently allocated for huge pages and in monitoring it will be shown as used.
base_hugepages_percentage=20
base_hugepages=$(($hugepages * $base_hugepages_percentage / 100))
base_hugepages=$(remove_decimal $base_hugepages)
echo "- Allocating $base_hugepages huge pages ($base_hugepages_percentage%) for base usage"
sudo bash -c "echo $base_hugepages > /proc/sys/vm/nr_hugepages"
overcommitment_hugepages_percentage=$((100 - $base_hugepages_percentage))
overcommitment_hugepages=$(($hugepages * $overcommitment_hugepages_percentage / 100))
overcommitment_hugepages=$(remove_decimal $overcommitment_hugepages)
echo "- Allocating $overcommitment_hugepages huge pages ($overcommitment_hugepages_percentage%) for overcommitment"
sudo bash -c "echo $overcommitment_hugepages >/proc/sys/vm/nr_overcommit_hugepages"
- name: Prepare vmlinux.bin
run: |
cp .github/workflows/artifacts/vmlinux.bin .
gcloud storage cp --recursive gs://e2b-prod-public-builds/kernels/vmlinux-6.1.102/vmlinux.bin vmlinux.bin
chmod 755 vmlinux.bin
ls -lh vmlinux.bin
- name: Prepare rootfs.ext4
run: |
echo Create empty file of desired size
dd if=/dev/zero of=rootfs.ext4 bs=1M count=5000
echo Create ext4 filesystem
mkfs.ext4 rootfs.ext4
echo Make the filesystem writable by removing the read-only flag
tune2fs -O ^read-only rootfs.ext4
mkdir /tmp/my-rootfs
sudo mount rootfs.ext4 /tmp/my-rootfs
docker run -i --rm -v /tmp/my-rootfs:/my-rootfs alpine sh -c 'apk add openrc util-linux && \
ln -s agetty /etc/init.d/agetty.ttyS0 && echo ttyS0 > /etc/securetty && \
rc-update add agetty.ttyS0 default && rc-update add devfs boot && rc-update add procfs boot && rc-update add sysfs boot && \
for d in bin etc lib root sbin usr; do tar c "/$d" | tar x -C /my-rootfs; done && \
for dir in dev proc run sys var; do mkdir /my-rootfs/${dir}; done'
sudo umount /tmp/my-rootfs
echo Check filesystem
e2fsck -n rootfs.ext4
echo Get filesystem information
tune2fs -l rootfs.ext4
echo Get filesystem size
du -h rootfs.ext4
ls -lh rootfs.ext4
- name: NBD Check
run: |
sudo modprobe nbd nbds_max=4096
- name: Create Firecracker Configuration
run: |
cat <<EOF > config.json
{
"boot-source": {
"kernel_image_path": "vmlinux.bin",
"boot_args": "console=ttyS0 reboot=k panic=1 pci=off",
"initrd_path": null
},
"drives": [
{
"drive_id": "rootfs",
"partuuid": null,
"is_root_device": true,
"cache_type": "Unsafe",
"is_read_only": false,
"path_on_host": "rootfs.ext4",
"io_engine": "Sync",
"rate_limiter": null,
"socket": null
}
],
"machine-config": {
"vcpu_count": 2,
"mem_size_mib": 512,
"smt": false,
"track_dirty_pages": false,
"huge_pages": "2M"
},
"cpu-config": null,
"balloon": null,
"network-interfaces": [],
"vsock": null,
"logger": null,
"metrics": null,
"mmds-config": null,
"entropy": null
}
EOF
- name: Run Firecracker VM
run: |
set +e
sudo timeout --kill-after=5 60 ./firecracker --api-sock /tmp/firecracker.socket --config-file config.json
result=$?
set -e
if [ $result -eq 124 ]; then
echo "Process timed out after 60 seconds. Treating as success."
exit 0
elif [ $result -ne 0 ]; then
echo "Firecracker returned an error: exit code $result"
exit $result
else
echo "Firecracker completed successfully."
exit 0
fi