@celilo/e2e 0.4.0 → 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/bin/e2e-build CHANGED
@@ -1,12 +1,12 @@
1
1
  #!/bin/bash
2
2
  #
3
- # Pre-build all E2E Docker images.
3
+ # Pre-build all E2E Docker images and package standard modules as .netapps.
4
4
  #
5
5
  # Run once before the test suite. Subsequent test runs use the cached
6
6
  # images and skip the build phase entirely (~5s vs ~3min per test).
7
7
  #
8
8
  # Usage:
9
- # ./e2e/bin/e2e-build # build all images
9
+ # ./e2e/bin/e2e-build # build netapps + all images
10
10
  # ./e2e/bin/e2e-build --save # build + save to tarball for colima restarts
11
11
  #
12
12
 
@@ -14,6 +14,11 @@ set -e
14
14
 
15
15
  SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
16
16
  E2E_DIR="$(dirname "$SCRIPT_DIR")"
17
+ PKG_DIR="$E2E_DIR"
18
+ REPO_ROOT="$(cd "$E2E_DIR/../.." && pwd)"
19
+ MODULES_DIR="$REPO_ROOT/modules"
20
+ NETAPPS_DIR="$E2E_DIR/netapps"
21
+
17
22
  cd "$E2E_DIR"
18
23
 
19
24
  GREEN='\033[0;32m'
@@ -21,6 +26,43 @@ DIM='\033[2m'
21
26
  BOLD='\033[1m'
22
27
  NC='\033[0m'
23
28
 
29
+ # ── Step 1: Package standard modules as .netapp files ─────────────────────────
30
+
31
+ STANDARD_MODULES=(namecheap greenwave iptables caddy authentik)
32
+
33
+ echo -e "${BOLD}Packaging standard modules...${NC}"
34
+ echo ""
35
+
36
+ mkdir -p "$NETAPPS_DIR"
37
+
38
+ for MODULE in "${STANDARD_MODULES[@]}"; do
39
+ SRC="$MODULES_DIR/$MODULE"
40
+ OUT="$NETAPPS_DIR/$MODULE.netapp"
41
+
42
+ if [ ! -d "$SRC" ]; then
43
+ echo -e " ${DIM}skip${NC} $MODULE ${DIM}(not found at $SRC)${NC}"
44
+ continue
45
+ fi
46
+
47
+ printf " %-20s " "$MODULE"
48
+ BUILD_START=$(date +%s)
49
+
50
+ # Use the wrapper script if available, else bun directly
51
+ if [ -x "$REPO_ROOT/celilo" ]; then
52
+ "$REPO_ROOT/celilo" package "$SRC" --output "$OUT" > /dev/null 2>&1
53
+ else
54
+ bun run "$REPO_ROOT/apps/celilo/src/cli/index.ts" package "$SRC" --output "$OUT" > /dev/null 2>&1
55
+ fi
56
+
57
+ BUILD_END=$(date +%s)
58
+ SIZE=$(du -h "$OUT" 2>/dev/null | cut -f1)
59
+ echo -e "${GREEN}✔${NC} ${DIM}$((BUILD_END - BUILD_START))s ${SIZE}${NC}"
60
+ done
61
+
62
+ echo ""
63
+
64
+ # ── Step 2: Build Docker images ───────────────────────────────────────────────
65
+
24
66
  echo -e "${BOLD}Building E2E Docker images...${NC}"
25
67
  echo ""
26
68
 
@@ -48,7 +90,8 @@ TOTAL_TIME=$((END - START))
48
90
  echo ""
49
91
  echo -e "${GREEN}All $TOTAL images built in ${TOTAL_TIME}s${NC}"
50
92
 
51
- # Optionally save to tarball
93
+ # ── Step 3: Optionally save images to tarball ─────────────────────────────────
94
+
52
95
  if [ "$1" = "--save" ]; then
53
96
  echo ""
54
97
  echo -e "${BOLD}Saving images to tarball...${NC}"
@@ -2,7 +2,7 @@ $ORIGIN iamtheinternet.org.
2
2
  $TTL 300
3
3
 
4
4
  @ IN SOA ns1.iamtheinternet.org. admin.iamtheinternet.org. (
5
- 2024010772 300 60 604800 300
5
+ 2024010778 300 60 604800 300
6
6
  )
7
7
 
8
8
  @ IN NS ns1.iamtheinternet.org.
@@ -22,9 +22,19 @@ RUN update-ca-certificates
22
22
  # Point apt at the simulated apt cache proxy (for runtime apt usage)
23
23
  RUN echo 'Acquire::http::Proxy "http://100.64.0.2:3142";' > /etc/apt/apt.conf.d/00proxy
24
24
 
25
- # Install celilo CLI from npm — provides the `celilo` command
25
+ # Install celilo CLI from npm — provides the fallback `celilo` command
26
26
  RUN bun add -g @celilo/cli@0.1.4
27
27
 
28
+ # Shim: prefer /celilo source when mounted (dev loop), fall back to npm install.
29
+ # This means `celilo ...` runs the monorepo's source code during e2e tests
30
+ # instead of the pinned npm version — critical for iterating on fixes.
31
+ RUN printf '#!/bin/bash\nif [ -d /celilo/apps/celilo ]; then\n exec bun run /celilo/apps/celilo/src/cli/index.ts "$@"\nfi\nexec /root/.bun/bin/celilo "$@"\n' > /usr/local/bin/celilo \
32
+ && chmod +x /usr/local/bin/celilo
33
+
34
+ # Standard modules pre-packaged as .netapp files — built by e2e-build.
35
+ # Tests import from /netapps/<module>.netapp instead of the monorepo mount.
36
+ COPY netapps/ /netapps/
37
+
28
38
  COPY config/ssh/generate-keys.sh /config/ssh/generate-keys.sh
