@celilo/e2e 0.16.0 → 0.17.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/socks/startup.sh +7 -0
- package/package.json +3 -3
- package/src/container-manager.ts +9 -1
- package/src/socks-proxy.ts +31 -3
- package/src/types.ts +14 -0
package/config/socks/startup.sh
CHANGED
|
@@ -34,6 +34,13 @@ esac
|
|
|
34
34
|
ip route del default 2>/dev/null || true
|
|
35
35
|
ip route add default via "$GATEWAY"
|
|
36
36
|
|
|
37
|
+
# An explicit resolver from the caller wins over the vantage default. The proxy
|
|
38
|
+
# is what resolves names for a SOCKS5 client — a browser hands it the hostname
|
|
39
|
+
# and never resolves it itself — so a test driving a browser at a name only the
|
|
40
|
+
# fleet's own resolver knows has to say so here. Modelling a real device: one
|
|
41
|
+
# on the internal zone is handed the fleet's resolver, not a fixed stub.
|
|
42
|
+
NAMESERVER="${NAMESERVER_OVERRIDE:-$NAMESERVER}"
|
|
43
|
+
|
|
37
44
|
# Bypass docker's embedded resolver — point directly at the in-network
|
|
38
45
|
# DNS so split-horizon and the namecheap simulator both behave correctly.
|
|
39
46
|
echo "nameserver $NAMESERVER" > /etc/resolv.conf
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@celilo/e2e",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.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",
|
|
@@ -37,10 +37,10 @@
|
|
|
37
37
|
"README.md"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@celilo/capabilities": "^1.
|
|
40
|
+
"@celilo/capabilities": "^2.1.0",
|
|
41
41
|
"@celilo/cli-display": "^0.2.0",
|
|
42
42
|
"@celilo/event-bus": "^0.6.0",
|
|
43
|
-
"@celilo/terraform-fake": "^0.3.
|
|
43
|
+
"@celilo/terraform-fake": "^0.3.1",
|
|
44
44
|
"yaml": "^2.8.0",
|
|
45
45
|
"zod": "^3.24.1"
|
|
46
46
|
},
|
package/src/container-manager.ts
CHANGED
|
@@ -708,11 +708,19 @@ function buildNetworkHandle(
|
|
|
708
708
|
);
|
|
709
709
|
}
|
|
710
710
|
// Kill any prior responder (idempotent: replaces prior values map).
|
|
711
|
+
//
|
|
712
|
+
// Matched on "events respond", NOT "celilo events respond": inside the
|
|
713
|
+
// e2e management image `celilo` is a dev-mode shim that execs `bun run
|
|
714
|
+
// .../index.ts events respond ...`, so the literal word "celilo" never
|
|
715
|
+
// appears contiguous with "events respond" in the resulting process's
|
|
716
|
+
// argv — the old pattern silently matched nothing, so a second
|
|
717
|
+
// `respondWith()` call left the FIRST responder (and its stale values
|
|
718
|
+
// map) running alongside the new one instead of replacing it.
|
|
711
719
|
dockerExec(
|
|
712
720
|
projectName,
|
|
713
721
|
composeDir,
|
|
714
722
|
'management',
|
|
715
|
-
'pkill -f "
|
|
723
|
+
'pkill -f "events respond" 2>/dev/null || true',
|
|
716
724
|
5_000,
|
|
717
725
|
);
|
|
718
726
|
// Spawn detached. nohup + & + disown cleanly survives the
|
package/src/socks-proxy.ts
CHANGED
|
@@ -22,6 +22,19 @@ export interface SocksProxyOptions {
|
|
|
22
22
|
* zones via the firewall.
|
|
23
23
|
*/
|
|
24
24
|
vantage?: SocksProxyVantage;
|
|
25
|
+
/**
|
|
26
|
+
* Resolver the proxy should use instead of the vantage's baked default.
|
|
27
|
+
*
|
|
28
|
+
* The PROXY resolves names for a SOCKS5 client: chromium configured with
|
|
29
|
+
* `socks5://` sends the hostname and never resolves it itself. A test driving
|
|
30
|
+
* a browser at a name only the fleet's own resolver knows — anything on a
|
|
31
|
+
* private ingress — therefore has to point the proxy at that resolver.
|
|
32
|
+
*
|
|
33
|
+
* More faithful rather than less: the rig's baked stub answers a fixed
|
|
34
|
+
* split-horizon table, whereas a device on the internal zone is handed the
|
|
35
|
+
* fleet's resolver. Pass the deployed resolver's DNS-ingress address.
|
|
36
|
+
*/
|
|
37
|
+
nameserver?: string;
|
|
25
38
|
}
|
|
26
39
|
|
|
27
40
|
export interface SocksProxyHandle {
|
|
@@ -69,8 +82,22 @@ const VANTAGE_CONFIGS: Record<SocksProxyVantage, VantageConfig> = {
|
|
|
69
82
|
},
|
|
70
83
|
};
|
|
71
84
|
|
|
72
|
-
|
|
73
|
-
|
|
85
|
+
/**
|
|
86
|
+
* Deterministic per (project, vantage, resolver).
|
|
87
|
+
*
|
|
88
|
+
* The resolver is part of the identity because a proxy is REUSED by name: two
|
|
89
|
+
* calls differing only in `nameserver` would otherwise silently share one
|
|
90
|
+
* container, and the second would resolve through the first's resolver. That
|
|
91
|
+
* failure looks like a DNS bug in the fleet, which is the worst possible place
|
|
92
|
+
* for it to look like anything.
|
|
93
|
+
*/
|
|
94
|
+
function containerNameFor(
|
|
95
|
+
projectName: string,
|
|
96
|
+
vantage: SocksProxyVantage,
|
|
97
|
+
nameserver?: string,
|
|
98
|
+
): string {
|
|
99
|
+
const suffix = nameserver ? `-dns-${nameserver.replace(/\./g, '-')}` : '';
|
|
100
|
+
return `${projectName}-socks-${vantage}${suffix}`;
|
|
74
101
|
}
|
|
75
102
|
|
|
76
103
|
/**
|
|
@@ -85,7 +112,7 @@ export async function startSocksProxy(
|
|
|
85
112
|
const vantage = options.vantage ?? 'isp-external';
|
|
86
113
|
const cfg = VANTAGE_CONFIGS[vantage];
|
|
87
114
|
const networkName = `${projectName}_${cfg.network}`;
|
|
88
|
-
const containerName = containerNameFor(projectName, vantage);
|
|
115
|
+
const containerName = containerNameFor(projectName, vantage, options.nameserver);
|
|
89
116
|
|
|
90
117
|
// Reuse existing container if one is running for this project + vantage
|
|
91
118
|
const existing = inspectContainer(containerName);
|
|
@@ -113,6 +140,7 @@ export async function startSocksProxy(
|
|
|
113
140
|
`--ip ${cfg.ip}`,
|
|
114
141
|
'--cap-add NET_ADMIN',
|
|
115
142
|
`-e VANTAGE=${vantage}`,
|
|
143
|
+
...(options.nameserver ? [`-e NAMESERVER_OVERRIDE=${options.nameserver}`] : []),
|
|
116
144
|
'-p 127.0.0.1::1080',
|
|
117
145
|
PROXY_IMAGE,
|
|
118
146
|
].join(' '),
|
package/src/types.ts
CHANGED
|
@@ -182,6 +182,20 @@ export class CeliloCommandError extends Error {
|
|
|
182
182
|
*/
|
|
183
183
|
export interface ProxyOptions {
|
|
184
184
|
vantage?: 'isp-external' | 'internal';
|
|
185
|
+
/**
|
|
186
|
+
* Resolver the proxy should use, overriding the vantage's baked default.
|
|
187
|
+
*
|
|
188
|
+
* The proxy is what actually resolves names: a browser configured with
|
|
189
|
+
* `socks5://` hands the HOSTNAME to the proxy and never resolves it itself.
|
|
190
|
+
* So a test driving a browser at a name only the fleet's own resolver knows
|
|
191
|
+
* — anything on a private ingress — must point the proxy at that resolver.
|
|
192
|
+
*
|
|
193
|
+
* This is more faithful, not less: the rig's baked stub answers a fixed
|
|
194
|
+
* split-horizon table, whereas a real device on the internal zone is handed
|
|
195
|
+
* the fleet's resolver by DHCP. Pass the deployed resolver's DNS-ingress
|
|
196
|
+
* address here to model that.
|
|
197
|
+
*/
|
|
198
|
+
nameserver?: string;
|
|
185
199
|
}
|
|
186
200
|
|
|
187
201
|
export interface SocksProxyHandle {
|