pmcf 1.8.1 → 1.9.1
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/pmcf-host-defs +2 -2
- package/bin/pmcf-location-defs +1 -1
- package/package.json +1 -1
- package/src/model.mjs +126 -61
- package/types/model.d.mts +9 -5
package/bin/pmcf-host-defs
CHANGED
|
@@ -28,10 +28,10 @@ async function generateMachineInfo(host, dir) {
|
|
|
28
28
|
etcDir,
|
|
29
29
|
"machine-info",
|
|
30
30
|
Object.entries({
|
|
31
|
-
CHASSIS: host.
|
|
31
|
+
CHASSIS: host.chassis,
|
|
32
32
|
DEPLOYMENT: host.deployment,
|
|
33
33
|
LOCATION: host.location.name,
|
|
34
|
-
HARDWARE_VENDOR: host.
|
|
34
|
+
HARDWARE_VENDOR: host.vendor,
|
|
35
35
|
HARDWARE_MODEL: host.modelName
|
|
36
36
|
}).map(([k, v]) => `${k}=${v}`)
|
|
37
37
|
);
|
package/bin/pmcf-location-defs
CHANGED
|
@@ -62,7 +62,7 @@ async function generateLocationDefs(location, dir) {
|
|
|
62
62
|
await mkdir(locationDir, { recursive: true });
|
|
63
63
|
|
|
64
64
|
copyFile(
|
|
65
|
-
join(
|
|
65
|
+
join(location.directory, "location.json"),
|
|
66
66
|
join(locationDir, "location.json")
|
|
67
67
|
);
|
|
68
68
|
}
|
package/package.json
CHANGED
package/src/model.mjs
CHANGED
|
@@ -27,20 +27,14 @@ export class Base {
|
|
|
27
27
|
return undefined;
|
|
28
28
|
}
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
return name.substring(0, name.length - this.typeFileName.length - 1);
|
|
32
|
-
}
|
|
33
|
-
|
|
34
|
-
return name;
|
|
30
|
+
return name.replace(/\/\w+\.json$/, "");
|
|
35
31
|
}
|
|
36
32
|
|
|
37
33
|
constructor(owner, data) {
|
|
38
34
|
this.owner = owner;
|
|
39
35
|
|
|
40
36
|
if (data) {
|
|
41
|
-
|
|
42
|
-
this.name = data.name;
|
|
43
|
-
}
|
|
37
|
+
this.name = data.name;
|
|
44
38
|
if (data.description) {
|
|
45
39
|
this.description = data.description;
|
|
46
40
|
}
|
|
@@ -82,6 +76,10 @@ export class Base {
|
|
|
82
76
|
return this.#directory || join(this.owner.directory, this.name);
|
|
83
77
|
}
|
|
84
78
|
|
|
79
|
+
get fullName() {
|
|
80
|
+
return join(this.owner.fullName, this.name);
|
|
81
|
+
}
|
|
82
|
+
|
|
85
83
|
expand(object) {
|
|
86
84
|
if (typeof object === "string") {
|
|
87
85
|
return object.replaceAll(/\$\{([^\}]*)\}/g, (match, m1) => {
|
|
@@ -109,7 +107,7 @@ export class Base {
|
|
|
109
107
|
}
|
|
110
108
|
|
|
111
109
|
toString() {
|
|
112
|
-
return this.
|
|
110
|
+
return `${this.fullName}(${this.typeName})`;
|
|
113
111
|
}
|
|
114
112
|
|
|
115
113
|
get propertyNames() {
|
|
@@ -133,8 +131,13 @@ export class Owner extends Base {
|
|
|
133
131
|
}
|
|
134
132
|
}
|
|
135
133
|
|
|
134
|
+
addObject(object) {
|
|
135
|
+
this.world.addObject(object);
|
|
136
|
+
}
|
|
137
|
+
|
|
136
138
|
addHost(host) {
|
|
137
139
|
this.#hosts.set(host.name, host);
|
|
140
|
+
this.addObject(host);
|
|
138
141
|
}
|
|
139
142
|
|
|
140
143
|
network(name) {
|
|
@@ -244,7 +247,11 @@ export class Owner extends Base {
|
|
|
244
247
|
|
|
245
248
|
export class World extends Owner {
|
|
246
249
|
static get types() {
|
|
247
|
-
return
|
|
250
|
+
return _typesByName;
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
static get typeName() {
|
|
254
|
+
return "world";
|
|
248
255
|
}
|
|
249
256
|
|
|
250
257
|
#byName = new Map();
|
|
@@ -252,39 +259,64 @@ export class World extends Owner {
|
|
|
252
259
|
constructor(directory) {
|
|
253
260
|
super(undefined, { name: "" });
|
|
254
261
|
this.directory = directory;
|
|
262
|
+
this.addObject(this);
|
|
263
|
+
}
|
|
264
|
+
|
|
265
|
+
get fullName() {
|
|
266
|
+
return "";
|
|
255
267
|
}
|
|
256
268
|
|
|
257
269
|
get world() {
|
|
258
270
|
return this;
|
|
259
271
|
}
|
|
260
272
|
|
|
261
|
-
async
|
|
262
|
-
|
|
273
|
+
async load(name, options) {
|
|
274
|
+
if (name === "") {
|
|
275
|
+
return this;
|
|
276
|
+
}
|
|
277
|
+
const baseName = Base.baseName(name);
|
|
263
278
|
|
|
264
279
|
let object = this.#byName.get(baseName);
|
|
265
280
|
|
|
266
281
|
if (!object) {
|
|
267
|
-
const data = JSON.parse(
|
|
268
|
-
await readFile(
|
|
269
|
-
join(this.directory, baseName, type.typeFileName),
|
|
270
|
-
"utf8"
|
|
271
|
-
)
|
|
272
|
-
);
|
|
273
|
-
|
|
274
|
-
let owner;
|
|
275
282
|
let path = baseName.split("/");
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
283
|
+
path.pop();
|
|
284
|
+
|
|
285
|
+
let data;
|
|
286
|
+
let type = options?.type;
|
|
287
|
+
if (type) {
|
|
288
|
+
data = JSON.parse(
|
|
289
|
+
await readFile(
|
|
290
|
+
join(this.directory, baseName, type.typeFileName),
|
|
291
|
+
"utf8"
|
|
292
|
+
)
|
|
293
|
+
);
|
|
281
294
|
} else {
|
|
282
|
-
|
|
295
|
+
for (type of _types) {
|
|
296
|
+
try {
|
|
297
|
+
data = JSON.parse(
|
|
298
|
+
await readFile(
|
|
299
|
+
join(this.directory, baseName, type.typeFileName),
|
|
300
|
+
"utf8"
|
|
301
|
+
)
|
|
302
|
+
);
|
|
303
|
+
break;
|
|
304
|
+
} catch {}
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
if (!data) {
|
|
308
|
+
return this.load(path.join("/"), options);
|
|
309
|
+
}
|
|
283
310
|
}
|
|
284
311
|
|
|
285
|
-
|
|
312
|
+
const owner = await this.load(path.join("/"));
|
|
313
|
+
|
|
314
|
+
const length = owner.fullName.length;
|
|
315
|
+
const n = baseName[length] === "/" ? length + 1 : length;
|
|
316
|
+
data.name = baseName.substring(n);
|
|
286
317
|
|
|
287
318
|
type = await type.prepareData(this, data);
|
|
319
|
+
|
|
288
320
|
object = new type(owner, data);
|
|
289
321
|
this.addObject(object);
|
|
290
322
|
}
|
|
@@ -292,27 +324,27 @@ export class World extends Owner {
|
|
|
292
324
|
return object;
|
|
293
325
|
}
|
|
294
326
|
|
|
295
|
-
async
|
|
327
|
+
async loadAll() {
|
|
296
328
|
for (let type of Object.values(World.types)) {
|
|
297
329
|
for await (const name of glob(type.fileNameGlob, {
|
|
298
330
|
cwd: this.directory
|
|
299
331
|
})) {
|
|
300
|
-
await this.
|
|
332
|
+
await this.load(name, { type });
|
|
301
333
|
}
|
|
302
334
|
}
|
|
303
335
|
}
|
|
304
336
|
|
|
305
337
|
addObject(object) {
|
|
306
|
-
this.#byName.set(object.
|
|
338
|
+
this.#byName.set(object.fullName, object);
|
|
307
339
|
}
|
|
308
340
|
|
|
309
341
|
async named(name) {
|
|
310
|
-
await this.
|
|
342
|
+
await this.loadAll();
|
|
311
343
|
return this.#byName.get(name);
|
|
312
344
|
}
|
|
313
345
|
|
|
314
346
|
async *locations() {
|
|
315
|
-
await this.
|
|
347
|
+
await this.loadAll();
|
|
316
348
|
|
|
317
349
|
for (const object of this.#byName.values()) {
|
|
318
350
|
if (object instanceof Location) {
|
|
@@ -322,7 +354,7 @@ export class World extends Owner {
|
|
|
322
354
|
}
|
|
323
355
|
|
|
324
356
|
async *hosts() {
|
|
325
|
-
await this.
|
|
357
|
+
await this.loadAll();
|
|
326
358
|
|
|
327
359
|
for (const object of this.#byName.values()) {
|
|
328
360
|
if (object instanceof Host) {
|
|
@@ -338,11 +370,11 @@ export class World extends Owner {
|
|
|
338
370
|
}
|
|
339
371
|
|
|
340
372
|
async location(name) {
|
|
341
|
-
return this.
|
|
373
|
+
return this.load(name, { type: Location });
|
|
342
374
|
}
|
|
343
375
|
|
|
344
376
|
async host(name) {
|
|
345
|
-
return this.
|
|
377
|
+
return this.load(name, { type: Host });
|
|
346
378
|
}
|
|
347
379
|
|
|
348
380
|
async *networkAddresses() {
|
|
@@ -508,6 +540,7 @@ export class Host extends Base {
|
|
|
508
540
|
networkInterfaces = {};
|
|
509
541
|
services = {};
|
|
510
542
|
postinstall = [];
|
|
543
|
+
#isModel = false;
|
|
511
544
|
#extends = [];
|
|
512
545
|
#provides = new Set();
|
|
513
546
|
#replaces = new Set();
|
|
@@ -516,6 +549,8 @@ export class Host extends Base {
|
|
|
516
549
|
#os;
|
|
517
550
|
#distribution;
|
|
518
551
|
#deployment;
|
|
552
|
+
#chassis;
|
|
553
|
+
#vendor;
|
|
519
554
|
#location;
|
|
520
555
|
|
|
521
556
|
static get typeName() {
|
|
@@ -531,16 +566,17 @@ export class Host extends Base {
|
|
|
531
566
|
data.extends = await Promise.all(data.extends.map(e => world.host(e)));
|
|
532
567
|
}
|
|
533
568
|
|
|
534
|
-
if (data.name?.indexOf("model/") >= 0) {
|
|
535
|
-
return Model;
|
|
536
|
-
}
|
|
537
|
-
|
|
538
569
|
return this;
|
|
539
570
|
}
|
|
540
571
|
|
|
541
572
|
constructor(owner, data) {
|
|
542
573
|
super(owner, data);
|
|
543
574
|
|
|
575
|
+
if (data.model) {
|
|
576
|
+
this.#isModel = true;
|
|
577
|
+
delete data.model;
|
|
578
|
+
}
|
|
579
|
+
|
|
544
580
|
if (data.location !== undefined) {
|
|
545
581
|
this.#location = data.location;
|
|
546
582
|
delete data.location;
|
|
@@ -550,6 +586,14 @@ export class Host extends Base {
|
|
|
550
586
|
this.#deployment = data.deployment;
|
|
551
587
|
delete data.deployment;
|
|
552
588
|
}
|
|
589
|
+
if (data.chassis !== undefined) {
|
|
590
|
+
this.#chassis = data.chassis;
|
|
591
|
+
delete data.chassis;
|
|
592
|
+
}
|
|
593
|
+
if (data.vendor !== undefined) {
|
|
594
|
+
this.#vendor = data.vendor;
|
|
595
|
+
delete data.vendor;
|
|
596
|
+
}
|
|
553
597
|
if (data.extends !== undefined) {
|
|
554
598
|
this.#extends = data.extends;
|
|
555
599
|
delete data.extends;
|
|
@@ -584,18 +628,8 @@ export class Host extends Base {
|
|
|
584
628
|
owner.addHost(this);
|
|
585
629
|
|
|
586
630
|
for (const [name, iface] of Object.entries(this.networkInterfaces)) {
|
|
587
|
-
iface.host = this;
|
|
588
631
|
iface.name = name;
|
|
589
|
-
|
|
590
|
-
const network = owner.network(iface.network);
|
|
591
|
-
|
|
592
|
-
if (network) {
|
|
593
|
-
iface.network = network;
|
|
594
|
-
network.addHost(this);
|
|
595
|
-
} else {
|
|
596
|
-
this.error("Missing network", iface.network);
|
|
597
|
-
}
|
|
598
|
-
}
|
|
632
|
+
this.networkInterfaces[name] = new NetworkInterface(this, iface);
|
|
599
633
|
}
|
|
600
634
|
|
|
601
635
|
for (const [name, data] of Object.entries(
|
|
@@ -607,7 +641,15 @@ export class Host extends Base {
|
|
|
607
641
|
}
|
|
608
642
|
|
|
609
643
|
get deployment() {
|
|
610
|
-
return this.#deployment || this.extends.find(e => e.deployment);
|
|
644
|
+
return this.#deployment || this.extends.find(e => e.deployment)?.deployment;
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
get chassis() {
|
|
648
|
+
return this.#chassis || this.extends.find(e => e.chassis)?.chassis;
|
|
649
|
+
}
|
|
650
|
+
|
|
651
|
+
get vendor() {
|
|
652
|
+
return this.#vendor || this.extends.find(e => e.vendor)?.vendor;
|
|
611
653
|
}
|
|
612
654
|
|
|
613
655
|
get extends() {
|
|
@@ -652,8 +694,12 @@ export class Host extends Base {
|
|
|
652
694
|
return this.#distribution || this.extends.find(e => e.distribution);
|
|
653
695
|
}
|
|
654
696
|
|
|
697
|
+
get isModel() {
|
|
698
|
+
return this.#isModel;
|
|
699
|
+
}
|
|
700
|
+
|
|
655
701
|
get model() {
|
|
656
|
-
return this.extends.find(h => h
|
|
702
|
+
return this.extends.find(h => h.isModel);
|
|
657
703
|
}
|
|
658
704
|
|
|
659
705
|
get domain() {
|
|
@@ -692,8 +738,6 @@ export class Host extends Base {
|
|
|
692
738
|
}
|
|
693
739
|
|
|
694
740
|
async publicKey(type = "ed25519") {
|
|
695
|
-
console.log("DIR", join(this.directory, `ssh_host_${type}_key.pub`));
|
|
696
|
-
|
|
697
741
|
return readFile(join(this.directory, `ssh_host_${type}_key.pub`), "utf8");
|
|
698
742
|
}
|
|
699
743
|
|
|
@@ -723,7 +767,32 @@ export class Host extends Base {
|
|
|
723
767
|
}
|
|
724
768
|
}
|
|
725
769
|
|
|
726
|
-
export class
|
|
770
|
+
export class NetworkInterface extends Base {
|
|
771
|
+
static get typeName() {
|
|
772
|
+
return "network_interface";
|
|
773
|
+
}
|
|
774
|
+
|
|
775
|
+
constructor(owner, data) {
|
|
776
|
+
super(owner, data);
|
|
777
|
+
|
|
778
|
+
if (data.network) {
|
|
779
|
+
const network = owner.owner.network(data.network);
|
|
780
|
+
|
|
781
|
+
if (network) {
|
|
782
|
+
data.network = network;
|
|
783
|
+
network.addHost(owner);
|
|
784
|
+
} else {
|
|
785
|
+
this.error("Missing network", data.network);
|
|
786
|
+
}
|
|
787
|
+
}
|
|
788
|
+
|
|
789
|
+
Object.assign(this, data);
|
|
790
|
+
}
|
|
791
|
+
|
|
792
|
+
get host() {
|
|
793
|
+
return this.owner;
|
|
794
|
+
}
|
|
795
|
+
}
|
|
727
796
|
|
|
728
797
|
export class Subnet extends Base {
|
|
729
798
|
networks = new Set();
|
|
@@ -838,12 +907,8 @@ export class Service extends Base {
|
|
|
838
907
|
}
|
|
839
908
|
}
|
|
840
909
|
|
|
841
|
-
const _types =
|
|
842
|
-
|
|
843
|
-
t.typeName,
|
|
844
|
-
t
|
|
845
|
-
])
|
|
846
|
-
);
|
|
910
|
+
const _types = [Location, Network, Subnet, Host, Service];
|
|
911
|
+
const _typesByName = Object.fromEntries(_types.map(t => [t.typeName, t]));
|
|
847
912
|
|
|
848
913
|
export async function writeLines(dir, name, lines) {
|
|
849
914
|
await mkdir(dir, { recursive: true });
|
package/types/model.d.mts
CHANGED
|
@@ -17,6 +17,7 @@ export class Base {
|
|
|
17
17
|
network(name: any): Promise<any>;
|
|
18
18
|
set directory(directory: any);
|
|
19
19
|
get directory(): any;
|
|
20
|
+
get fullName(): string;
|
|
20
21
|
expand(object: any): any;
|
|
21
22
|
error(...args: any[]): void;
|
|
22
23
|
info(...args: any[]): void;
|
|
@@ -27,6 +28,7 @@ export class Base {
|
|
|
27
28
|
}
|
|
28
29
|
export class Owner extends Base {
|
|
29
30
|
hosts(): AsyncGenerator<any, void, unknown>;
|
|
31
|
+
addObject(object: any): void;
|
|
30
32
|
addHost(host: any): void;
|
|
31
33
|
network(name: any): any;
|
|
32
34
|
networks(): AsyncGenerator<any, void, unknown>;
|
|
@@ -52,9 +54,8 @@ export class World extends Owner {
|
|
|
52
54
|
};
|
|
53
55
|
constructor(directory: any);
|
|
54
56
|
get world(): this;
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
addObject(object: any): void;
|
|
57
|
+
load(name: any, options: any): any;
|
|
58
|
+
loadAll(): Promise<void>;
|
|
58
59
|
named(name: any): Promise<any>;
|
|
59
60
|
locations(): AsyncGenerator<Location, void, unknown>;
|
|
60
61
|
hosts(): AsyncGenerator<Host, void, unknown>;
|
|
@@ -94,6 +95,8 @@ export class Host extends Base {
|
|
|
94
95
|
services: {};
|
|
95
96
|
postinstall: any[];
|
|
96
97
|
get deployment(): any;
|
|
98
|
+
get chassis(): any;
|
|
99
|
+
get vendor(): any;
|
|
97
100
|
get extends(): any[];
|
|
98
101
|
get provides(): Set<any>;
|
|
99
102
|
get replaces(): Set<any>;
|
|
@@ -102,7 +105,8 @@ export class Host extends Base {
|
|
|
102
105
|
get master(): boolean;
|
|
103
106
|
get os(): any;
|
|
104
107
|
get distribution(): any;
|
|
105
|
-
get
|
|
108
|
+
get isModel(): boolean;
|
|
109
|
+
get model(): any;
|
|
106
110
|
get domain(): any;
|
|
107
111
|
get modelName(): any;
|
|
108
112
|
get hostName(): any;
|
|
@@ -119,7 +123,7 @@ export class Host extends Base {
|
|
|
119
123
|
};
|
|
120
124
|
#private;
|
|
121
125
|
}
|
|
122
|
-
export class
|
|
126
|
+
export class NetworkInterface extends Base {
|
|
123
127
|
}
|
|
124
128
|
export class Subnet extends Base {
|
|
125
129
|
networks: Set<any>;
|