29
39
  COPY config/routing/management-routes.sh /startup.sh
30
40
  RUN chmod +x /startup.sh /config/ssh/generate-keys.sh
@@ -12,6 +12,9 @@ RUN apt-get update && apt-get install -y \
12
12
  dnsutils \
13
13
  procps \
14
14
  python3 \
15
+ python3-apt \
16
+ sqlite3 \
17
+ jq \
15
18
  sudo \
16
19
  curl \
17
20
  ca-certificates \
@@ -16,6 +16,9 @@ RUN apt-get update && apt-get install -y \
16
16
  dnsutils \
17
17
  procps \
18
18
  python3 \
19
+ python3-apt \
20
+ sqlite3 \
21
+ jq \
19
22
  sudo \
20
23
  curl \
21
24
  ca-certificates \
File without changes
Binary file
Binary file
Binary file
Binary file
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@celilo/e2e",
3
- "version": "0.4.0",
3
+ "version": "0.5.0",
4
4
  "description": "E2E test infrastructure for Celilo-deployed applications. Provides a simulated internet with DNS hierarchy, ACME server, firewalls, and target machines in Docker.",
5
5
  "type": "module",
6
6
  "main": "./src/index.ts",
@@ -21,6 +21,7 @@
21
21
  "config/",
22
22
  "simulators/",
23
23
  "bin/",
24
+ "netapps/",
24
25
  "README.md"
25
26
  ],
26
27
  "dependencies": {
@@ -158,6 +158,66 @@ async function waitFor(
158
158
  throw new Error(`Timeout waiting for ${label} after ${timeoutMs}ms`);
159
159
  }
160
160
 
161
+ /**
162
+ * Run `docker compose build` with per-service progress signals.
163
+ * Uses --progress=plain so output is parseable on non-TTY.
164
+ * Emits one [progress:start] per service being built so the runner
165
+ * shows "building <service>" as each image is compiled.
166
+ */
167
+ async function streamingBuild(
168
+ projectName: string,
169
+ composeDir: string,
170
+ composeFile: string,
171
+ ): Promise<void> {
172
+ return new Promise<void>((resolve, reject) => {
173
+ const proc = spawn(
174
+ 'docker',
175
+ ['compose', '-f', composeFile, '-p', projectName, 'build', '--progress=plain'],
176
+ { cwd: composeDir },
177
+ );
178
+
179
+ const seenServices = new Set<string>();
180
+ let stderr = '';
181
+
182
+ function handleLine(line: string) {
183
+ // --progress=plain lines look like: #5 [management 2/4] RUN apt-get ...
184
+ const svcMatch = line.match(/\[([a-z][a-z0-9-]*)\s+\d+\/\d+\]/);
185
+ if (svcMatch) {
186
+ const svc = svcMatch[1];
187
+ if (!seenServices.has(svc)) {
188
+ seenServices.add(svc);
189
+ // Each new service auto-finalizes the previous [progress:start] in the runner.
190
+ console.log(`[progress:start] building image: ${svc} | ${svc} image ready`);
191
+ }
192
+ }
193
+ }
194
+
195
+ let buf = '';
196
+ function onData(chunk: Buffer) {
197
+ buf += chunk.toString();
198
+ const lines = buf.split('\n');
199
+ buf = lines.pop() ?? '';
200
+ for (const line of lines) handleLine(line.trim());
201
+ }
202
+
203
+ proc.stdout.on('data', onData);
204
+ proc.stderr.on('data', (chunk: Buffer) => {
205
+ stderr += chunk.toString();
206
+ onData(chunk);
207
+ });
208
+
209
+ proc.on('close', (code) => {
210
+ if (buf.trim()) handleLine(buf.trim());
211
+ if (code === 0) {
212
+ console.log('[progress:done] images built');
213
+ resolve();
214
+ } else {
215
+ reject(new Error(`docker compose build failed (exit ${code}):\n${stderr.slice(-500)}`));
216
+ }
217
+ });
218
+ });
219
+ }
220
+
161
221
  export async function startNetwork(config: NetworkConfig): Promise<NetworkHandle> {
162
222
  // Pre-flight: fail if live containers are running that will compete for resources.
163
223
  try {
@@ -218,9 +278,9 @@ export async function startNetwork(config: NetworkConfig): Promise<NetworkHandle
218
278
  const yaml = generateTestComposeYaml(config, celiloRoot);
219
279
  writeFileSync(join(composeDir, COMPOSE_FILE), yaml);
220
280
 
221
- // Build and start per-test containers only
222
- console.log('[progress:start] building Docker images | images built');
223
- run(`docker compose -f ${COMPOSE_FILE} -p ${projectName} build`, { cwd: composeDir, timeout: 600_000 });
281
+ // Build and start per-test containers only — stream output so the runner
282
+ // can show which service is currently being built (can take minutes on cold cache).
283
+ await streamingBuild(projectName, composeDir, COMPOSE_FILE);
224
284
 
225
285
  console.log('[progress:start] starting containers | containers running');
226
286
  run(`docker compose -f ${COMPOSE_FILE} -p ${projectName} up -d`, { cwd: composeDir, timeout: 120_000 });