|
3 | 3 | # Purpose: Install prerequisites, pre-download core Docker images, and set up |
4 | 4 | # first-boot installer for EC2 Image Builder. |
5 | 5 | # |
| 6 | +# Env vars: |
| 7 | +# PROFILE_URL — URL to dappnode_profile.sh with pinned versions (required) |
| 8 | +# |
6 | 9 | # The installer still runs at first boot (via rc.local), but finds the heavy |
7 | | -# Docker images already cached in /usr/src/dappnode/DNCORE/, making boot fast |
8 | | -# and not dependent on network for bulk downloads. |
| 10 | +# Docker images already cached in /usr/src/dappnode/DNCORE/, making boot fast. |
9 | 11 |
|
10 | 12 | set -euo pipefail |
11 | 13 |
|
| 14 | +: "${PROFILE_URL:?PROFILE_URL env var is required}" |
| 15 | + |
12 | 16 | DAPPNODE_DIR="/usr/src/dappnode" |
13 | 17 | DNCORE_DIR="$DAPPNODE_DIR/DNCORE" |
14 | 18 | LOGS_DIR="$DAPPNODE_DIR/logs" |
15 | 19 | LOG_FILE="$LOGS_DIR/ami_build.log" |
16 | 20 |
|
| 21 | +export DEBIAN_FRONTEND=noninteractive |
| 22 | + |
17 | 23 | mkdir -p "$DAPPNODE_DIR/scripts" "$DNCORE_DIR" "$LOGS_DIR" |
18 | 24 | touch "$LOG_FILE" |
| 25 | +exec > >(tee -a "$LOG_FILE") 2>&1 |
19 | 26 |
|
20 | | -log() { echo "[AMI-BUILD] $*" | tee -a "$LOG_FILE"; } |
| 27 | +log() { echo "[AMI-BUILD] $*"; } |
21 | 28 |
|
22 | 29 | lsb_dist="$(. /etc/os-release && echo "$ID")" |
23 | | -log "Detected OS: $lsb_dist" |
| 30 | +log "OS: $lsb_dist | Profile: $PROFILE_URL" |
| 31 | + |
| 32 | +# ─── Phase 1: Prerequisites ────────────────────────────────────────────────── |
| 33 | +log "=== Phase 1: Prerequisites ===" |
24 | 34 |
|
25 | | -# ─── Docker ─────────────────────────────────────────────────────────────────── |
26 | | -install_docker() { |
| 35 | +apt-get update -y |
| 36 | + |
| 37 | +if ! docker -v >/dev/null 2>&1; then |
27 | 38 | log "Installing Docker..." |
28 | | - apt-get update -y |
29 | 39 | apt-get remove -y docker docker-engine docker.io containerd runc || true |
30 | | - |
31 | 40 | apt-get install -y ca-certificates curl lsb-release |
32 | 41 | install -m 0755 -d /etc/apt/keyrings |
33 | 42 | curl -fsSL "https://download.docker.com/linux/${lsb_dist}/gpg" -o /etc/apt/keyrings/docker.asc |
34 | 43 | chmod a+r /etc/apt/keyrings/docker.asc |
35 | | - |
36 | 44 | echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/$lsb_dist $(lsb_release -cs) stable" \ |
37 | 45 | | tee /etc/apt/sources.list.d/docker.list >/dev/null |
38 | | - |
39 | 46 | apt-get update -y |
40 | 47 | apt-get install -y docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin |
41 | | - [ -f "/usr/bin/xz" ] || apt-get install -y xz-utils |
42 | | - log "Docker installed successfully" |
43 | | -} |
| 48 | +fi |
44 | 49 |
|
45 | | -# ─── Docker Compose alias (legacy compatibility) ────────────────────────────── |
46 | | -install_compose_alias() { |
47 | | - cat >/usr/local/bin/docker-compose <<'EOL' |
| 50 | +cat >/usr/local/bin/docker-compose <<'EOL' |
48 | 51 | #!/bin/bash |
49 | 52 | docker compose "$@" |
50 | 53 | EOL |
51 | | - chmod +x /usr/local/bin/docker-compose |
52 | | -} |
53 | | - |
54 | | -# ─── Prerequisites ──────────────────────────────────────────────────────────── |
55 | | -log "=== Phase 1: Prerequisites ===" |
56 | | - |
57 | | -apt-get update -y | tee -a "$LOG_FILE" |
58 | | - |
59 | | -if ! docker -v >/dev/null 2>&1; then |
60 | | - install_docker 2>&1 | tee -a "$LOG_FILE" |
61 | | -else |
62 | | - log "Docker already installed" |
63 | | -fi |
64 | | - |
65 | | -install_compose_alias |
| 54 | +chmod +x /usr/local/bin/docker-compose |
66 | 55 |
|
67 | 56 | modprobe wireguard 2>/dev/null || apt-get install -y wireguard-dkms || apt-get install -y wireguard-tools || true |
68 | 57 | apt-get install -y lsof iptables xz-utils || true |
69 | 58 |
|
70 | | -# ─── Pre-download core Docker images ───────────────────────────────────────── |
| 59 | +# ─── Phase 2: Pre-download core images ─────────────────────────────────────── |
71 | 60 | log "=== Phase 2: Pre-downloading core images ===" |
72 | 61 |
|
73 | | -# Download latest released profile (contains version pins) |
74 | | -wget -O "$DNCORE_DIR/.dappnode_profile" \ |
75 | | - "https://github.com/dappnode/DAppNode/releases/latest/download/dappnode_profile.sh" |
| 62 | +wget -O "$DNCORE_DIR/.dappnode_profile" "$PROFILE_URL" |
76 | 63 |
|
77 | 64 | # Source only the version variables (up to ISOBUILD marker) |
78 | 65 | sed '/^\#\!ISOBUILD/q' "$DNCORE_DIR/.dappnode_profile" > /tmp/vars.sh |
@@ -106,24 +93,23 @@ for comp in "${COMPONENTS[@]}"; do |
106 | 93 | log "WARNING: Failed to download $comp manifest" |
107 | 94 | done |
108 | 95 |
|
109 | | -# Grab content hashes for execution/consensus clients |
| 96 | +# Content hashes for execution/consensus clients |
110 | 97 | CONTENT_HASH_PKGS=(besu geth nethermind erigon prysm teku lighthouse lodestar nimbus) |
111 | 98 | HASH_FILE="$DNCORE_DIR/packages-content-hash.csv" |
112 | 99 | rm -f "$HASH_FILE" |
113 | 100 | for pkg in "${CONTENT_HASH_PKGS[@]}"; do |
114 | 101 | HASH=$(wget -q -O- "https://github.com/dappnode/DAppNodePackage-${pkg}/releases/latest/download/content-hash" || true) |
115 | 102 | if [ -n "$HASH" ]; then |
116 | 103 | echo "${pkg}.dnp.dappnode.eth,${HASH}" >> "$HASH_FILE" |
117 | | - log "Got content hash for $pkg" |
| 104 | + log "Got content hash: $pkg" |
118 | 105 | fi |
119 | 106 | done |
120 | 107 |
|
121 | 108 | log "Pre-download complete:" |
122 | | -ls -lh "$DNCORE_DIR/" |
123 | 109 | du -sh "$DNCORE_DIR/" |
124 | 110 |
|
125 | | -# ─── Set up first-boot installer ───────────────────────────────────────────── |
126 | | -log "=== Phase 3: First-boot installer ===" |
| 111 | +# ─── Phase 3: First-boot installer ─────────────────────────────────────────── |
| 112 | +log "=== Phase 3: First-boot setup ===" |
127 | 113 |
|
128 | 114 | wget -O "$DAPPNODE_DIR/scripts/dappnode_install.sh" https://installer.dappnode.io |
129 | 115 | chmod +x "$DAPPNODE_DIR/scripts/dappnode_install.sh" |
|
136 | 122 | chmod +x /etc/rc.local |
137 | 123 | touch "$DAPPNODE_DIR/.firstboot" |
138 | 124 |
|
139 | | -log "=== AMI build complete. First boot will find pre-cached images in DNCORE/ ===" |
| 125 | +log "=== AMI build complete ===" |
0 commit comments