@celilo/cli 0.4.1 → 0.5.0-alpha.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.
@@ -358,7 +358,7 @@ describe('Variable Context', () => {
358
358
  name: 'Grafana',
359
359
  version: '1.0.0',
360
360
  requires: {
361
- machine: {
361
+ system: {
362
362
  cpu: 2,
363
363
  memory: 2048,
364
364
  disk: 20,
@@ -372,34 +372,11 @@ describe('Variable Context', () => {
372
372
 
373
373
  const context = await buildResolutionContext('grafana', db);
374
374
 
375
- expect(context.selfConfig['requires.machine.cpu']).toBe('2');
376
- expect(context.selfConfig['requires.machine.memory']).toBe('2048');
377
- expect(context.selfConfig['requires.machine.disk']).toBe('20');
378
- expect(context.selfConfig['requires.machine.storage']).toBe('local-lvm');
379
- expect(context.selfConfig['requires.machine.zone']).toBe('app');
380
- });
381
-
382
- test('should handle module without VM resources', async () => {
383
- // Create module without VM resources
384
- db.insert(modules)
385
- .values({
386
- id: 'simple',
387
- name: 'Simple Module',
388
- version: '1.0.0',
389
- sourcePath: '/test/simple',
390
- manifestData: {
391
- id: 'simple',
392
- name: 'Simple Module',
393
- version: '1.0.0',
394
- },
395
- })
396
- .run();
397
-
398
- const context = await buildResolutionContext('simple', db);
399
-
400
- // Should not have requires.machine keys
401
- expect(context.selfConfig['requires.machine.cpu']).toBeUndefined();
402
- expect(context.selfConfig['requires.machine.memory']).toBeUndefined();
375
+ expect(context.selfConfig['requires.system.cpu']).toBe('2');
376
+ expect(context.selfConfig['requires.system.memory']).toBe('2048');
377
+ expect(context.selfConfig['requires.system.disk']).toBe('20');
378
+ expect(context.selfConfig['requires.system.storage']).toBe('local-lvm');
379
+ expect(context.selfConfig['requires.system.zone']).toBe('app');
403
380
  });
404
381
 
405
382
  test('should auto-derive inventory variables from target_ip', async () => {
@@ -472,7 +449,7 @@ describe('Variable Context', () => {
472
449
  ],
473
450
  },
474
451
  requires: {
475
- machine: {
452
+ system: {
476
453
  zone: 'dmz',
477
454
  },
478
455
  },
@@ -529,7 +506,7 @@ describe('Variable Context', () => {
529
506
  { name: 'target_ip', type: 'string', required: true, source: 'user' },
530
507
  ],
531
508
  },
532
- requires: { machine: { zone: 'dmz' } },
509
+ requires: { system: { zone: 'dmz' } },
533
510
  },
534
511
  })
535
512
  .run();
@@ -649,7 +626,7 @@ describe('Variable Context', () => {
649
626
  { name: 'target_ip', type: 'string', required: true, source: 'user' },
650
627
  ],
651
628
  },
652
- requires: { machine: { zone: 'dmz' } },
629
+ requires: { system: { zone: 'dmz' } },
653
630
  },
654
631
  })
655
632
  .run();
@@ -672,7 +649,7 @@ describe('Variable Context', () => {
672
649
  { name: 'target_ip', type: 'string', required: true, source: 'user' },
673
650
  ],
674
651
  },
675
- requires: { machine: { zone: 'dmz' } },
652
+ requires: { system: { zone: 'dmz' } },
676
653
  },
677
654
  })
678
655
  .run();
