-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwebarena-map-backend-boot-init.yaml
More file actions
314 lines (265 loc) · 11.7 KB
/
Copy pathwebarena-map-backend-boot-init.yaml
File metadata and controls
314 lines (265 loc) · 11.7 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
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
#cloud-config
# WebArena Map Backend Server Boot-Init Script
# Based on successful deployment from trajectory analysis
# This script sets up tile server, geocoding server, and routing servers
package_update: true
package_upgrade: false
package_reboot_if_required: false
# Configure APT with retry logic and better error handling
apt:
conf: |
APT::Acquire::Retries "3";
APT::Acquire::http::Timeout "30";
APT::Acquire::https::Timeout "30";
Dpkg::Options {
"--force-confdef";
"--force-confold";
};
packages:
- docker.io
- curl
- wget
- htop
- unzip
# Create swap file to handle memory-intensive operations
bootcmd:
- |
# Create 4GB swap file to handle large data extractions (reduced from 8GB to save space)
if [ ! -f /swapfile ]; then
fallocate -l 4G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
fi
runcmd:
# Wait for package locks to be released
- while fuser /var/lib/dpkg/lock-frontend >/dev/null 2>&1; do echo "Waiting for dpkg lock..."; sleep 5; done
- while fuser /var/lib/apt/lists/lock >/dev/null 2>&1; do echo "Waiting for apt lock..."; sleep 5; done
# Enable and start Docker with retries
- systemctl enable docker
- systemctl start docker
- sleep 10
# Add ubuntu user to docker group
- usermod -aG docker ubuntu
# Create necessary directories
- mkdir -p /opt/osm_dump /opt/osrm /var/lib/docker/volumes
- mkdir -p /root/logs
# Install AWS CLI v2 (awscli package not available in Ubuntu 24.04)
- curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o /tmp/awscliv2.zip
- unzip /tmp/awscliv2.zip -d /tmp/
- /tmp/aws/install
- rm -rf /tmp/awscliv2.zip /tmp/aws
# Configure AWS CLI for S3 access (no credentials needed for public buckets)
- mkdir -p /root/.aws
- |
cat > /root/.aws/config << 'EOF'
[default]
region = us-east-2
output = json
EOF
# Create a comprehensive bootstrap script that runs in background
- |
cat > /root/bootstrap.sh << 'EOF'
#!/bin/bash
set -euo pipefail
exec > >(tee -a /var/log/webarena-map-bootstrap.log) 2>&1
echo "$(date): Starting WebArena map server bootstrap"
echo "$(date): System info: $(uname -a)"
echo "$(date): Available memory: $(free -h)"
echo "$(date): Available disk space: $(df -h)"
# Check if we have enough disk space (need at least 200GB free)
AVAILABLE_GB=$(df / | awk 'NR==2 {print int($4/1024/1024)}')
echo "$(date): Available disk space: ${AVAILABLE_GB}GB"
if [ "$AVAILABLE_GB" -lt 200 ]; then
echo "$(date): ERROR: Insufficient disk space. Need at least 200GB, have ${AVAILABLE_GB}GB"
exit 1
fi
# Function to retry commands with exponential backoff
retry() {
local n=1
local max=5
local delay=30
while true; do
"$@" && break || {
if [[ $n -lt $max ]]; then
((n++))
echo "$(date): Command failed. Attempt $n/$max. Waiting ${delay}s..."
sleep $delay
delay=$((delay * 2)) # Exponential backoff
else
echo "$(date): Command failed after $n attempts: $*"
return 1
fi
}
done
}
# Function to monitor background processes
monitor_extraction() {
local pid=$1
local desc=$2
echo "$(date): Monitoring $desc (PID: $pid)"
while kill -0 $pid 2>/dev/null; do
echo "$(date): $desc still running..."
sleep 60
done
wait $pid
local exit_code=$?
if [ $exit_code -eq 0 ]; then
echo "$(date): ✅ $desc completed successfully"
else
echo "$(date): ❌ $desc failed with exit code $exit_code"
return $exit_code
fi
}
# Download and extract data with retries and parallel processing where safe
echo "$(date): Starting data downloads..."
# Download all files first (can be done in parallel)
echo "$(date): Downloading OSM tile server data..."
retry aws s3 cp --no-sign-request s3://webarena-map-server-data/osm_tile_server.tar /root/osm_tile_server.tar &
DOWNLOAD_TILE_PID=$!
echo "$(date): Downloading Nominatim data..."
retry aws s3 cp --no-sign-request s3://webarena-map-server-data/nominatim_volumes.tar /root/nominatim_volumes.tar &
DOWNLOAD_NOM_PID=$!
echo "$(date): Downloading OSM dump..."
retry aws s3 cp --no-sign-request s3://webarena-map-server-data/osm_dump.tar /root/osm_dump.tar &
DOWNLOAD_DUMP_PID=$!
echo "$(date): Downloading OSRM routing data..."
retry aws s3 cp --no-sign-request s3://webarena-map-server-data/osrm_routing.tar /root/osrm_routing.tar &
DOWNLOAD_OSRM_PID=$!
# Wait for all downloads to complete
echo "$(date): Waiting for downloads to complete..."
monitor_extraction $DOWNLOAD_TILE_PID "OSM tile server download"
monitor_extraction $DOWNLOAD_NOM_PID "Nominatim download"
monitor_extraction $DOWNLOAD_DUMP_PID "OSM dump download"
monitor_extraction $DOWNLOAD_OSRM_PID "OSRM routing download"
echo "$(date): All downloads completed. Starting extractions..."
# Extract files sequentially to avoid memory issues and clean up immediately
# Note: Using --strip-components=5 to remove nested 'projects/ogma3/docker/volumes/' prefix
echo "$(date): Extracting OSM tile server data..."
tar -C /var/lib/docker/volumes --strip-components=5 -xf /root/osm_tile_server.tar
rm -f /root/osm_tile_server.tar # Clean up immediately to save space
echo "$(date): ✅ OSM tile server data extracted and cleaned up"
echo "$(date): Extracting Nominatim data..."
tar -C /var/lib/docker/volumes --strip-components=5 -xf /root/nominatim_volumes.tar
rm -f /root/nominatim_volumes.tar # Clean up immediately to save space
echo "$(date): ✅ Nominatim data extracted and cleaned up"
echo "$(date): Extracting OSM dump..."
tar -C /opt/osm_dump -xf /root/osm_dump.tar
rm -f /root/osm_dump.tar # Clean up immediately to save space
echo "$(date): ✅ OSM dump extracted and cleaned up"
echo "$(date): Extracting OSRM routing data..."
tar -C /opt/osrm -xf /root/osrm_routing.tar
rm -f /root/osrm_routing.tar # Clean up immediately to save space
echo "$(date): ✅ OSRM routing data extracted and cleaned up"
# Verify extracted data
echo "$(date): Verifying extracted data..."
ls -la /var/lib/docker/volumes/ | head -20
ls -la /opt/osm_dump/ | head -10
ls -la /opt/osrm/ | head -10
# Pull Docker images
echo "$(date): Pulling Docker images..."
docker pull overv/openstreetmap-tile-server
docker pull mediagis/nominatim:4.2
docker pull ghcr.io/project-osrm/osrm-backend:v5.27.1
# Start containers with restart policies and proper resource limits
echo "$(date): Starting tile server..."
docker run --name tile --restart unless-stopped \
--memory=2g --memory-swap=4g \
--volume=osm-data:/data/database/ --volume=osm-tiles:/data/tiles/ \
-p 8080:80 -d overv/openstreetmap-tile-server run
# Wait a bit for tile server to initialize
sleep 30
echo "$(date): Starting Nominatim geocoding server..."
docker run --name nominatim --restart unless-stopped \
--memory=4g --memory-swap=8g \
--env=IMPORT_STYLE=extratags \
--env=PBF_PATH=/nominatim/data/us-northeast-latest.osm.pbf \
--env=IMPORT_WIKIPEDIA=/nominatim/data/wikimedia-importance.sql.gz \
--volume=/opt/osm_dump:/nominatim/data \
--volume=nominatim-data:/var/lib/postgresql/14/main \
--volume=nominatim-flatnode:/nominatim/flatnode \
-p 8085:8080 -d mediagis/nominatim:4.2 /app/start.sh
# Wait for Nominatim to initialize
sleep 60
echo "$(date): Starting OSRM routing servers..."
# Start OSRM car routing
docker run --name osrm-car --restart unless-stopped \
--memory=4g --memory-swap=8g \
--volume=/opt/osrm/car:/data -p 5000:5000 -d \
ghcr.io/project-osrm/osrm-backend:v5.27.1 osrm-routed --algorithm mld /data/us-northeast-latest.osrm
# Start OSRM bike routing
docker run --name osrm-bike --restart unless-stopped \
--memory=4g --memory-swap=8g \
--volume=/opt/osrm/bike:/data -p 5001:5000 -d \
ghcr.io/project-osrm/osrm-backend:v5.27.1 osrm-routed --algorithm mld /data/us-northeast-latest.osrm
# Start OSRM foot routing
docker run --name osrm-foot --restart unless-stopped \
--memory=4g --memory-swap=8g \
--volume=/opt/osrm/foot:/data -p 5002:5000 -d \
ghcr.io/project-osrm/osrm-backend:v5.27.1 osrm-routed --algorithm mld /data/us-northeast-latest.osrm
echo "$(date): All services started. Waiting for initialization..."
sleep 120
echo "$(date): Verifying service health..."
docker ps --format "table {{.Names}}\t{{.Image}}\t{{.Status}}\t{{.Ports}}"
# Test service endpoints
echo "$(date): Testing service endpoints..."
# Test tile server
if curl -f -s -o /dev/null "http://localhost:8080/tile/0/0/0.png"; then
echo "$(date): ✅ Tile server is responding"
else
echo "$(date): ❌ Tile server is not responding"
fi
# Test Nominatim
if curl -f -s -o /dev/null "http://localhost:8085/search?q=test&format=json&limit=1"; then
echo "$(date): ✅ Nominatim is responding"
else
echo "$(date): ❌ Nominatim is not responding"
fi
# Test OSRM services
for service in car bike foot; do
port=$((5000 + $(echo "car bike foot" | tr ' ' '\n' | grep -n $service | cut -d: -f1) - 1))
if curl -f -s -o /dev/null "http://localhost:$port/route/v1/$service/-79.9959,40.4406;-79.9,40.45?overview=false"; then
echo "$(date): ✅ OSRM $service routing is responding"
else
echo "$(date): ❌ OSRM $service routing is not responding"
fi
done
# All tar files already cleaned up during extraction
# Final status report
echo "$(date): Bootstrap completed!"
echo "$(date): Final service status:"
docker ps
echo "$(date): Available disk space after cleanup:"
df -h
echo "$(date): Memory usage:"
free -h
echo "$(date): Services are available at:"
# 169.254.169.254 is the AWS Instance Metadata Service (IMDS) endpoint
# It provides instance metadata including the public IP address
echo " - Tile server: http://$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4):8080/tile/{z}/{x}/{y}.png"
echo " - Geocoding: http://$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4):8085/"
echo " - OSRM Car: http://$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4):5000/"
echo " - OSRM Bike: http://$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4):5001/"
echo " - OSRM Foot: http://$(curl -s http://169.254.169.254/latest/meta-data/public-ipv4):5002/"
echo "$(date): Bootstrap script completed successfully!"
EOF
# Make bootstrap script executable and run it in background
- chmod +x /root/bootstrap.sh
- nohup /root/bootstrap.sh > /var/log/webarena-map-bootstrap.log 2>&1 &
# Write completion marker
write_files:
- path: /root/cloud-init-completed
content: |
Cloud-init completed at $(date)
Bootstrap script started in background
Check /var/log/webarena-map-bootstrap.log for progress
permissions: '0644'
final_message: |
WebArena map server cloud-init completed.
Bootstrap script is running in background.
Check /var/log/webarena-map-bootstrap.log for progress.
Services will be available at:
- Tiles: http://<instance-ip>:8080/tile/{z}/{x}/{y}.png
- Geocoding: http://<instance-ip>:8085/
- Routing: http://<instance-ip>:5000 (car), :5001 (bike), :5002 (foot)