@celilo/e2e 0.18.0 → 0.19.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.
|
@@ -24,9 +24,19 @@ iptables -P FORWARD ACCEPT
|
|
|
24
24
|
# DNS
|
|
25
25
|
echo "nameserver 203.0.113.1" > /etc/resolv.conf
|
|
26
26
|
|
|
27
|
-
# Start dnsmasq DHCP server on internal network
|
|
28
|
-
|
|
29
|
-
|
|
27
|
+
# Start dnsmasq DHCP server on internal network.
|
|
28
|
+
#
|
|
29
|
+
# Skippable, because celilo can serve DHCP itself (`modules/dnsmasq-dhcp`) and
|
|
30
|
+
# two DHCP servers on one broadcast domain race: whichever answers a DISCOVER
|
|
31
|
+
# first wins, and a test asserting which one served a lease would be asserting
|
|
32
|
+
# a coin toss. An operator moving DHCP to celilo turns the router's off, so a
|
|
33
|
+
# suite that tests celilo's DHCP models that by setting ROUTER_DHCP=off.
|
|
34
|
+
if [ "${ROUTER_DHCP:-on}" = "off" ]; then
|
|
35
|
+
echo "dnsmasq DHCP server NOT started (ROUTER_DHCP=off; celilo serves DHCP here)"
|
|
36
|
+
else
|
|
37
|
+
dnsmasq --conf-dir=/etc/dnsmasq.d --keep-in-foreground --log-facility=- &
|
|
38
|
+
echo "dnsmasq DHCP server started"
|
|
39
|
+
fi
|
|
30
40
|
|
|
31
41
|
# Start greenwave simulator
|
|
32
42
|
if [ -f /simulator/server.ts ]; then
|
|
@@ -35,6 +35,12 @@ RUN apt-get update && apt-get install -y \
|
|
|
35
35
|
procps \
|
|
36
36
|
zsh \
|
|
37
37
|
gnupg \
|
|
38
|
+
# The hook jail (openspec/changes/hook-process-boundary, stage 2) runs every
|
|
39
|
+
# hook under bubblewrap. Without it the management box runs hooks unjailed,
|
|
40
|
+
# which is a valid mode but not the one the e2e suite is there to exercise.
|
|
41
|
+
# The container needs security_opt relaxations to let it build a namespace —
|
|
42
|
+
# see the measured ladder in docker-compose-generator.ts.
|
|
43
|
+
bubblewrap \
|
|
38
44
|
&& rm -rf /var/lib/apt/lists/*
|
|
39
45
|
|
|
40
46
|
# --- Terraform, plus an OFFLINE provider mirror -------------------------------
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@celilo/e2e",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.19.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,7 +37,7 @@
|
|
|
37
37
|
"README.md"
|
|
38
38
|
],
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@celilo/capabilities": "^3.
|
|
40
|
+
"@celilo/capabilities": "^3.1.0",
|
|
41
41
|
"@celilo/cli-display": "^0.2.0",
|
|
42
42
|
"@celilo/event-bus": "^0.6.0",
|
|
43
43
|
"@celilo/terraform-fake": "^0.3.1",
|
package/src/container-manager.ts
CHANGED
|
@@ -1264,8 +1264,14 @@ export async function startNetwork(config: NetworkConfig): Promise<NetworkHandle
|
|
|
1264
1264
|
);
|
|
1265
1265
|
}
|
|
1266
1266
|
|
|
1267
|
-
// Wait for DHCP client lease
|
|
1268
|
-
|
|
1267
|
+
// Wait for DHCP client lease.
|
|
1268
|
+
//
|
|
1269
|
+
// Skipped when the router's DHCP is off, because then NOTHING is serving yet:
|
|
1270
|
+
// celilo's own DHCP server is a module, and modules deploy long after the
|
|
1271
|
+
// network is up. Waiting here would time out at 60s on every such suite and
|
|
1272
|
+
// report it as a network-start failure. Those suites drive the client
|
|
1273
|
+
// themselves once their server is deployed.
|
|
1274
|
+
if (config.dhcpClient && config.routerDhcp !== false) {
|
|
1269
1275
|
console.log('[progress:start] waiting for DHCP client lease | DHCP lease acquired');
|
|
1270
1276
|
// Self-diagnosing via waitFor's onTimeout (e2e-confidence #255): a DHCP-lease
|
|
1271
1277
|
// timeout is an intermittent in-suite flake (passes solo). On timeout, dump
|
|
@@ -94,6 +94,12 @@ function baseService(opts: {
|
|
|
94
94
|
environment?: Record<string, string>;
|
|
95
95
|
tmpfs?: string[];
|
|
96
96
|
privileged?: boolean;
|
|
97
|
+
/**
|
|
98
|
+
* Docker `security_opt` entries, e.g. `seccomp=unconfined`. Needed by the
|
|
99
|
+
* management box so the hook jail's bubblewrap can build a namespace inside
|
|
100
|
+
* a container — see the measured ladder at its call site.
|
|
101
|
+
*/
|
|
102
|
+
security_opt?: string[];
|
|
97
103
|
dns?: string[];
|
|
98
104
|
/** Host devices to expose, e.g. `/dev/net/tun` for a userspace WireGuard tunnel. */
|
|
99
105
|
devices?: string[];
|
|
@@ -215,7 +221,13 @@ function defaultTopologyServices(config: NetworkConfig): Record<string, unknown>
|
|
|
215
221
|
volumes: ['ssh-keys:/ssh-keys:ro'],
|
|
216
222
|
// Which real ISP router this sim stands in for. The protocol is identical
|
|
217
223
|
// across the two; only the TR-181 vendor extension prefix differs.
|
|
218
|
-
environment: {
|
|
224
|
+
environment: {
|
|
225
|
+
ROUTER_VENDOR_PREFIX: config.routerVendorPrefix ?? 'X_GWS_',
|
|
226
|
+
// The simulated router serves DHCP on `internal` by default, which is
|
|
227
|
+
// what an operator's router does. A suite testing celilo's OWN DHCP
|
|
228
|
+
// turns it off, because two servers on one broadcast domain race.
|
|
229
|
+
ROUTER_DHCP: config.routerDhcp === false ? 'off' : 'on',
|
|
230
|
+
},
|
|
219
231
|
}),
|
|
220
232
|
};
|
|
221
233
|
}
|
|
@@ -568,7 +580,34 @@ export function generateTestComposeYaml(config: NetworkConfig, celiloRoot?: stri
|
|
|
568
580
|
image:
|
|
569
581
|
variant === 'vanilla' ? 'celilo-e2e/management:vanilla' : 'celilo-e2e/management:latest',
|
|
570
582
|
networks: { [zone]: { ipv4_address: ip } },
|
|
571
|
-
|
|
583
|
+
// SYS_ADMIN is for the hook jail, NET_ADMIN for the routing the box does
|
|
584
|
+
// anyway. See the security_opt block below for why both are here.
|
|
585
|
+
cap_add: ['NET_ADMIN', 'SYS_ADMIN'],
|
|
586
|
+
// The hook jail runs each hook under bubblewrap, which has to build a
|
|
587
|
+
// user namespace and then mount inside it. Docker denies that four
|
|
588
|
+
// separate ways, and every one of these is load-bearing — measured on a
|
|
589
|
+
// colima Ubuntu 24.04.1 VM (kernel 6.8.0-50,
|
|
590
|
+
// kernel.apparmor_restrict_unprivileged_userns=1), by removing one at a
|
|
591
|
+
// time from the working set:
|
|
592
|
+
//
|
|
593
|
+
// drop seccomp=unconfined -> bwrap: pivot_root: Operation not permitted
|
|
594
|
+
// drop apparmor=unconfined -> bwrap: Failed to make / slave: Permission denied
|
|
595
|
+
// drop systempaths=unconfined -> bwrap: Can't mount proc on /newroot/proc
|
|
596
|
+
// drop SYS_ADMIN -> bwrap: setting up uid map: Permission denied
|
|
597
|
+
//
|
|
598
|
+
// Deliberately NOT `privileged: true`, which design D8 measured as
|
|
599
|
+
// working and task 4.1 asked to improve on. It would also grant every
|
|
600
|
+
// capability and every host device; this set grants four named things.
|
|
601
|
+
//
|
|
602
|
+
// `systempaths=unconfined` is the one D8's ladder was missing: it unmasks
|
|
603
|
+
// the /proc paths Docker hides, which is why "all three" of the earlier
|
|
604
|
+
// options still failed on the proc mount.
|
|
605
|
+
//
|
|
606
|
+
// NOTE this makes the container a WEAK place to test the AppArmor
|
|
607
|
+
// profile: apparmor=unconfined means the restriction the profile exists
|
|
608
|
+
// to satisfy is not in force here. That gate is the celilo-builder probe
|
|
609
|
+
// on a real kernel, never this container.
|
|
610
|
+
security_opt: ['seccomp=unconfined', 'apparmor=unconfined', 'systempaths=unconfined'],
|
|
572
611
|
// ISS-0157: `module import`'s `bun install` hard-links packages from the
|
|
573
612
|
// bun cache into node_modules, which on overlayfs forces a copy-up + fsync
|
|
574
613
|
// per file. On a slow/contended builder disk that storm blows past the
|
package/src/network-builder.ts
CHANGED
|
@@ -140,6 +140,23 @@ export class NetworkBuilder {
|
|
|
140
140
|
return this;
|
|
141
141
|
}
|
|
142
142
|
|
|
143
|
+
/**
|
|
144
|
+
* Stop the simulated ISP router serving DHCP on `internal`.
|
|
145
|
+
*
|
|
146
|
+
* For suites where CELILO serves DHCP (`modules/dnsmasq-dhcp`). Two servers
|
|
147
|
+
* on one broadcast domain race, so without this a lease assertion is a coin
|
|
148
|
+
* toss. It is also what an operator does when moving DHCP to celilo, so the
|
|
149
|
+
* suite models the migration rather than dodging a conflict.
|
|
150
|
+
*
|
|
151
|
+
* NOTE: `withDhcpClient()`'s start-up lease wait expects SOMETHING to answer.
|
|
152
|
+
* Pair this with a suite that deploys celilo's DHCP server, or the client
|
|
153
|
+
* gets no lease and the network never comes up.
|
|
154
|
+
*/
|
|
155
|
+
withoutRouterDhcp(): this {
|
|
156
|
+
this.config.routerDhcp = false;
|
|
157
|
+
return this;
|
|
158
|
+
}
|
|
159
|
+
|
|
143
160
|
/**
|
|
144
161
|
* Add the Proxmox API simulator on `secure-mgmt`.
|
|
145
162
|
*
|
package/src/types.ts
CHANGED
|
@@ -66,6 +66,19 @@ export interface NetworkConfig {
|
|
|
66
66
|
* serves both rather than a near-duplicate second one.
|
|
67
67
|
*/
|
|
68
68
|
routerVendorPrefix?: string;
|
|
69
|
+
/**
|
|
70
|
+
* Whether the simulated ISP router serves DHCP on `internal`. Defaults to
|
|
71
|
+
* true, which is what an operator's router does and what every existing suite
|
|
72
|
+
* relies on.
|
|
73
|
+
*
|
|
74
|
+
* Set false when celilo serves DHCP instead (`modules/dnsmasq-dhcp`). Two
|
|
75
|
+
* DHCP servers on one broadcast domain race — whichever answers a DISCOVER
|
|
76
|
+
* first wins — so a suite asserting WHICH server issued a lease would be
|
|
77
|
+
* asserting a coin toss. Turning the router's off is also what a real
|
|
78
|
+
* operator does when moving DHCP to celilo, so this models the migration
|
|
79
|
+
* rather than papering over a conflict.
|
|
80
|
+
*/
|
|
81
|
+
routerDhcp?: boolean;
|
|
69
82
|
/** Extra volume mounts for the management container (host:container format) */
|
|
70
83
|
managementVolumes: string[];
|
|
71
84
|
/** Include a DHCP client container on the internal network */
|