@celilo/e2e 0.9.2 → 0.10.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/config/cpanel-host/cpanel-host-ca.crt +20 -0
- package/config/cpanel-host/docroot/.htaccess +14 -0
- package/config/cpanel-host/docroot/cms.html +4 -0
- package/config/cpanel-host/site-tls.crt +20 -0
- package/config/cpanel-host/site-tls.key +28 -0
- package/config/cpanel-host/site.conf +27 -0
- package/config/dns/com.zone +7 -0
- package/config/dns/knot-namecheap.conf +6 -0
- package/config/dns/tangohost.com.zone +14 -0
- package/config/proxy/squid.conf +7 -2
- package/config/resolver/unbound.conf +39 -3
- package/config/routing/management-routes.sh +9 -4
- package/config/routing/resolver-internal-routes.sh +10 -0
- package/docker/Dockerfile.cpanel-host-sim +70 -0
- package/docker/Dockerfile.firewall +12 -0
- package/docker/Dockerfile.management +6 -0
- package/docker/Dockerfile.minio +1 -1
- package/docker/Dockerfile.observer +11 -0
- package/docker/Dockerfile.signal-cli +60 -0
- package/docker/Dockerfile.signal-release +36 -0
- package/docker/Dockerfile.signal-sim +17 -0
- package/docker/Dockerfile.target-machine +10 -1
- package/docker/Dockerfile.target-machine-docker +1 -1
- package/docker/Dockerfile.target-technitium +1 -1
- package/package.json +1 -1
- package/registry-server/src/auth.ts +2 -2
- package/registry-server/src/introspection.test.ts +247 -0
- package/registry-server/src/introspection.ts +204 -0
- package/registry-server/src/module-owner-store.test.ts +85 -0
- package/registry-server/src/module-owner-store.ts +108 -0
- package/registry-server/src/server.test.ts +262 -0
- package/registry-server/src/server.ts +139 -10
- package/scripts/pack-celilo-packages.ts +79 -51
- package/scripts/stage-libsignal.ts +116 -0
- package/simulators/signal-cli/server.ts +272 -0
- package/src/cli/build.ts +35 -9
- package/src/cli/command-registry.ts +34 -6
- package/src/cli/index.ts +59 -21
- package/src/container-manager.ts +6 -2
- package/src/docker-compose-generator.ts +108 -4
- package/src/network-builder.ts +52 -0
- package/src/runner.ts +128 -57
- package/src/simulator-ips.ts +9 -0
- package/src/types.ts +34 -0
- package/config/dns/example.net.zone +0 -16
- package/config/dns/iamtheinternet.org.zone +0 -16
package/src/runner.ts
CHANGED
|
@@ -17,11 +17,11 @@
|
|
|
17
17
|
* Countdown goes negative when over estimate.
|
|
18
18
|
*/
|
|
19
19
|
|
|
20
|
-
import { spawn, spawnSync
|
|
20
|
+
import { execSync, spawn, spawnSync } from 'node:child_process';
|
|
21
21
|
import { existsSync, mkdirSync, readFileSync, readdirSync, writeFileSync } from 'node:fs';
|
|
22
22
|
import { basename, dirname, join, resolve } from 'node:path';
|
|
23
|
-
import { parse as parseYaml } from 'yaml';
|
|
24
23
|
import { type DisplayMode, ProgressDisplay } from '@celilo/cli-display';
|
|
24
|
+
import { parse as parseYaml } from 'yaml';
|
|
25
25
|
import {
|
|
26
26
|
emitRunCompleted,
|
|
27
27
|
emitRunFailed,
|
|
@@ -30,7 +30,7 @@ import {
|
|
|
30
30
|
emitTestStarted,
|
|
31
31
|
} from './bus-events';
|
|
32
32
|
import { parseLine } from './parse-line';
|
|
33
|
-
import {
|
|
33
|
+
import { E2eBusyError, acquireRunLock, markKept } from './run-lock';
|
|
34
34
|
import { SIMULATOR_IPS } from './simulator-ips';
|
|
35
35
|
|
|
36
36
|
// ─── Config ──────────────────────────────────────────────────────────
|
|
@@ -50,7 +50,9 @@ function resolveModuleTestsDir(dir: string): string {
|
|
|
50
50
|
const manifestPath = join(dir, 'manifest.yml');
|
|
51
51
|
if (existsSync(manifestPath)) {
|
|
52
52
|
try {
|
|
53
|
-
const parsed = parseYaml(readFileSync(manifestPath, 'utf-8')) as {
|
|
53
|
+
const parsed = parseYaml(readFileSync(manifestPath, 'utf-8')) as {
|
|
54
|
+
e2e?: { tests_dir?: string };
|
|
55
|
+
};
|
|
54
56
|
if (parsed?.e2e?.tests_dir) return resolve(dir, parsed.e2e.tests_dir);
|
|
55
57
|
} catch {}
|
|
56
58
|
}
|
|
@@ -84,11 +86,14 @@ const flagCi = rawArgs.includes('--ci');
|
|
|
84
86
|
const flagNoCi = rawArgs.includes('--no-ci');
|
|
85
87
|
const ci = flagCi || (!flagNoCi && !!process.env.CI);
|
|
86
88
|
const patterns = rawArgs.filter((a) => !a.startsWith('--'));
|
|
87
|
-
//
|
|
88
|
-
// known-failing
|
|
89
|
-
//
|
|
90
|
-
//
|
|
91
|
-
|
|
89
|
+
// Quarantine: tests whose file contains the marker `cele2e-ci-unsafe` (a comment
|
|
90
|
+
// naming the reason + ISS) are known-failing / builder-flaky and tracked
|
|
91
|
+
// separately, so they must never turn a broad run red. They are SKIPPED by
|
|
92
|
+
// default in every broad run (`--all`, `--all-modules`, `--ci-safe`, bare). Two
|
|
93
|
+
// ways to run one anyway: name it explicitly (`cele2e run <name>`), or pass
|
|
94
|
+
// `--complete` (the deliberate "run everything, including quarantined" opt-in).
|
|
95
|
+
// `--complete` is passed through from the CLI (not stripped) so the runner sees it.
|
|
96
|
+
const flagComplete = rawArgs.includes('--complete');
|
|
92
97
|
// --notify: fire a desktop notification when the run finishes (handy for long
|
|
93
98
|
// detached/background runs). Best-effort — never affects the exit code.
|
|
94
99
|
const flagNotify = rawArgs.includes('--notify');
|
|
@@ -123,9 +128,20 @@ function notify(title: string, message: string): void {
|
|
|
123
128
|
if (!flagNotify) return;
|
|
124
129
|
try {
|
|
125
130
|
if (process.platform === 'darwin') {
|
|
126
|
-
const r = spawnSync(
|
|
131
|
+
const r = spawnSync(
|
|
132
|
+
'terminal-notifier',
|
|
133
|
+
['-title', title, '-message', message, '-sound', 'Glass'],
|
|
134
|
+
{ stdio: 'ignore' },
|
|
135
|
+
);
|
|
127
136
|
if (r.error) {
|
|
128
|
-
spawnSync(
|
|
137
|
+
spawnSync(
|
|
138
|
+
'osascript',
|
|
139
|
+
[
|
|
140
|
+
'-e',
|
|
141
|
+
`display notification ${JSON.stringify(message)} with title ${JSON.stringify(title)} sound name "Glass"`,
|
|
142
|
+
],
|
|
143
|
+
{ stdio: 'ignore' },
|
|
144
|
+
);
|
|
129
145
|
}
|
|
130
146
|
spawnSync('say', [message], { stdio: 'ignore' });
|
|
131
147
|
} else if (process.platform === 'linux') {
|
|
@@ -182,7 +198,10 @@ function extractFailureMessage(lines: string[], exitCode: number): string {
|
|
|
182
198
|
// bun's own test failure: "✗ test name [Xms]" — extract the failing test name
|
|
183
199
|
const bunFailIdx = plain.findIndex((l) => /^\s*✗\s+\S/.test(l) && !l.includes('failed ('));
|
|
184
200
|
if (bunFailIdx >= 0) {
|
|
185
|
-
const testName = plain[bunFailIdx]
|
|
201
|
+
const testName = plain[bunFailIdx]
|
|
202
|
+
.replace(/^\s*✗\s+/, '')
|
|
203
|
+
.replace(/\s*\[\d+ms\].*$/, '')
|
|
204
|
+
.trim();
|
|
186
205
|
// Grab the error detail on the next few lines (bun indents it under the test)
|
|
187
206
|
const detail = plain
|
|
188
207
|
.slice(bunFailIdx + 1, bunFailIdx + 6)
|
|
@@ -215,7 +234,13 @@ function extractFailureMessage(lines: string[], exitCode: number): string {
|
|
|
215
234
|
|
|
216
235
|
// Last resort: print the last few non-empty, non-progress lines from the output
|
|
217
236
|
const tail = plain
|
|
218
|
-
.filter(
|
|
237
|
+
.filter(
|
|
238
|
+
(l) =>
|
|
239
|
+
l.length > 0 &&
|
|
240
|
+
!l.startsWith('[progress') &&
|
|
241
|
+
!l.startsWith('[e2e:') &&
|
|
242
|
+
!l.startsWith('[ansible:'),
|
|
243
|
+
)
|
|
219
244
|
.slice(-3)
|
|
220
245
|
.map((l) => l.trim())
|
|
221
246
|
.join(' | ');
|
|
@@ -270,7 +295,9 @@ async function runTest(
|
|
|
270
295
|
testEnv.CELILO_E2E_REUSE = '1';
|
|
271
296
|
testEnv.CELILO_E2E_PROJECT = data.projectName;
|
|
272
297
|
} catch {
|
|
273
|
-
console.error(
|
|
298
|
+
console.error(
|
|
299
|
+
`${red}✗ --reuse: no persistent network found. Run with --keep first.${reset}`,
|
|
300
|
+
);
|
|
274
301
|
process.exit(1);
|
|
275
302
|
}
|
|
276
303
|
}
|
|
@@ -298,23 +325,32 @@ async function runTest(
|
|
|
298
325
|
process.stdout.write(`${bold}\x1b[33m║${reset} Container: ${bold}${container}${reset}\n`);
|
|
299
326
|
process.stdout.write(`${bold}\x1b[33m║${reset}\n`);
|
|
300
327
|
process.stdout.write(`${bold}\x1b[33m║${reset} ${dim}Run commands:${reset}\n`);
|
|
301
|
-
process.stdout.write(
|
|
302
|
-
|
|
328
|
+
process.stdout.write(
|
|
329
|
+
`${bold}\x1b[33m║${reset} docker compose -f docker-compose.test.yml \\\n`,
|
|
330
|
+
);
|
|
331
|
+
process.stdout.write(
|
|
332
|
+
`${bold}\x1b[33m║${reset} -p ${project} exec ${container} bash -c '<cmd>'\n`,
|
|
333
|
+
);
|
|
303
334
|
process.stdout.write(`${bold}\x1b[33m║${reset}\n`);
|
|
304
335
|
|
|
305
336
|
if (interactive) {
|
|
306
|
-
process.stdout.write(
|
|
337
|
+
process.stdout.write(
|
|
338
|
+
`${bold}\x1b[33m║${reset} ${dim}Or get a shell: type 'exit' to resume the test.${reset}\n`,
|
|
339
|
+
);
|
|
307
340
|
process.stdout.write(`${bold}\x1b[33m╚${border}${reset}\n\n`);
|
|
308
341
|
|
|
309
|
-
spawnSync(
|
|
310
|
-
'
|
|
311
|
-
'exec', container, 'bash',
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
342
|
+
spawnSync(
|
|
343
|
+
'docker',
|
|
344
|
+
['compose', '-f', 'docker-compose.test.yml', '-p', project, 'exec', container, 'bash'],
|
|
345
|
+
{
|
|
346
|
+
cwd: PKG_DIR,
|
|
347
|
+
stdio: 'inherit',
|
|
348
|
+
},
|
|
349
|
+
);
|
|
316
350
|
} else {
|
|
317
|
-
process.stdout.write(
|
|
351
|
+
process.stdout.write(
|
|
352
|
+
`${bold}\x1b[33m║${reset} ${dim}Resume: touch ${signalFile}${reset}\n`,
|
|
353
|
+
);
|
|
318
354
|
process.stdout.write(`${bold}\x1b[33m╚${border}${reset}\n\n`);
|
|
319
355
|
|
|
320
356
|
// Non-interactive: just wait for the signal file (no shell)
|
|
@@ -376,7 +412,7 @@ async function runTest(
|
|
|
376
412
|
writeFileSync(logFile, stdout + '\n---STDERR---\n' + stderr);
|
|
377
413
|
|
|
378
414
|
const expectMatch = stdout.match(/(\d+) expect\(\) calls/);
|
|
379
|
-
const expectCount = expectMatch ? parseInt(expectMatch[1], 10) : undefined;
|
|
415
|
+
const expectCount = expectMatch ? Number.parseInt(expectMatch[1], 10) : undefined;
|
|
380
416
|
|
|
381
417
|
if (code === 0) {
|
|
382
418
|
if (expectCount === 0) {
|
|
@@ -389,7 +425,13 @@ async function runTest(
|
|
|
389
425
|
error: '0 assertions — test likely exited before reaching assertions',
|
|
390
426
|
});
|
|
391
427
|
} else {
|
|
392
|
-
resolveTest({
|
|
428
|
+
resolveTest({
|
|
429
|
+
name,
|
|
430
|
+
status: 'pass',
|
|
431
|
+
duration,
|
|
432
|
+
hadDebugPause,
|
|
433
|
+
projectName: capturedProjectName,
|
|
434
|
+
});
|
|
393
435
|
}
|
|
394
436
|
} else {
|
|
395
437
|
// Collect a raw tail: strip ANSI, drop internal protocol lines, keep last 30
|
|
@@ -397,12 +439,13 @@ async function runTest(
|
|
|
397
439
|
.split('\n')
|
|
398
440
|
.map(stripAnsi)
|
|
399
441
|
.map((l) => l.trimEnd())
|
|
400
|
-
.filter(
|
|
401
|
-
l
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
442
|
+
.filter(
|
|
443
|
+
(l) =>
|
|
444
|
+
l.length > 0 &&
|
|
445
|
+
!l.startsWith('[progress') &&
|
|
446
|
+
!l.startsWith('[e2e:') &&
|
|
447
|
+
!l.startsWith('[ansible:') &&
|
|
448
|
+
!l.startsWith('[debug:'),
|
|
406
449
|
)
|
|
407
450
|
.slice(-30)
|
|
408
451
|
.join('\n');
|
|
@@ -424,10 +467,12 @@ async function runTest(
|
|
|
424
467
|
|
|
425
468
|
function dockerComposeShared(cmd: string): string {
|
|
426
469
|
try {
|
|
427
|
-
return execSync(
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
470
|
+
return execSync(`docker compose -f docker-compose.shared.yml -p celilo-e2e-shared ${cmd}`, {
|
|
471
|
+
cwd: PKG_DIR,
|
|
472
|
+
encoding: 'utf-8',
|
|
473
|
+
stdio: ['pipe', 'pipe', 'pipe'],
|
|
474
|
+
timeout: 60_000,
|
|
475
|
+
}).trim();
|
|
431
476
|
} catch {
|
|
432
477
|
return '';
|
|
433
478
|
}
|
|
@@ -435,7 +480,9 @@ function dockerComposeShared(cmd: string): string {
|
|
|
435
480
|
|
|
436
481
|
function stopSharedInfra(): void {
|
|
437
482
|
dockerComposeShared('down --volumes --remove-orphans');
|
|
438
|
-
try {
|
|
483
|
+
try {
|
|
484
|
+
execSync('docker network prune -f', { stdio: 'pipe', timeout: 10_000 });
|
|
485
|
+
} catch {}
|
|
439
486
|
}
|
|
440
487
|
|
|
441
488
|
/**
|
|
@@ -486,14 +533,20 @@ async function main() {
|
|
|
486
533
|
// docker mutation so a competing run can't wipe our shared infra mid-setup.
|
|
487
534
|
const lockLabel = patterns.length ? patterns.join(',') : moduleDirs.length ? 'modules' : 'all';
|
|
488
535
|
try {
|
|
489
|
-
acquireRunLock({
|
|
536
|
+
acquireRunLock({
|
|
537
|
+
test: lockLabel,
|
|
538
|
+
runId: process.env.CELE2E_RUN_ID ?? ambientRunId,
|
|
539
|
+
allowKept: flagReuse,
|
|
540
|
+
});
|
|
490
541
|
// A --reuse run keeps using a kept stack that stays up afterwards — hold the
|
|
491
542
|
// lock in kept state so it isn't freed out from under the reused network.
|
|
492
543
|
if (flagReuse) markKept();
|
|
493
544
|
} catch (err) {
|
|
494
545
|
if (err instanceof E2eBusyError) {
|
|
495
546
|
console.error(`\n${red}${err.message}${reset}`);
|
|
496
|
-
console.error(
|
|
547
|
+
console.error(
|
|
548
|
+
`${dim}Poll with: cele2e status (machine-readable: cele2e status --json)${reset}\n`,
|
|
549
|
+
);
|
|
497
550
|
process.exit(3);
|
|
498
551
|
}
|
|
499
552
|
throw err;
|
|
@@ -511,7 +564,9 @@ async function main() {
|
|
|
511
564
|
const tp = resolveModuleTestsDir(dir);
|
|
512
565
|
if (!existsSync(tp)) {
|
|
513
566
|
console.error(`${red}No tests directory found at ${tp}${reset}`);
|
|
514
|
-
console.error(
|
|
567
|
+
console.error(
|
|
568
|
+
`${red}Set e2e.tests_dir in ${join(dir, 'manifest.yml')} to point to your test files.${reset}`,
|
|
569
|
+
);
|
|
515
570
|
process.exit(1);
|
|
516
571
|
}
|
|
517
572
|
// Auto-install e2e/ dependencies if package.json exists but node_modules is missing
|
|
@@ -573,11 +628,10 @@ async function main() {
|
|
|
573
628
|
testFiles = testFiles.filter((f) => patterns.some((p) => basename(f, '.test.ts').includes(p)));
|
|
574
629
|
}
|
|
575
630
|
|
|
576
|
-
//
|
|
577
|
-
//
|
|
578
|
-
//
|
|
579
|
-
|
|
580
|
-
if (flagCiSafe) {
|
|
631
|
+
// Drop quarantined tests (file contains `cele2e-ci-unsafe`) from broad runs so
|
|
632
|
+
// they never turn a full run red. Skipped by default; bypassed only when the
|
|
633
|
+
// user explicitly named tests (`patterns.length > 0`) or passed `--complete`.
|
|
634
|
+
if (!flagComplete && patterns.length === 0) {
|
|
581
635
|
const before = testFiles.length;
|
|
582
636
|
testFiles = testFiles.filter((f) => {
|
|
583
637
|
try {
|
|
@@ -588,7 +642,9 @@ async function main() {
|
|
|
588
642
|
});
|
|
589
643
|
const skipped = before - testFiles.length;
|
|
590
644
|
if (skipped > 0) {
|
|
591
|
-
console.log(
|
|
645
|
+
console.log(
|
|
646
|
+
`${dim}skipped ${skipped} quarantined (cele2e-ci-unsafe) test(s) — pass --complete or name one to run it${reset}`,
|
|
647
|
+
);
|
|
592
648
|
}
|
|
593
649
|
}
|
|
594
650
|
|
|
@@ -637,7 +693,9 @@ async function main() {
|
|
|
637
693
|
console.log(`${bold}╔══════════════════════════════════════════════════════════════${reset}`);
|
|
638
694
|
console.log(`${bold}║ Celilo E2E Tests${moduleLabel}${reset}`);
|
|
639
695
|
if (hasHistory) {
|
|
640
|
-
console.log(
|
|
696
|
+
console.log(
|
|
697
|
+
`${bold}║ ${testFiles.length} test(s) — expected ~${formatDuration(suiteExpected)}${reset}`,
|
|
698
|
+
);
|
|
641
699
|
} else {
|
|
642
700
|
console.log(`${bold}║ ${testFiles.length} test(s) — first run, no timing history${reset}`);
|
|
643
701
|
}
|
|
@@ -741,7 +799,8 @@ async function main() {
|
|
|
741
799
|
emitTestCompleted({
|
|
742
800
|
runId,
|
|
743
801
|
name,
|
|
744
|
-
status:
|
|
802
|
+
status:
|
|
803
|
+
result.status === 'pass' ? 'pass' : result.status === 'suspicious' ? 'suspicious' : 'fail',
|
|
745
804
|
durationMs: result.duration * 1000,
|
|
746
805
|
error: result.error,
|
|
747
806
|
logDir,
|
|
@@ -757,11 +816,15 @@ async function main() {
|
|
|
757
816
|
if (flagKeep && result.projectName) {
|
|
758
817
|
writeFileSync(
|
|
759
818
|
persistentFile,
|
|
760
|
-
JSON.stringify(
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
819
|
+
JSON.stringify(
|
|
820
|
+
{
|
|
821
|
+
projectName: result.projectName,
|
|
822
|
+
testFile: file,
|
|
823
|
+
createdAt: new Date().toISOString(),
|
|
824
|
+
},
|
|
825
|
+
null,
|
|
826
|
+
2,
|
|
827
|
+
) + '\n',
|
|
765
828
|
);
|
|
766
829
|
console.log(`${dim} Persistent network: ${result.projectName}${reset}`);
|
|
767
830
|
console.log(`${dim} Reuse: ${basename(process.argv[1])} --reuse${reset}`);
|
|
@@ -800,7 +863,9 @@ async function main() {
|
|
|
800
863
|
JSON.stringify({ status: result.status, duration: result.duration, error: result.error }),
|
|
801
864
|
);
|
|
802
865
|
|
|
803
|
-
try {
|
|
866
|
+
try {
|
|
867
|
+
execSync('docker network prune -f', { stdio: 'pipe', timeout: 10_000 });
|
|
868
|
+
} catch {}
|
|
804
869
|
}
|
|
805
870
|
|
|
806
871
|
saveTiming(history);
|
|
@@ -820,7 +885,9 @@ async function main() {
|
|
|
820
885
|
for (const r of results) {
|
|
821
886
|
const icon = r.status === 'pass' ? '✓' : '✗';
|
|
822
887
|
const color = r.status === 'pass' ? green : red;
|
|
823
|
-
console.log(
|
|
888
|
+
console.log(
|
|
889
|
+
`${bold}║${reset} ${color}${icon}${reset} ${r.name.padEnd(28)} ${dim}${(r.duration + 's').padStart(6)}${reset}`,
|
|
890
|
+
);
|
|
824
891
|
if (r.error) {
|
|
825
892
|
console.log(`${bold}║${reset} ${red}└─ ${r.error}${reset}`);
|
|
826
893
|
}
|
|
@@ -832,7 +899,11 @@ async function main() {
|
|
|
832
899
|
|
|
833
900
|
writeFileSync(
|
|
834
901
|
join(resultsDir, 'summary.json'),
|
|
835
|
-
JSON.stringify(
|
|
902
|
+
JSON.stringify(
|
|
903
|
+
{ timestamp, total: testFiles.length, passed, failed, duration: suiteDuration },
|
|
904
|
+
null,
|
|
905
|
+
2,
|
|
906
|
+
),
|
|
836
907
|
);
|
|
837
908
|
|
|
838
909
|
const gitignore = join(testDir, '.gitignore');
|
package/src/simulator-ips.ts
CHANGED
|
@@ -35,6 +35,15 @@ export const SIMULATOR_IPS = {
|
|
|
35
35
|
APT_REPO: '100.64.0.60',
|
|
36
36
|
/** MinIO S3-compatible object storage — backup/restore target (replaces AWS S3 in tests). Reachable at http://minio.lab. */
|
|
37
37
|
MINIO: '100.64.0.61',
|
|
38
|
+
/**
|
|
39
|
+
* OFF-FLEET cPanel/SSH web host simulator (`tangohost.com`) — a third-party
|
|
40
|
+
* host celilo publishes to via `external_web` but does NOT govern. A public
|
|
41
|
+
* peer of namecheap-dns/pebble, NOT behind the customer firewall, so public
|
|
42
|
+
* DNS pointing the domain here is a genuine public endpoint.
|
|
43
|
+
*/
|
|
44
|
+
CPANEL_HOST: '100.64.0.63',
|
|
45
|
+
/** signal-cli release host — serves the tarball the signal module downloads at deploy time. */
|
|
46
|
+
SIGNAL_RELEASE: '100.64.0.62',
|
|
38
47
|
/** Pebble ACME server (replaces production Let's Encrypt). */
|
|
39
48
|
PEBBLE: '100.64.0.100',
|
|
40
49
|
} as const;
|
package/src/types.ts
CHANGED
|
@@ -45,6 +45,40 @@ export interface NetworkConfig {
|
|
|
45
45
|
managementVolumes: string[];
|
|
46
46
|
/** Include a DHCP client container on the internal network */
|
|
47
47
|
dhcpClient: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* Include a REAL signal-cli daemon on the internal network.
|
|
50
|
+
*
|
|
51
|
+
* Never linked to a Signal account — the JSON-RPC interface is served
|
|
52
|
+
* locally and needs none. It exists so the contract celilo's client depends
|
|
53
|
+
* on is verified against the actual binary rather than against a simulator
|
|
54
|
+
* that encodes the same assumptions. See design.md D16.
|
|
55
|
+
*/
|
|
56
|
+
signalCli: boolean;
|
|
57
|
+
/**
|
|
58
|
+
* Include the signal-cli SIMULATOR on the internal network.
|
|
59
|
+
*
|
|
60
|
+
* The drivable counterpart to `signalCli`: it can queue an inbound reply,
|
|
61
|
+
* fail a recipient inside a JSON-RPC success, and revoke the device link on
|
|
62
|
+
* command, which is what a test of the delivery/ack loop needs and what an
|
|
63
|
+
* unlinked real daemon cannot be made to do.
|
|
64
|
+
*/
|
|
65
|
+
signalSim: boolean;
|
|
66
|
+
/**
|
|
67
|
+
* Serve the signal-cli release tarball from the simulated internet, so the
|
|
68
|
+
* signal module's deploy-time download resolves inside the sealed network.
|
|
69
|
+
*/
|
|
70
|
+
signalRelease: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Which zone the celilo management container sits in. Defaults to `internal`
|
|
73
|
+
* — the single-network topology every existing test uses.
|
|
74
|
+
*
|
|
75
|
+
* `secure-mgmt` places celilo-mgr on its OWN control-plane network, which is
|
|
76
|
+
* the production topology and the one the suite could not express before. That
|
|
77
|
+
* gap is why the control-plane-network bug reached production: with management
|
|
78
|
+
* always on `internal`, the hardcoded "trusted subnet == network.internal.subnet"
|
|
79
|
+
* assumption was accidentally true in every test.
|
|
80
|
+
*/
|
|
81
|
+
managementZone?: 'internal' | 'secure-mgmt';
|
|
48
82
|
/**
|
|
49
83
|
* Observer vantages to inject into the topology. Each becomes an `observer-*`
|
|
50
84
|
* container — a passive spy carrying the probe tooling, placed at the named
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
$ORIGIN example.net.
|
|
2
|
-
$TTL 300
|
|
3
|
-
|
|
4
|
-
@ IN SOA ns1.example.net. admin.example.net. (
|
|
5
|
-
2024020108 300 60 604800 300
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
; Public DNS — RFC 1918 addresses NEVER appear here. The whole point of
|
|
9
|
-
; the e2e simulation is to model real internet connectivity, where
|
|
10
|
-
; private IPs are unreachable from outside. All public-facing names
|
|
11
|
-
; resolve to the firewall's external IP (100.100.0.100), which DNATs
|
|
12
|
-
; inbound to the right internal host.
|
|
13
|
-
@ IN NS ns1.example.net.
|
|
14
|
-
ns1 IN A 100.64.0.55
|
|
15
|
-
@ IN A 100.100.0.100
|
|
16
|
-
www IN A 100.100.0.100
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
$ORIGIN iamtheinternet.org.
|
|
2
|
-
$TTL 300
|
|
3
|
-
|
|
4
|
-
@ IN SOA ns1.iamtheinternet.org. admin.iamtheinternet.org. (
|
|
5
|
-
2024020247 300 60 604800 300
|
|
6
|
-
)
|
|
7
|
-
|
|
8
|
-
; Public DNS — RFC 1918 addresses NEVER appear here. The whole point of
|
|
9
|
-
; the e2e simulation is to model real internet connectivity, where
|
|
10
|
-
; private IPs are unreachable from outside. All public-facing names
|
|
11
|
-
; resolve to the firewall's external IP (100.100.0.100), which DNATs
|
|
12
|
-
; inbound to the right internal host.
|
|
13
|
-
@ IN NS ns1.iamtheinternet.org.
|
|
14
|
-
ns1 IN A 100.64.0.55
|
|
15
|
-
@ IN A 0.0.0.0
|
|
16
|
-
www IN A 100.100.0.100
|