@@ -890,7 +867,7 @@ describe('Variable Context', () => {
890
867
  name: 'App With Resources',
891
868
  version: '1.0.0',
892
869
  requires: {
893
- machine: {
870
+ system: {
894
871
  cpu: 2,
895
872
  memory: 2048,
896
873
  disk: 20,
@@ -935,7 +912,7 @@ describe('Variable Context', () => {
935
912
  name: 'Custom Resources',
936
913
  version: '1.0.0',
937
914
  requires: {
938
- machine: {
915
+ system: {
939
916
  cpu: 2,
940
917
  memory: 2048,
941
918
  },
@@ -997,7 +974,7 @@ describe('Variable Context', () => {
997
974
  name: 'Partial Resources',
998
975
  version: '1.0.0',
999
976
  requires: {
1000
- machine: {
977
+ system: {
1001
978
  cpu: 1,
1002
979
  memory: 512,
1003
980
  // No disk or storage specified
@@ -1031,7 +1008,7 @@ describe('Variable Context', () => {
1031
1008
  name: 'DMZ Module',
1032
1009
  version: '1.0.0',
1033
1010
  requires: {
1034
- machine: {
1011
+ system: {
1035
1012
  zone: 'dmz',
1036
1013
  },
1037
1014
  },
@@ -1073,7 +1050,7 @@ describe('Variable Context', () => {
1073
1050
  name: 'App Module',
1074
1051
  version: '1.0.0',
1075
1052
  requires: {
1076
- machine: {
1053
+ system: {
1077
1054
  zone: 'app',
1078
1055
  },
1079
1056
  },
@@ -1103,7 +1080,7 @@ describe('Variable Context', () => {
1103
1080
  name: 'Secure Module',
1104
1081
  version: '1.0.0',
1105
1082
  requires: {
1106
- machine: {
1083
+ system: {
1107
1084
  zone: 'secure',
1108
1085
  },
1109
1086
  },
@@ -1158,7 +1135,7 @@ describe('Variable Context', () => {
1158
1135
  name: 'Custom Network',
1159
1136
  version: '1.0.0',
1160
1137
  requires: {
1161
- machine: {
1138
+ system: {
1162
1139
  zone: 'dmz',
1163
1140
  },
1164
1141
  },
@@ -1198,7 +1175,7 @@ describe('Variable Context', () => {
1198
1175
  name: 'VPS External',
1199
1176
  version: '1.0.0',
1200
1177
  requires: {
1201
- machine: {
1178
+ system: {
1202
1179
  zone: 'external',
1203
1180
  },
1204
1181
  },
@@ -1228,7 +1205,7 @@ describe('Variable Context', () => {
1228
1205
  name: 'No Net Config',
1229
1206
  version: '1.0.0',
1230
1207
  requires: {
1231
- machine: {
1208
+ system: {
1232
1209
  zone: 'dmz',
1233
1210
  },
1234
1211
  },
@@ -14,7 +14,7 @@ import {
14
14
  systemSecrets,
15
15
  } from '../db/schema';
16
16
  import { allocateResources, getAllocation } from '../ipam/allocator';
17
- import { type ModuleManifest, getDeclaredSystems } from '../manifest/schema';
17
+ import { type ModuleManifest, getDeclaredSystems, getSingularSystemSpec } from '../manifest/schema';
18
18
  import { decryptSecret } from '../secrets/encryption';
19
19
  import { getOrCreateMasterKey } from '../secrets/master-key';
20
20
  import { upsertModuleConfig } from '../services/module-config';
@@ -76,7 +76,7 @@ async function autoAssignFromWellKnown(
76
76
  const wellKnown = getWellKnownCapability(capability.name);
77
77
 
78
78
  // Determine current zone (from config or manifest)
79
- const currentZone = selfConfig.zone || manifest.requires?.machine?.zone;
79
+ const currentZone = selfConfig.zone || getSingularSystemSpec(manifest)?.zone;
80
80
 
81
81
  // Auto-assign hostname if not already set
82
82
  if (!selfConfig.hostname) {
@@ -261,22 +261,22 @@ export async function buildResolutionContext(
261
261
  // Auto-apply VM resource defaults from manifest if not already configured
262
262
  if (module?.manifestData) {
263
263
  const manifest = module.manifestData as ModuleManifest;
264
- const machineResources = manifest.requires?.machine;
264
+ const systemResources = getSingularSystemSpec(manifest);
265
265
 
266
- if (machineResources) {
266
+ if (systemResources) {
267
267
  // Map manifest fields to module variable names and apply defaults
268
268
  const resourceMappings: Array<{
269
- manifestKey: keyof typeof machineResources;
269
+ manifestKey: keyof typeof systemResources;
270
270
  configKey: string;
271
271
  }> = [
272
- { manifestKey: 'cpu', configKey: 'cores' }, // manifest.requires.machine.cpu → cores variable
272
+ { manifestKey: 'cpu', configKey: 'cores' }, // manifest.requires.system.cpu → cores variable
273
273
  { manifestKey: 'memory', configKey: 'memory' },
274
274
  { manifestKey: 'disk', configKey: 'disk' },
275
275
  { manifestKey: 'storage', configKey: 'storage' },
276
276
  ];
277
277
 
278
278
  for (const { manifestKey, configKey } of resourceMappings) {
279
- const value = machineResources[manifestKey];
279
+ const value = systemResources[manifestKey];
280
280
 
281
281
  // Manifest fields are typed (cpu: number, storage: string, etc.).
282
282
  // Pass them through unstringified so valueJson preserves the
@@ -374,15 +374,13 @@ export async function buildResolutionContext(
374
374
  }
375
375
  }
376
376
 
377
- // Add machine requirements from manifest to selfConfig so templates can
378
- // reference them via $self:requires.machine.<field>
377
+ // Add system requirements from manifest to selfConfig so templates can
378
+ // reference them via $self:requires.system.<field>.
379
379
  if (module?.manifestData) {
380
- const manifest = module.manifestData as Record<string, unknown>;
381
- const requires = manifest.requires as Record<string, unknown> | undefined;
382
- if (requires?.machine) {
383
- const machineRequires = requires.machine as Record<string, unknown>;
384
- for (const [key, value] of Object.entries(machineRequires)) {
385
- selfConfig[`requires.machine.${key}`] = String(value);
380
+ const systemSpec = getSingularSystemSpec(module.manifestData as ModuleManifest);
381
+ if (systemSpec) {
382
+ for (const [key, value] of Object.entries(systemSpec)) {
383
+ selfConfig[`requires.system.${key}`] = String(value);
386
384
  }
387
385
  }
388
386
  }
@@ -550,7 +548,7 @@ export async function buildResolutionContext(
550
548
  // Auto-derive network config from zone (gateway, vlan, subnet, bridge)
551
549
  if (module?.manifestData) {
552
550
  const manifest = module.manifestData as ModuleManifest;
553
- const zone = selfConfig.zone || manifest.requires?.machine?.zone;
551
+ const zone = selfConfig.zone || getSingularSystemSpec(manifest)?.zone;
554
552
 
555
553
  // If zone from manifest but not in selfConfig, store it as first-class config
556
554
  if (zone && !selfConfig.zone) {
@@ -24,7 +24,7 @@ describe('lxc_nameserver composition', () => {
24
24
  id: 'consumer',
25
25
  name: 'consumer',
26
26
  version: '1.0.0',
27
- manifestData: { requires: { machine: { zone: 'app' } } },
27
+ manifestData: { requires: { system: { zone: 'app' } } },
28
28
  sourcePath: '/tmp/consumer',
29
29
  })
30
30
  .run();
package/tsconfig.json CHANGED
@@ -16,6 +16,6 @@
16
16
  "@/*": ["./src/*"]
17
17
  }
18
18
  },
19
- "include": ["src/**/*"],
19
+ "include": ["src/**/*", "test-integration/**/*"],
20
20
  "exclude": ["node_modules"]
21
21
  }