vmsan 0.1.0-alpha.2 → 0.1.0-alpha.21

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.
@@ -1,1064 +0,0 @@
1
- import { a as noKernelDirError, d as socketTimeoutError, i as noExt4RootfsError, o as noKernelError, p as defaultInterfaceNotFoundError, r as missingBinaryError, s as noRootfsDirError, y as snapshotNotFoundError } from "./errors.mjs";
2
- import { join } from "node:path";
3
- import { execFileSync } from "node:child_process";
4
- import { existsSync, readFileSync, readdirSync } from "node:fs";
5
- import { connect } from "node:net";
6
- const DOH_RESOLVER_IPS = [
7
- "8.8.8.8",
8
- "8.8.4.4",
9
- "1.1.1.1",
10
- "1.0.0.1",
11
- "9.9.9.9",
12
- "149.112.112.112",
13
- "208.67.222.222",
14
- "208.67.220.220",
15
- "185.228.168.168",
16
- "185.228.169.168"
17
- ];
18
- function runArgs(bin, args) {
19
- execFileSync(bin, args, { stdio: "pipe" });
20
- }
21
- function sudo(args) {
22
- runArgs("sudo", args);
23
- }
24
- function sudoNetns(nsName, args) {
25
- sudo([
26
- "ip",
27
- "netns",
28
- "exec",
29
- nsName,
30
- ...args
31
- ]);
32
- }
33
- function getDefaultInterface() {
34
- const match = execFileSync("ip", [
35
- "route",
36
- "show",
37
- "default"
38
- ], {
39
- encoding: "utf-8",
40
- stdio: "pipe"
41
- }).trim().match(/dev\s+(\S+)/);
42
- if (!match) throw defaultInterfaceNotFoundError();
43
- return match[1];
44
- }
45
- /**
46
- * Detect effective policy mode:
47
- * - "deny-all": explicit deny-all, no outbound
48
- * - "custom": any of allowedDomains/allowedCidrs/deniedCidrs present
49
- * - "allow-all": default, unrestricted
50
- */
51
- function effectivePolicy(config) {
52
- if (config.networkPolicy === "deny-all") return "deny-all";
53
- if (config.allowedDomains.length > 0 || config.allowedCidrs.length > 0 || config.deniedCidrs.length > 0) return "custom";
54
- return "allow-all";
55
- }
56
- var NetworkManager = class NetworkManager {
57
- config;
58
- constructor(slot, networkPolicy, allowedDomains, allowedCidrs, deniedCidrs, publishedPorts, bandwidthMbit, netnsName) {
59
- this.config = {
60
- slot,
61
- tapDevice: `fhvm${slot}`,
62
- hostIp: `172.16.${slot}.1`,
63
- guestIp: `172.16.${slot}.2`,
64
- subnetMask: "255.255.255.252",
65
- macAddress: `AA:FC:00:00:00:${(slot + 1).toString(16).padStart(2, "0").toUpperCase()}`,
66
- networkPolicy,
67
- allowedDomains,
68
- allowedCidrs,
69
- deniedCidrs,
70
- publishedPorts,
71
- bandwidthMbit,
72
- netnsName
73
- };
74
- }
75
- static bootArgs(slot) {
76
- const hostIp = `172.16.${slot}.1`;
77
- return `console=ttyS0 reboot=k panic=1 pci=off ip=172.16.${slot}.2::${hostIp}:255.255.255.252::eth0:off:${hostIp}`;
78
- }
79
- static fromConfig(config) {
80
- const mgr = Object.create(NetworkManager.prototype);
81
- mgr.config = config;
82
- return mgr;
83
- }
84
- static fromVmNetwork(network) {
85
- const slot = Number(network.hostIp.split(".")[2]);
86
- if (!Number.isInteger(slot)) throw new Error(`invalid network slot derived from hostIp: ${network.hostIp}`);
87
- return NetworkManager.fromConfig({
88
- slot,
89
- tapDevice: network.tapDevice,
90
- hostIp: network.hostIp,
91
- guestIp: network.guestIp,
92
- subnetMask: network.subnetMask,
93
- macAddress: network.macAddress,
94
- networkPolicy: network.networkPolicy,
95
- allowedDomains: network.allowedDomains,
96
- allowedCidrs: network.allowedCidrs || [],
97
- deniedCidrs: network.deniedCidrs || [],
98
- publishedPorts: network.publishedPorts,
99
- bandwidthMbit: network.bandwidthMbit,
100
- netnsName: network.netnsName
101
- });
102
- }
103
- nsRun(args) {
104
- const { netnsName } = this.config;
105
- if (netnsName) sudoNetns(netnsName, args);
106
- else sudo(args);
107
- }
108
- setupNamespace() {
109
- const { slot, netnsName } = this.config;
110
- if (!netnsName) return;
111
- const vethHost = `veth-h-${slot}`;
112
- const vethGuest = `veth-g-${slot}`;
113
- const transitHostIp = `10.200.${slot}.1`;
114
- const transitGuestIp = `10.200.${slot}.2`;
115
- sudo([
116
- "ip",
117
- "netns",
118
- "add",
119
- netnsName
120
- ]);
121
- sudo([
122
- "ip",
123
- "link",
124
- "add",
125
- vethHost,
126
- "type",
127
- "veth",
128
- "peer",
129
- "name",
130
- vethGuest
131
- ]);
132
- sudo([
133
- "ip",
134
- "link",
135
- "set",
136
- vethGuest,
137
- "netns",
138
- netnsName
139
- ]);
140
- sudo([
141
- "ip",
142
- "addr",
143
- "add",
144
- `${transitHostIp}/30`,
145
- "dev",
146
- vethHost
147
- ]);
148
- sudo([
149
- "ip",
150
- "link",
151
- "set",
152
- vethHost,
153
- "up"
154
- ]);
155
- sudoNetns(netnsName, [
156
- "ip",
157
- "addr",
158
- "add",
159
- `${transitGuestIp}/30`,
160
- "dev",
161
- vethGuest
162
- ]);
163
- sudoNetns(netnsName, [
164
- "ip",
165
- "link",
166
- "set",
167
- vethGuest,
168
- "up"
169
- ]);
170
- sudoNetns(netnsName, [
171
- "ip",
172
- "link",
173
- "set",
174
- "lo",
175
- "up"
176
- ]);
177
- sudoNetns(netnsName, [
178
- "ip",
179
- "route",
180
- "add",
181
- "default",
182
- "via",
183
- transitHostIp
184
- ]);
185
- sudoNetns(netnsName, [
186
- "sysctl",
187
- "-w",
188
- "net.ipv4.ip_forward=1"
189
- ]);
190
- sudo([
191
- "ip",
192
- "route",
193
- "add",
194
- `172.16.${slot}.0/30`,
195
- "via",
196
- transitGuestIp
197
- ]);
198
- sudo([
199
- "sysctl",
200
- "-w",
201
- "net.ipv4.ip_forward=1"
202
- ]);
203
- }
204
- teardownNamespace() {
205
- const { slot, netnsName } = this.config;
206
- if (!netnsName) return;
207
- const tryRun = (args) => {
208
- try {
209
- sudo(args);
210
- } catch {}
211
- };
212
- tryRun([
213
- "ip",
214
- "route",
215
- "del",
216
- `172.16.${slot}.0/30`
217
- ]);
218
- tryRun([
219
- "ip",
220
- "netns",
221
- "delete",
222
- netnsName
223
- ]);
224
- }
225
- setupDevice() {
226
- const { tapDevice, hostIp, netnsName } = this.config;
227
- if (!netnsName) {
228
- if (existsSync(`/sys/class/net/${tapDevice}`)) try {
229
- sudo([
230
- "ip",
231
- "link",
232
- "delete",
233
- tapDevice
234
- ]);
235
- } catch {}
236
- sudo([
237
- "ip",
238
- "tuntap",
239
- "add",
240
- "dev",
241
- tapDevice,
242
- "mode",
243
- "tap"
244
- ]);
245
- sudo([
246
- "ip",
247
- "addr",
248
- "add",
249
- `${hostIp}/30`,
250
- "dev",
251
- tapDevice
252
- ]);
253
- sudo([
254
- "ip",
255
- "link",
256
- "set",
257
- tapDevice,
258
- "up"
259
- ]);
260
- sudo([
261
- "sysctl",
262
- "-w",
263
- "net.ipv4.ip_forward=1"
264
- ]);
265
- } else {
266
- sudoNetns(netnsName, [
267
- "ip",
268
- "tuntap",
269
- "add",
270
- "dev",
271
- tapDevice,
272
- "mode",
273
- "tap"
274
- ]);
275
- sudoNetns(netnsName, [
276
- "ip",
277
- "addr",
278
- "add",
279
- `${hostIp}/30`,
280
- "dev",
281
- tapDevice
282
- ]);
283
- sudoNetns(netnsName, [
284
- "ip",
285
- "link",
286
- "set",
287
- tapDevice,
288
- "up"
289
- ]);
290
- }
291
- }
292
- setupRules() {
293
- const { tapDevice, hostIp, guestIp, publishedPorts } = this.config;
294
- const policy = effectivePolicy(this.config);
295
- const fwd = this.nsRun.bind(this);
296
- if (policy === "deny-all") {
297
- fwd([
298
- "iptables",
299
- "-I",
300
- "FORWARD",
301
- "-i",
302
- tapDevice,
303
- "-j",
304
- "DROP"
305
- ]);
306
- fwd([
307
- "iptables",
308
- "-I",
309
- "FORWARD",
310
- "-o",
311
- tapDevice,
312
- "-j",
313
- "DROP"
314
- ]);
315
- return;
316
- }
317
- const defaultIface = getDefaultInterface();
318
- sudo([
319
- "iptables",
320
- "-t",
321
- "nat",
322
- "-A",
323
- "POSTROUTING",
324
- "-s",
325
- `${guestIp}/30`,
326
- "-o",
327
- defaultIface,
328
- "-j",
329
- "MASQUERADE"
330
- ]);
331
- if (policy === "custom") {
332
- for (const cidr of this.config.deniedCidrs) fwd([
333
- "iptables",
334
- "-A",
335
- "FORWARD",
336
- "-i",
337
- tapDevice,
338
- "-d",
339
- cidr,
340
- "-j",
341
- "DROP"
342
- ]);
343
- fwd([
344
- "iptables",
345
- "-A",
346
- "FORWARD",
347
- "-i",
348
- tapDevice,
349
- "-d",
350
- hostIp,
351
- "-p",
352
- "udp",
353
- "--dport",
354
- "53",
355
- "-j",
356
- "ACCEPT"
357
- ]);
358
- fwd([
359
- "iptables",
360
- "-A",
361
- "FORWARD",
362
- "-i",
363
- tapDevice,
364
- "-d",
365
- hostIp,
366
- "-p",
367
- "tcp",
368
- "--dport",
369
- "53",
370
- "-j",
371
- "ACCEPT"
372
- ]);
373
- fwd([
374
- "iptables",
375
- "-A",
376
- "FORWARD",
377
- "-i",
378
- tapDevice,
379
- "-p",
380
- "udp",
381
- "--dport",
382
- "53",
383
- "-j",
384
- "DROP"
385
- ]);
386
- fwd([
387
- "iptables",
388
- "-A",
389
- "FORWARD",
390
- "-i",
391
- tapDevice,
392
- "-p",
393
- "tcp",
394
- "--dport",
395
- "53",
396
- "-j",
397
- "DROP"
398
- ]);
399
- fwd([
400
- "iptables",
401
- "-A",
402
- "FORWARD",
403
- "-i",
404
- tapDevice,
405
- "-p",
406
- "udp",
407
- "--dport",
408
- "853",
409
- "-j",
410
- "DROP"
411
- ]);
412
- fwd([
413
- "iptables",
414
- "-A",
415
- "FORWARD",
416
- "-i",
417
- tapDevice,
418
- "-p",
419
- "tcp",
420
- "--dport",
421
- "853",
422
- "-j",
423
- "DROP"
424
- ]);
425
- for (const ip of DOH_RESOLVER_IPS) {
426
- fwd([
427
- "iptables",
428
- "-A",
429
- "FORWARD",
430
- "-i",
431
- tapDevice,
432
- "-d",
433
- ip,
434
- "-p",
435
- "tcp",
436
- "--dport",
437
- "443",
438
- "-j",
439
- "DROP"
440
- ]);
441
- fwd([
442
- "iptables",
443
- "-A",
444
- "FORWARD",
445
- "-i",
446
- tapDevice,
447
- "-d",
448
- ip,
449
- "-p",
450
- "udp",
451
- "--dport",
452
- "443",
453
- "-j",
454
- "DROP"
455
- ]);
456
- }
457
- fwd([
458
- "iptables",
459
- "-A",
460
- "FORWARD",
461
- "-i",
462
- tapDevice,
463
- "-d",
464
- "172.16.0.0/16",
465
- "-j",
466
- "DROP"
467
- ]);
468
- for (const cidr of this.config.allowedCidrs) fwd([
469
- "iptables",
470
- "-A",
471
- "FORWARD",
472
- "-i",
473
- tapDevice,
474
- "-d",
475
- cidr,
476
- "-j",
477
- "ACCEPT"
478
- ]);
479
- fwd([
480
- "iptables",
481
- "-A",
482
- "FORWARD",
483
- "-i",
484
- tapDevice,
485
- "-j",
486
- "ACCEPT"
487
- ]);
488
- } else {
489
- fwd([
490
- "iptables",
491
- "-A",
492
- "FORWARD",
493
- "-i",
494
- tapDevice,
495
- "-d",
496
- hostIp,
497
- "-p",
498
- "udp",
499
- "--dport",
500
- "53",
501
- "-j",
502
- "ACCEPT"
503
- ]);
504
- fwd([
505
- "iptables",
506
- "-A",
507
- "FORWARD",
508
- "-i",
509
- tapDevice,
510
- "-d",
511
- hostIp,
512
- "-p",
513
- "tcp",
514
- "--dport",
515
- "53",
516
- "-j",
517
- "ACCEPT"
518
- ]);
519
- fwd([
520
- "iptables",
521
- "-A",
522
- "FORWARD",
523
- "-i",
524
- tapDevice,
525
- "-p",
526
- "udp",
527
- "--dport",
528
- "53",
529
- "-j",
530
- "DROP"
531
- ]);
532
- fwd([
533
- "iptables",
534
- "-A",
535
- "FORWARD",
536
- "-i",
537
- tapDevice,
538
- "-p",
539
- "tcp",
540
- "--dport",
541
- "53",
542
- "-j",
543
- "DROP"
544
- ]);
545
- fwd([
546
- "iptables",
547
- "-A",
548
- "FORWARD",
549
- "-i",
550
- tapDevice,
551
- "-p",
552
- "udp",
553
- "--dport",
554
- "853",
555
- "-j",
556
- "DROP"
557
- ]);
558
- fwd([
559
- "iptables",
560
- "-A",
561
- "FORWARD",
562
- "-i",
563
- tapDevice,
564
- "-p",
565
- "tcp",
566
- "--dport",
567
- "853",
568
- "-j",
569
- "DROP"
570
- ]);
571
- for (const ip of DOH_RESOLVER_IPS) {
572
- fwd([
573
- "iptables",
574
- "-A",
575
- "FORWARD",
576
- "-i",
577
- tapDevice,
578
- "-d",
579
- ip,
580
- "-p",
581
- "tcp",
582
- "--dport",
583
- "443",
584
- "-j",
585
- "DROP"
586
- ]);
587
- fwd([
588
- "iptables",
589
- "-A",
590
- "FORWARD",
591
- "-i",
592
- tapDevice,
593
- "-d",
594
- ip,
595
- "-p",
596
- "udp",
597
- "--dport",
598
- "443",
599
- "-j",
600
- "DROP"
601
- ]);
602
- }
603
- fwd([
604
- "iptables",
605
- "-A",
606
- "FORWARD",
607
- "-i",
608
- tapDevice,
609
- "-d",
610
- "172.16.0.0/16",
611
- "-j",
612
- "DROP"
613
- ]);
614
- fwd([
615
- "iptables",
616
- "-A",
617
- "FORWARD",
618
- "-i",
619
- tapDevice,
620
- "-j",
621
- "ACCEPT"
622
- ]);
623
- }
624
- fwd([
625
- "iptables",
626
- "-A",
627
- "FORWARD",
628
- "-o",
629
- tapDevice,
630
- "-m",
631
- "state",
632
- "--state",
633
- "RELATED,ESTABLISHED",
634
- "-j",
635
- "ACCEPT"
636
- ]);
637
- for (const port of publishedPorts) {
638
- const portStr = String(port);
639
- sudo([
640
- "iptables",
641
- "-t",
642
- "nat",
643
- "-A",
644
- "PREROUTING",
645
- "-i",
646
- defaultIface,
647
- "-p",
648
- "tcp",
649
- "--dport",
650
- portStr,
651
- "-j",
652
- "DNAT",
653
- "--to-destination",
654
- `${guestIp}:${portStr}`
655
- ]);
656
- sudo([
657
- "iptables",
658
- "-A",
659
- "FORWARD",
660
- "-p",
661
- "tcp",
662
- "-d",
663
- guestIp,
664
- "--dport",
665
- portStr,
666
- "-j",
667
- "ACCEPT"
668
- ]);
669
- }
670
- }
671
- setupThrottle() {
672
- const { tapDevice, bandwidthMbit } = this.config;
673
- if (bandwidthMbit === void 0) return;
674
- const rateKbit = bandwidthMbit * 1e3;
675
- const burstKb = Math.max(32, Math.floor(rateKbit / 8));
676
- this.nsRun([
677
- "tc",
678
- "qdisc",
679
- "add",
680
- "dev",
681
- tapDevice,
682
- "root",
683
- "tbf",
684
- "rate",
685
- `${bandwidthMbit}mbit`,
686
- "burst",
687
- `${burstKb}kb`,
688
- "latency",
689
- "400ms"
690
- ]);
691
- }
692
- teardownThrottle() {
693
- const { tapDevice } = this.config;
694
- try {
695
- this.nsRun([
696
- "tc",
697
- "qdisc",
698
- "del",
699
- "dev",
700
- tapDevice,
701
- "root"
702
- ]);
703
- } catch {}
704
- }
705
- teardownRules() {
706
- const { tapDevice, hostIp, guestIp, publishedPorts, netnsName } = this.config;
707
- let defaultIface;
708
- try {
709
- defaultIface = getDefaultInterface();
710
- } catch {}
711
- const tryRun = (args) => {
712
- try {
713
- sudo(args);
714
- } catch {}
715
- };
716
- const tryFwd = (args) => {
717
- try {
718
- this.nsRun(args);
719
- } catch {}
720
- };
721
- for (const port of publishedPorts) {
722
- const portStr = String(port);
723
- if (defaultIface) tryRun([
724
- "iptables",
725
- "-t",
726
- "nat",
727
- "-D",
728
- "PREROUTING",
729
- "-i",
730
- defaultIface,
731
- "-p",
732
- "tcp",
733
- "--dport",
734
- portStr,
735
- "-j",
736
- "DNAT",
737
- "--to-destination",
738
- `${guestIp}:${portStr}`
739
- ]);
740
- tryRun([
741
- "iptables",
742
- "-D",
743
- "FORWARD",
744
- "-p",
745
- "tcp",
746
- "-d",
747
- guestIp,
748
- "--dport",
749
- portStr,
750
- "-j",
751
- "ACCEPT"
752
- ]);
753
- }
754
- if (!netnsName) {
755
- for (const cidr of this.config.deniedCidrs) tryFwd([
756
- "iptables",
757
- "-D",
758
- "FORWARD",
759
- "-i",
760
- tapDevice,
761
- "-d",
762
- cidr,
763
- "-j",
764
- "DROP"
765
- ]);
766
- for (const cidr of this.config.allowedCidrs) tryFwd([
767
- "iptables",
768
- "-D",
769
- "FORWARD",
770
- "-i",
771
- tapDevice,
772
- "-d",
773
- cidr,
774
- "-j",
775
- "ACCEPT"
776
- ]);
777
- tryFwd([
778
- "iptables",
779
- "-D",
780
- "FORWARD",
781
- "-i",
782
- tapDevice,
783
- "-d",
784
- hostIp,
785
- "-p",
786
- "udp",
787
- "--dport",
788
- "53",
789
- "-j",
790
- "ACCEPT"
791
- ]);
792
- tryFwd([
793
- "iptables",
794
- "-D",
795
- "FORWARD",
796
- "-i",
797
- tapDevice,
798
- "-d",
799
- hostIp,
800
- "-p",
801
- "tcp",
802
- "--dport",
803
- "53",
804
- "-j",
805
- "ACCEPT"
806
- ]);
807
- tryFwd([
808
- "iptables",
809
- "-D",
810
- "FORWARD",
811
- "-i",
812
- tapDevice,
813
- "-p",
814
- "udp",
815
- "--dport",
816
- "53",
817
- "-j",
818
- "DROP"
819
- ]);
820
- tryFwd([
821
- "iptables",
822
- "-D",
823
- "FORWARD",
824
- "-i",
825
- tapDevice,
826
- "-p",
827
- "tcp",
828
- "--dport",
829
- "53",
830
- "-j",
831
- "DROP"
832
- ]);
833
- tryFwd([
834
- "iptables",
835
- "-D",
836
- "FORWARD",
837
- "-i",
838
- tapDevice,
839
- "-p",
840
- "udp",
841
- "--dport",
842
- "853",
843
- "-j",
844
- "DROP"
845
- ]);
846
- tryFwd([
847
- "iptables",
848
- "-D",
849
- "FORWARD",
850
- "-i",
851
- tapDevice,
852
- "-p",
853
- "tcp",
854
- "--dport",
855
- "853",
856
- "-j",
857
- "DROP"
858
- ]);
859
- for (const ip of DOH_RESOLVER_IPS) {
860
- tryFwd([
861
- "iptables",
862
- "-D",
863
- "FORWARD",
864
- "-i",
865
- tapDevice,
866
- "-d",
867
- ip,
868
- "-p",
869
- "tcp",
870
- "--dport",
871
- "443",
872
- "-j",
873
- "DROP"
874
- ]);
875
- tryFwd([
876
- "iptables",
877
- "-D",
878
- "FORWARD",
879
- "-i",
880
- tapDevice,
881
- "-d",
882
- ip,
883
- "-p",
884
- "udp",
885
- "--dport",
886
- "443",
887
- "-j",
888
- "DROP"
889
- ]);
890
- }
891
- tryFwd([
892
- "iptables",
893
- "-D",
894
- "FORWARD",
895
- "-i",
896
- tapDevice,
897
- "-d",
898
- "172.16.0.0/16",
899
- "-j",
900
- "DROP"
901
- ]);
902
- tryFwd([
903
- "iptables",
904
- "-D",
905
- "FORWARD",
906
- "-i",
907
- tapDevice,
908
- "-j",
909
- "ACCEPT"
910
- ]);
911
- tryFwd([
912
- "iptables",
913
- "-D",
914
- "FORWARD",
915
- "-o",
916
- tapDevice,
917
- "-m",
918
- "state",
919
- "--state",
920
- "RELATED,ESTABLISHED",
921
- "-j",
922
- "ACCEPT"
923
- ]);
924
- tryFwd([
925
- "iptables",
926
- "-D",
927
- "FORWARD",
928
- "-i",
929
- tapDevice,
930
- "-j",
931
- "DROP"
932
- ]);
933
- tryFwd([
934
- "iptables",
935
- "-D",
936
- "FORWARD",
937
- "-o",
938
- tapDevice,
939
- "-j",
940
- "DROP"
941
- ]);
942
- }
943
- if (defaultIface) tryRun([
944
- "iptables",
945
- "-t",
946
- "nat",
947
- "-D",
948
- "POSTROUTING",
949
- "-s",
950
- `${guestIp}/30`,
951
- "-o",
952
- defaultIface,
953
- "-j",
954
- "MASQUERADE"
955
- ]);
956
- }
957
- teardownDevice() {
958
- const { tapDevice, netnsName } = this.config;
959
- if (netnsName) return;
960
- try {
961
- sudo([
962
- "ip",
963
- "link",
964
- "delete",
965
- tapDevice
966
- ]);
967
- } catch {}
968
- }
969
- async setup() {
970
- this.setupNamespace();
971
- this.setupDevice();
972
- this.setupRules();
973
- this.setupThrottle();
974
- }
975
- teardown() {
976
- if (this.config.netnsName) {
977
- this.teardownRules();
978
- this.teardownNamespace();
979
- } else {
980
- this.teardownThrottle();
981
- this.teardownRules();
982
- this.teardownDevice();
983
- }
984
- }
985
- updatePolicy(newPolicy, newDomains, newAllowedCidrs, newDeniedCidrs) {
986
- const oldConfig = { ...this.config };
987
- this.teardownRules();
988
- this.config.networkPolicy = newPolicy;
989
- this.config.allowedDomains = newDomains;
990
- this.config.allowedCidrs = newAllowedCidrs;
991
- this.config.deniedCidrs = newDeniedCidrs;
992
- try {
993
- this.setupRules();
994
- } catch (err) {
995
- this.config = oldConfig;
996
- try {
997
- this.setupRules();
998
- } catch {}
999
- throw err;
1000
- }
1001
- }
1002
- };
1003
- function validateEnvironment(baseDir) {
1004
- const firecrackerPath = join(baseDir, "bin", "firecracker");
1005
- const jailerPath = join(baseDir, "bin", "jailer");
1006
- if (!existsSync(firecrackerPath)) throw missingBinaryError("Firecracker", firecrackerPath);
1007
- if (!existsSync(jailerPath)) throw missingBinaryError("Jailer", jailerPath);
1008
- }
1009
- function findKernel(baseDir) {
1010
- const kernelDir = join(baseDir, "kernels");
1011
- if (!existsSync(kernelDir)) throw noKernelDirError();
1012
- const files = readdirSync(kernelDir).filter((fileName) => fileName.startsWith("vmlinux"));
1013
- if (files.length === 0) throw noKernelError();
1014
- return join(kernelDir, files.sort().at(-1));
1015
- }
1016
- function findRootfs(baseDir) {
1017
- const rootfsDir = join(baseDir, "rootfs");
1018
- if (!existsSync(rootfsDir)) throw noRootfsDirError();
1019
- const files = readdirSync(rootfsDir).filter((fileName) => fileName.endsWith(".ext4"));
1020
- if (files.length === 0) throw noExt4RootfsError();
1021
- return join(rootfsDir, files.sort().at(-1));
1022
- }
1023
- async function waitForSocket(socketPath, timeoutMs = 5e3) {
1024
- const start = Date.now();
1025
- while (Date.now() - start < timeoutMs) {
1026
- if (existsSync(socketPath)) {
1027
- if (await new Promise((resolve) => {
1028
- const socket = connect(socketPath);
1029
- socket.on("connect", () => {
1030
- socket.destroy();
1031
- resolve(true);
1032
- });
1033
- socket.on("error", () => resolve(false));
1034
- })) return;
1035
- }
1036
- await new Promise((resolve) => setTimeout(resolve, 100));
1037
- }
1038
- throw socketTimeoutError(socketPath);
1039
- }
1040
- function getVmPid(vmId) {
1041
- try {
1042
- const entries = readdirSync("/proc").filter((entry) => /^\d+$/.test(entry));
1043
- for (const entry of entries) try {
1044
- const cmdline = readFileSync(`/proc/${entry}/cmdline`, "utf-8");
1045
- if (cmdline.includes("firecracker") && cmdline.includes(vmId)) return Number(entry);
1046
- } catch {}
1047
- } catch {}
1048
- return null;
1049
- }
1050
- function getVmJailerPid(vmId) {
1051
- try {
1052
- const entries = readdirSync("/proc").filter((entry) => /^\d+$/.test(entry));
1053
- for (const entry of entries) try {
1054
- const cmdline = readFileSync(`/proc/${entry}/cmdline`, "utf-8");
1055
- if (cmdline.includes("jailer") && cmdline.includes(vmId)) return Number(entry);
1056
- } catch {}
1057
- } catch {}
1058
- return null;
1059
- }
1060
- function assertSnapshotExists(snapshotId, paths) {
1061
- const snapshotDir = join(paths.snapshotsDir, snapshotId);
1062
- if (!existsSync(join(snapshotDir, "snapshot_file")) || !existsSync(join(snapshotDir, "mem_file"))) throw snapshotNotFoundError(snapshotId);
1063
- }
1064
- export { getVmPid as a, NetworkManager as c, getVmJailerPid as i, findKernel as n, validateEnvironment as o, findRootfs as r, waitForSocket as s, assertSnapshotExists as t };