freestyle-sandboxes 0.1.26 → 0.1.28
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/index.cjs +157 -25
- package/index.d.cts +16 -1
- package/index.d.mts +16 -1
- package/index.mjs +157 -26
- package/package.json +1 -1
package/index.cjs
CHANGED
|
@@ -5689,6 +5689,10 @@ function composeCreateVmOptions(arr) {
|
|
|
5689
5689
|
if (options.snapshotId !== void 0)
|
|
5690
5690
|
result.snapshotId = options.snapshotId;
|
|
5691
5691
|
if (options.recreate !== void 0) result.recreate = options.recreate;
|
|
5692
|
+
if (options.aptDeps !== void 0) result.aptDeps = options.aptDeps;
|
|
5693
|
+
if (options.domains !== void 0) result.domains = options.domains;
|
|
5694
|
+
if (options.activityThresholdBytes !== void 0)
|
|
5695
|
+
result.activityThresholdBytes = options.activityThresholdBytes;
|
|
5692
5696
|
if (options.persistence !== void 0)
|
|
5693
5697
|
result.persistence = options.persistence;
|
|
5694
5698
|
if (options.ports !== void 0) {
|
|
@@ -6324,8 +6328,14 @@ class VmSpec {
|
|
|
6324
6328
|
this.with = withBuilders ?? {};
|
|
6325
6329
|
}
|
|
6326
6330
|
}
|
|
6331
|
+
function isVmSpecLike(value) {
|
|
6332
|
+
return !!value && typeof value === "object" && "raw" in value && "with" in value;
|
|
6333
|
+
}
|
|
6334
|
+
function isVmTemplateLike(value) {
|
|
6335
|
+
return !!value && typeof value === "object" && "raw" in value && "with" in value;
|
|
6336
|
+
}
|
|
6327
6337
|
async function convertSpecSnapshotsToTemplates(spec, processBuilders = true) {
|
|
6328
|
-
if (!spec.raw.snapshot) {
|
|
6338
|
+
if (!isVmSpecLike(spec.raw.snapshot)) {
|
|
6329
6339
|
return void 0;
|
|
6330
6340
|
}
|
|
6331
6341
|
let innerSpec = spec.raw.snapshot;
|
|
@@ -6334,7 +6344,7 @@ async function convertSpecSnapshotsToTemplates(spec, processBuilders = true) {
|
|
|
6334
6344
|
}
|
|
6335
6345
|
const { snapshot: nestedSnapshot, ...innerRaw } = innerSpec.raw;
|
|
6336
6346
|
let nestedTemplate;
|
|
6337
|
-
if (nestedSnapshot
|
|
6347
|
+
if (isVmSpecLike(nestedSnapshot)) {
|
|
6338
6348
|
nestedTemplate = await convertSpecSnapshotsToTemplates(innerSpec, false);
|
|
6339
6349
|
}
|
|
6340
6350
|
return new VmTemplate({
|
|
@@ -6352,7 +6362,7 @@ async function processOuterSpecBuilders(spec) {
|
|
|
6352
6362
|
}
|
|
6353
6363
|
if (builder.configureSnapshotSpec) {
|
|
6354
6364
|
let snapshotSpec;
|
|
6355
|
-
if (spec.raw.snapshot
|
|
6365
|
+
if (isVmSpecLike(spec.raw.snapshot)) {
|
|
6356
6366
|
snapshotSpec = spec.raw.snapshot;
|
|
6357
6367
|
} else {
|
|
6358
6368
|
snapshotSpec = new VmSpec({});
|
|
@@ -6373,7 +6383,7 @@ async function processSpecTree(spec) {
|
|
|
6373
6383
|
}
|
|
6374
6384
|
if (builder.configureSnapshotSpec) {
|
|
6375
6385
|
let snapshotSpec;
|
|
6376
|
-
if (spec.raw.snapshot
|
|
6386
|
+
if (isVmSpecLike(spec.raw.snapshot)) {
|
|
6377
6387
|
snapshotSpec = spec.raw.snapshot;
|
|
6378
6388
|
} else {
|
|
6379
6389
|
snapshotSpec = new VmSpec({});
|
|
@@ -6383,14 +6393,14 @@ async function processSpecTree(spec) {
|
|
|
6383
6393
|
}
|
|
6384
6394
|
}
|
|
6385
6395
|
}
|
|
6386
|
-
if (spec.raw.snapshot
|
|
6396
|
+
if (isVmSpecLike(spec.raw.snapshot)) {
|
|
6387
6397
|
spec.raw.snapshot = await processSpecTree(spec.raw.snapshot);
|
|
6388
6398
|
}
|
|
6389
6399
|
return spec;
|
|
6390
6400
|
}
|
|
6391
6401
|
function collectSpecBuilders(spec) {
|
|
6392
6402
|
let builders = {};
|
|
6393
|
-
if (spec.raw.snapshot
|
|
6403
|
+
if (isVmSpecLike(spec.raw.snapshot)) {
|
|
6394
6404
|
builders = collectSpecBuilders(spec.raw.snapshot);
|
|
6395
6405
|
}
|
|
6396
6406
|
if (spec.with) {
|
|
@@ -6426,8 +6436,8 @@ class VmsNamespace {
|
|
|
6426
6436
|
* @returns A VM instance representing the created VM
|
|
6427
6437
|
*/
|
|
6428
6438
|
async create(options = {}) {
|
|
6429
|
-
if (options.snapshot
|
|
6430
|
-
if (options.spec
|
|
6439
|
+
if (isVmSpecLike(options.snapshot)) {
|
|
6440
|
+
if (isVmSpecLike(options.spec)) {
|
|
6431
6441
|
if (!options.spec.raw.snapshot) {
|
|
6432
6442
|
options.spec.raw.snapshot = options.snapshot;
|
|
6433
6443
|
}
|
|
@@ -6477,10 +6487,10 @@ class VmsNamespace {
|
|
|
6477
6487
|
const { snapshot: _snapshot, ...rest } = options;
|
|
6478
6488
|
options = rest;
|
|
6479
6489
|
}
|
|
6480
|
-
if (options.spec
|
|
6490
|
+
if (isVmSpecLike(options.spec) && options.with) {
|
|
6481
6491
|
options.spec = mergeWithBuildersIntoSpec(options.spec, options.with);
|
|
6482
6492
|
}
|
|
6483
|
-
if (options.spec
|
|
6493
|
+
if (isVmSpecLike(options.spec)) {
|
|
6484
6494
|
let spec = options.spec;
|
|
6485
6495
|
spec = await processOuterSpecBuilders(spec);
|
|
6486
6496
|
const { snapshot, ...outerSpecOptions } = spec.raw;
|
|
@@ -6500,19 +6510,19 @@ class VmsNamespace {
|
|
|
6500
6510
|
options.with = spec.with;
|
|
6501
6511
|
}
|
|
6502
6512
|
}
|
|
6503
|
-
const specBuilders = options.spec
|
|
6504
|
-
const templateBuilders = options.template
|
|
6513
|
+
const specBuilders = isVmSpecLike(options.spec) ? collectSpecBuilders(options.spec) : void 0;
|
|
6514
|
+
const templateBuilders = isVmTemplateLike(options.template) ? options.template.with : void 0;
|
|
6505
6515
|
const builders = {
|
|
6506
6516
|
...templateBuilders || {},
|
|
6507
6517
|
...specBuilders || {},
|
|
6508
6518
|
...options.with || {}
|
|
6509
6519
|
};
|
|
6510
|
-
const { with: _, ...baseConfig } = options;
|
|
6520
|
+
const { with: _, spec: _spec, ...baseConfig } = options;
|
|
6511
6521
|
let config = baseConfig;
|
|
6512
|
-
if (config.template
|
|
6522
|
+
if (isVmTemplateLike(config.template)) {
|
|
6513
6523
|
config.template = await processTemplateTree(config.template);
|
|
6514
6524
|
}
|
|
6515
|
-
if (config.template
|
|
6525
|
+
if (isVmTemplateLike(config.template)) {
|
|
6516
6526
|
config.template = await ensureNestedTemplates(
|
|
6517
6527
|
config.template,
|
|
6518
6528
|
this.snapshots
|
|
@@ -6525,10 +6535,47 @@ class VmsNamespace {
|
|
|
6525
6535
|
config = await builder.configure(config);
|
|
6526
6536
|
}
|
|
6527
6537
|
}
|
|
6538
|
+
if (config.systemd?.services) {
|
|
6539
|
+
const normalizedServices = config.systemd.services.map((service) => ({
|
|
6540
|
+
...service,
|
|
6541
|
+
after: service.after?.map(
|
|
6542
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6543
|
+
),
|
|
6544
|
+
requires: service.requires?.map(
|
|
6545
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6546
|
+
),
|
|
6547
|
+
wantedBy: service.wantedBy?.map(
|
|
6548
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6549
|
+
)
|
|
6550
|
+
}));
|
|
6551
|
+
const { services: processedServices, additionalFiles: bashFiles } = processSystemdServices(
|
|
6552
|
+
normalizedServices,
|
|
6553
|
+
config.additionalFiles ?? {}
|
|
6554
|
+
);
|
|
6555
|
+
config.systemd.services = processedServices;
|
|
6556
|
+
config.additionalFiles = bashFiles;
|
|
6557
|
+
}
|
|
6558
|
+
if (config.systemd?.patchedServices) {
|
|
6559
|
+
config.systemd.patchedServices = config.systemd.patchedServices.map(
|
|
6560
|
+
(service) => {
|
|
6561
|
+
service.after = service.after?.map(
|
|
6562
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6563
|
+
);
|
|
6564
|
+
service.requires = service.requires?.map(
|
|
6565
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6566
|
+
);
|
|
6567
|
+
service.wantedBy = service.wantedBy?.map(
|
|
6568
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6569
|
+
);
|
|
6570
|
+
return service;
|
|
6571
|
+
}
|
|
6572
|
+
);
|
|
6573
|
+
}
|
|
6574
|
+
config.git = normalizeGitOptions(config.git);
|
|
6528
6575
|
const response = await this.freestyle._apiClient.post("/v1/vms", {
|
|
6529
6576
|
body: {
|
|
6530
6577
|
...config,
|
|
6531
|
-
template: config.template
|
|
6578
|
+
template: isVmTemplateLike(config.template) ? config.template["raw"] : config.template,
|
|
6532
6579
|
// Cast systemd since we've processed SystemdServiceInput[] to RawSystemdService[]
|
|
6533
6580
|
systemd: config.systemd,
|
|
6534
6581
|
// Normalize git options - default config to {}
|
|
@@ -6629,8 +6676,8 @@ class VmSnapshotsNamespace {
|
|
|
6629
6676
|
}
|
|
6630
6677
|
async ensure(options) {
|
|
6631
6678
|
let requestOptions = options;
|
|
6632
|
-
if (requestOptions.snapshot
|
|
6633
|
-
if (requestOptions.spec
|
|
6679
|
+
if (isVmSpecLike(requestOptions.snapshot)) {
|
|
6680
|
+
if (isVmSpecLike(requestOptions.spec)) {
|
|
6634
6681
|
if (!requestOptions.spec.raw.snapshot) {
|
|
6635
6682
|
requestOptions.spec.raw.snapshot = requestOptions.snapshot;
|
|
6636
6683
|
}
|
|
@@ -6642,7 +6689,7 @@ class VmSnapshotsNamespace {
|
|
|
6642
6689
|
const { snapshot: _snapshot, ...rest } = requestOptions;
|
|
6643
6690
|
requestOptions = rest;
|
|
6644
6691
|
}
|
|
6645
|
-
if (requestOptions.spec
|
|
6692
|
+
if (isVmSpecLike(requestOptions.spec)) {
|
|
6646
6693
|
let spec = requestOptions.spec;
|
|
6647
6694
|
spec = await processSpecTree(spec);
|
|
6648
6695
|
const { snapshot: _snapshotSpec, ...outerSpecOptions } = spec.raw;
|
|
@@ -6657,12 +6704,12 @@ class VmSnapshotsNamespace {
|
|
|
6657
6704
|
const { spec: _spec, ...rest } = requestOptions;
|
|
6658
6705
|
requestOptions = rest;
|
|
6659
6706
|
}
|
|
6660
|
-
if (requestOptions.template
|
|
6707
|
+
if (isVmTemplateLike(requestOptions.template)) {
|
|
6661
6708
|
const processedTemplate = await processTemplateTree(
|
|
6662
6709
|
requestOptions.template
|
|
6663
6710
|
);
|
|
6664
6711
|
requestOptions.template = processedTemplate;
|
|
6665
|
-
if (processedTemplate.raw.template
|
|
6712
|
+
if (isVmTemplateLike(processedTemplate.raw.template)) {
|
|
6666
6713
|
requestOptions.template = await ensureNestedTemplates(
|
|
6667
6714
|
processedTemplate,
|
|
6668
6715
|
this
|
|
@@ -6677,7 +6724,7 @@ class VmSnapshotsNamespace {
|
|
|
6677
6724
|
return this.apiClient.post("/v1/vms/snapshots", {
|
|
6678
6725
|
body: {
|
|
6679
6726
|
...requestOptions,
|
|
6680
|
-
template: requestOptions.template
|
|
6727
|
+
template: isVmTemplateLike(requestOptions.template) ? requestOptions.template.raw : requestOptions.template
|
|
6681
6728
|
}
|
|
6682
6729
|
}).catch((e) => {
|
|
6683
6730
|
enhanceError(e);
|
|
@@ -6719,7 +6766,7 @@ async function processTemplateTree(template) {
|
|
|
6719
6766
|
}
|
|
6720
6767
|
if (builder.configureNestedTemplate) {
|
|
6721
6768
|
let nestedTemplate;
|
|
6722
|
-
if (template.raw.template
|
|
6769
|
+
if (isVmTemplateLike(template.raw.template)) {
|
|
6723
6770
|
nestedTemplate = template.raw.template;
|
|
6724
6771
|
} else {
|
|
6725
6772
|
nestedTemplate = new VmTemplate({});
|
|
@@ -6731,7 +6778,46 @@ async function processTemplateTree(template) {
|
|
|
6731
6778
|
}
|
|
6732
6779
|
}
|
|
6733
6780
|
}
|
|
6734
|
-
if (template.raw.
|
|
6781
|
+
if (template.raw.git) {
|
|
6782
|
+
template.raw.git = normalizeGitOptions(
|
|
6783
|
+
template.raw.git
|
|
6784
|
+
);
|
|
6785
|
+
}
|
|
6786
|
+
if (template.raw.systemd?.services) {
|
|
6787
|
+
const normalizedServices = template.raw.systemd.services.map((service) => ({
|
|
6788
|
+
...service,
|
|
6789
|
+
after: service.after?.map((s) => s.includes(".") ? s : `${s}.service`),
|
|
6790
|
+
requires: service.requires?.map(
|
|
6791
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6792
|
+
),
|
|
6793
|
+
wantedBy: service.wantedBy?.map(
|
|
6794
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6795
|
+
)
|
|
6796
|
+
}));
|
|
6797
|
+
const { services: processedServices, additionalFiles: bashFiles } = processSystemdServices(
|
|
6798
|
+
normalizedServices,
|
|
6799
|
+
template.raw.additionalFiles ?? {}
|
|
6800
|
+
);
|
|
6801
|
+
template.raw.systemd.services = processedServices;
|
|
6802
|
+
template.raw.additionalFiles = bashFiles;
|
|
6803
|
+
}
|
|
6804
|
+
if (template.raw.systemd?.patchedServices) {
|
|
6805
|
+
template.raw.systemd.patchedServices = template.raw.systemd.patchedServices.map(
|
|
6806
|
+
(service) => ({
|
|
6807
|
+
...service,
|
|
6808
|
+
after: service.after?.map(
|
|
6809
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6810
|
+
),
|
|
6811
|
+
requires: service.requires?.map(
|
|
6812
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6813
|
+
),
|
|
6814
|
+
wantedBy: service.wantedBy?.map(
|
|
6815
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6816
|
+
)
|
|
6817
|
+
})
|
|
6818
|
+
);
|
|
6819
|
+
}
|
|
6820
|
+
if (isVmTemplateLike(template.raw.template)) {
|
|
6735
6821
|
template.raw.template = await processTemplateTree(
|
|
6736
6822
|
template.raw.template
|
|
6737
6823
|
);
|
|
@@ -6740,7 +6826,7 @@ async function processTemplateTree(template) {
|
|
|
6740
6826
|
}
|
|
6741
6827
|
async function ensureNestedTemplates(template, snapshots) {
|
|
6742
6828
|
const templates = [template];
|
|
6743
|
-
while (templates.at(-1)?.raw.template
|
|
6829
|
+
while (isVmTemplateLike(templates.at(-1)?.raw.template)) {
|
|
6744
6830
|
const innerTemplate = templates.at(-1).raw.template;
|
|
6745
6831
|
templates.at(-1).raw.template = void 0;
|
|
6746
6832
|
templates.push(innerTemplate);
|
|
@@ -6927,6 +7013,51 @@ async function readFiles(directory) {
|
|
|
6927
7013
|
return files;
|
|
6928
7014
|
}
|
|
6929
7015
|
|
|
7016
|
+
async function debugCreateRequests(freestyle, options = {}) {
|
|
7017
|
+
const requests = [];
|
|
7018
|
+
let snapshotCounter = 0;
|
|
7019
|
+
let vmCounter = 0;
|
|
7020
|
+
const apiClient = freestyle._apiClient;
|
|
7021
|
+
const originalPost = apiClient.post.bind(freestyle._apiClient);
|
|
7022
|
+
const mockPost = (async (path, ...args) => {
|
|
7023
|
+
const rawBody = args[0] && "body" in args[0] ? args[0].body : void 0;
|
|
7024
|
+
const clonedBody = JSON.parse(JSON.stringify(rawBody ?? null));
|
|
7025
|
+
if (path === "/v1/vms/snapshots") {
|
|
7026
|
+
requests.push({
|
|
7027
|
+
path: "/v1/vms/snapshots",
|
|
7028
|
+
body: clonedBody
|
|
7029
|
+
});
|
|
7030
|
+
snapshotCounter += 1;
|
|
7031
|
+
return {
|
|
7032
|
+
snapshotId: `__debug_snapshot_${snapshotCounter}__`
|
|
7033
|
+
};
|
|
7034
|
+
}
|
|
7035
|
+
if (path === "/v1/vms") {
|
|
7036
|
+
requests.push({
|
|
7037
|
+
path: "/v1/vms",
|
|
7038
|
+
body: clonedBody
|
|
7039
|
+
});
|
|
7040
|
+
vmCounter += 1;
|
|
7041
|
+
return {
|
|
7042
|
+
id: `__debug_vm_${vmCounter}__`,
|
|
7043
|
+
domains: [],
|
|
7044
|
+
consoleUrl: "https://debug.local/console"
|
|
7045
|
+
};
|
|
7046
|
+
}
|
|
7047
|
+
return originalPost(
|
|
7048
|
+
path,
|
|
7049
|
+
...args
|
|
7050
|
+
);
|
|
7051
|
+
});
|
|
7052
|
+
apiClient.post = mockPost;
|
|
7053
|
+
try {
|
|
7054
|
+
await freestyle.vms.create(options);
|
|
7055
|
+
} finally {
|
|
7056
|
+
apiClient.post = originalPost;
|
|
7057
|
+
}
|
|
7058
|
+
return requests;
|
|
7059
|
+
}
|
|
7060
|
+
|
|
6930
7061
|
class Freestyle {
|
|
6931
7062
|
/**
|
|
6932
7063
|
* @internal
|
|
@@ -7012,5 +7143,6 @@ exports.VmSpec = VmSpec;
|
|
|
7012
7143
|
exports.VmTemplate = VmTemplate;
|
|
7013
7144
|
exports.VmWith = VmWith;
|
|
7014
7145
|
exports.VmWithInstance = VmWithInstance;
|
|
7146
|
+
exports.debugCreateRequests = debugCreateRequests;
|
|
7015
7147
|
exports.freestyle = freestyle;
|
|
7016
7148
|
exports.readFiles = readFiles;
|
package/index.d.cts
CHANGED
|
@@ -13835,6 +13835,21 @@ declare function readFiles(directory: string): Promise<{
|
|
|
13835
13835
|
encoding: string;
|
|
13836
13836
|
}[]>;
|
|
13837
13837
|
|
|
13838
|
+
type DebugCreateApiRequest = {
|
|
13839
|
+
path: "/v1/vms/snapshots" | "/v1/vms";
|
|
13840
|
+
body: unknown;
|
|
13841
|
+
};
|
|
13842
|
+
/**
|
|
13843
|
+
* Simulate what the SDK would POST during `freestyle.vms.create(...)` and
|
|
13844
|
+
* return all request bodies in execution order without network calls.
|
|
13845
|
+
*/
|
|
13846
|
+
declare function debugCreateRequests<T extends Record<string, VmWith>>(freestyle: Freestyle, options?: CreateVmOptions & {
|
|
13847
|
+
with?: T;
|
|
13848
|
+
template?: VmTemplate<T>;
|
|
13849
|
+
spec?: VmSpec<T>;
|
|
13850
|
+
snapshot?: VmSpec<T>;
|
|
13851
|
+
}): Promise<DebugCreateApiRequest[]>;
|
|
13852
|
+
|
|
13838
13853
|
type FreestyleOptions = ApiClientConfig;
|
|
13839
13854
|
declare class Freestyle {
|
|
13840
13855
|
readonly domains: DomainsNamespace;
|
|
@@ -13856,5 +13871,5 @@ declare class Freestyle {
|
|
|
13856
13871
|
*/
|
|
13857
13872
|
declare const freestyle: Freestyle;
|
|
13858
13873
|
|
|
13859
|
-
export { CronNamespace, Deployment, errors as Errors, FileSystem, Freestyle, GitRepo, Identity, requests as Requests, responses as Responses, Systemd, SystemdService, Vm, VmBuilder, VmService, VmSpec, VmTemplate, VmWith, VmWithInstance, freestyle, readFiles };
|
|
13874
|
+
export { CronNamespace, Deployment, errors as Errors, FileSystem, Freestyle, GitRepo, Identity, requests as Requests, responses as Responses, Systemd, SystemdService, Vm, VmBuilder, VmService, VmSpec, VmTemplate, VmWith, VmWithInstance, debugCreateRequests, freestyle, readFiles };
|
|
13860
13875
|
export type { CreateVmOptions, CronSchedule, FreestyleOptions, SystemdServiceInput };
|
package/index.d.mts
CHANGED
|
@@ -13835,6 +13835,21 @@ declare function readFiles(directory: string): Promise<{
|
|
|
13835
13835
|
encoding: string;
|
|
13836
13836
|
}[]>;
|
|
13837
13837
|
|
|
13838
|
+
type DebugCreateApiRequest = {
|
|
13839
|
+
path: "/v1/vms/snapshots" | "/v1/vms";
|
|
13840
|
+
body: unknown;
|
|
13841
|
+
};
|
|
13842
|
+
/**
|
|
13843
|
+
* Simulate what the SDK would POST during `freestyle.vms.create(...)` and
|
|
13844
|
+
* return all request bodies in execution order without network calls.
|
|
13845
|
+
*/
|
|
13846
|
+
declare function debugCreateRequests<T extends Record<string, VmWith>>(freestyle: Freestyle, options?: CreateVmOptions & {
|
|
13847
|
+
with?: T;
|
|
13848
|
+
template?: VmTemplate<T>;
|
|
13849
|
+
spec?: VmSpec<T>;
|
|
13850
|
+
snapshot?: VmSpec<T>;
|
|
13851
|
+
}): Promise<DebugCreateApiRequest[]>;
|
|
13852
|
+
|
|
13838
13853
|
type FreestyleOptions = ApiClientConfig;
|
|
13839
13854
|
declare class Freestyle {
|
|
13840
13855
|
readonly domains: DomainsNamespace;
|
|
@@ -13856,5 +13871,5 @@ declare class Freestyle {
|
|
|
13856
13871
|
*/
|
|
13857
13872
|
declare const freestyle: Freestyle;
|
|
13858
13873
|
|
|
13859
|
-
export { CronNamespace, Deployment, errors as Errors, FileSystem, Freestyle, GitRepo, Identity, requests as Requests, responses as Responses, Systemd, SystemdService, Vm, VmBuilder, VmService, VmSpec, VmTemplate, VmWith, VmWithInstance, freestyle, readFiles };
|
|
13874
|
+
export { CronNamespace, Deployment, errors as Errors, FileSystem, Freestyle, GitRepo, Identity, requests as Requests, responses as Responses, Systemd, SystemdService, Vm, VmBuilder, VmService, VmSpec, VmTemplate, VmWith, VmWithInstance, debugCreateRequests, freestyle, readFiles };
|
|
13860
13875
|
export type { CreateVmOptions, CronSchedule, FreestyleOptions, SystemdServiceInput };
|
package/index.mjs
CHANGED
|
@@ -5687,6 +5687,10 @@ function composeCreateVmOptions(arr) {
|
|
|
5687
5687
|
if (options.snapshotId !== void 0)
|
|
5688
5688
|
result.snapshotId = options.snapshotId;
|
|
5689
5689
|
if (options.recreate !== void 0) result.recreate = options.recreate;
|
|
5690
|
+
if (options.aptDeps !== void 0) result.aptDeps = options.aptDeps;
|
|
5691
|
+
if (options.domains !== void 0) result.domains = options.domains;
|
|
5692
|
+
if (options.activityThresholdBytes !== void 0)
|
|
5693
|
+
result.activityThresholdBytes = options.activityThresholdBytes;
|
|
5690
5694
|
if (options.persistence !== void 0)
|
|
5691
5695
|
result.persistence = options.persistence;
|
|
5692
5696
|
if (options.ports !== void 0) {
|
|
@@ -6322,8 +6326,14 @@ class VmSpec {
|
|
|
6322
6326
|
this.with = withBuilders ?? {};
|
|
6323
6327
|
}
|
|
6324
6328
|
}
|
|
6329
|
+
function isVmSpecLike(value) {
|
|
6330
|
+
return !!value && typeof value === "object" && "raw" in value && "with" in value;
|
|
6331
|
+
}
|
|
6332
|
+
function isVmTemplateLike(value) {
|
|
6333
|
+
return !!value && typeof value === "object" && "raw" in value && "with" in value;
|
|
6334
|
+
}
|
|
6325
6335
|
async function convertSpecSnapshotsToTemplates(spec, processBuilders = true) {
|
|
6326
|
-
if (!spec.raw.snapshot) {
|
|
6336
|
+
if (!isVmSpecLike(spec.raw.snapshot)) {
|
|
6327
6337
|
return void 0;
|
|
6328
6338
|
}
|
|
6329
6339
|
let innerSpec = spec.raw.snapshot;
|
|
@@ -6332,7 +6342,7 @@ async function convertSpecSnapshotsToTemplates(spec, processBuilders = true) {
|
|
|
6332
6342
|
}
|
|
6333
6343
|
const { snapshot: nestedSnapshot, ...innerRaw } = innerSpec.raw;
|
|
6334
6344
|
let nestedTemplate;
|
|
6335
|
-
if (nestedSnapshot
|
|
6345
|
+
if (isVmSpecLike(nestedSnapshot)) {
|
|
6336
6346
|
nestedTemplate = await convertSpecSnapshotsToTemplates(innerSpec, false);
|
|
6337
6347
|
}
|
|
6338
6348
|
return new VmTemplate({
|
|
@@ -6350,7 +6360,7 @@ async function processOuterSpecBuilders(spec) {
|
|
|
6350
6360
|
}
|
|
6351
6361
|
if (builder.configureSnapshotSpec) {
|
|
6352
6362
|
let snapshotSpec;
|
|
6353
|
-
if (spec.raw.snapshot
|
|
6363
|
+
if (isVmSpecLike(spec.raw.snapshot)) {
|
|
6354
6364
|
snapshotSpec = spec.raw.snapshot;
|
|
6355
6365
|
} else {
|
|
6356
6366
|
snapshotSpec = new VmSpec({});
|
|
@@ -6371,7 +6381,7 @@ async function processSpecTree(spec) {
|
|
|
6371
6381
|
}
|
|
6372
6382
|
if (builder.configureSnapshotSpec) {
|
|
6373
6383
|
let snapshotSpec;
|
|
6374
|
-
if (spec.raw.snapshot
|
|
6384
|
+
if (isVmSpecLike(spec.raw.snapshot)) {
|
|
6375
6385
|
snapshotSpec = spec.raw.snapshot;
|
|
6376
6386
|
} else {
|
|
6377
6387
|
snapshotSpec = new VmSpec({});
|
|
@@ -6381,14 +6391,14 @@ async function processSpecTree(spec) {
|
|
|
6381
6391
|
}
|
|
6382
6392
|
}
|
|
6383
6393
|
}
|
|
6384
|
-
if (spec.raw.snapshot
|
|
6394
|
+
if (isVmSpecLike(spec.raw.snapshot)) {
|
|
6385
6395
|
spec.raw.snapshot = await processSpecTree(spec.raw.snapshot);
|
|
6386
6396
|
}
|
|
6387
6397
|
return spec;
|
|
6388
6398
|
}
|
|
6389
6399
|
function collectSpecBuilders(spec) {
|
|
6390
6400
|
let builders = {};
|
|
6391
|
-
if (spec.raw.snapshot
|
|
6401
|
+
if (isVmSpecLike(spec.raw.snapshot)) {
|
|
6392
6402
|
builders = collectSpecBuilders(spec.raw.snapshot);
|
|
6393
6403
|
}
|
|
6394
6404
|
if (spec.with) {
|
|
@@ -6424,8 +6434,8 @@ class VmsNamespace {
|
|
|
6424
6434
|
* @returns A VM instance representing the created VM
|
|
6425
6435
|
*/
|
|
6426
6436
|
async create(options = {}) {
|
|
6427
|
-
if (options.snapshot
|
|
6428
|
-
if (options.spec
|
|
6437
|
+
if (isVmSpecLike(options.snapshot)) {
|
|
6438
|
+
if (isVmSpecLike(options.spec)) {
|
|
6429
6439
|
if (!options.spec.raw.snapshot) {
|
|
6430
6440
|
options.spec.raw.snapshot = options.snapshot;
|
|
6431
6441
|
}
|
|
@@ -6475,10 +6485,10 @@ class VmsNamespace {
|
|
|
6475
6485
|
const { snapshot: _snapshot, ...rest } = options;
|
|
6476
6486
|
options = rest;
|
|
6477
6487
|
}
|
|
6478
|
-
if (options.spec
|
|
6488
|
+
if (isVmSpecLike(options.spec) && options.with) {
|
|
6479
6489
|
options.spec = mergeWithBuildersIntoSpec(options.spec, options.with);
|
|
6480
6490
|
}
|
|
6481
|
-
if (options.spec
|
|
6491
|
+
if (isVmSpecLike(options.spec)) {
|
|
6482
6492
|
let spec = options.spec;
|
|
6483
6493
|
spec = await processOuterSpecBuilders(spec);
|
|
6484
6494
|
const { snapshot, ...outerSpecOptions } = spec.raw;
|
|
@@ -6498,19 +6508,19 @@ class VmsNamespace {
|
|
|
6498
6508
|
options.with = spec.with;
|
|
6499
6509
|
}
|
|
6500
6510
|
}
|
|
6501
|
-
const specBuilders = options.spec
|
|
6502
|
-
const templateBuilders = options.template
|
|
6511
|
+
const specBuilders = isVmSpecLike(options.spec) ? collectSpecBuilders(options.spec) : void 0;
|
|
6512
|
+
const templateBuilders = isVmTemplateLike(options.template) ? options.template.with : void 0;
|
|
6503
6513
|
const builders = {
|
|
6504
6514
|
...templateBuilders || {},
|
|
6505
6515
|
...specBuilders || {},
|
|
6506
6516
|
...options.with || {}
|
|
6507
6517
|
};
|
|
6508
|
-
const { with: _, ...baseConfig } = options;
|
|
6518
|
+
const { with: _, spec: _spec, ...baseConfig } = options;
|
|
6509
6519
|
let config = baseConfig;
|
|
6510
|
-
if (config.template
|
|
6520
|
+
if (isVmTemplateLike(config.template)) {
|
|
6511
6521
|
config.template = await processTemplateTree(config.template);
|
|
6512
6522
|
}
|
|
6513
|
-
if (config.template
|
|
6523
|
+
if (isVmTemplateLike(config.template)) {
|
|
6514
6524
|
config.template = await ensureNestedTemplates(
|
|
6515
6525
|
config.template,
|
|
6516
6526
|
this.snapshots
|
|
@@ -6523,10 +6533,47 @@ class VmsNamespace {
|
|
|
6523
6533
|
config = await builder.configure(config);
|
|
6524
6534
|
}
|
|
6525
6535
|
}
|
|
6536
|
+
if (config.systemd?.services) {
|
|
6537
|
+
const normalizedServices = config.systemd.services.map((service) => ({
|
|
6538
|
+
...service,
|
|
6539
|
+
after: service.after?.map(
|
|
6540
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6541
|
+
),
|
|
6542
|
+
requires: service.requires?.map(
|
|
6543
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6544
|
+
),
|
|
6545
|
+
wantedBy: service.wantedBy?.map(
|
|
6546
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6547
|
+
)
|
|
6548
|
+
}));
|
|
6549
|
+
const { services: processedServices, additionalFiles: bashFiles } = processSystemdServices(
|
|
6550
|
+
normalizedServices,
|
|
6551
|
+
config.additionalFiles ?? {}
|
|
6552
|
+
);
|
|
6553
|
+
config.systemd.services = processedServices;
|
|
6554
|
+
config.additionalFiles = bashFiles;
|
|
6555
|
+
}
|
|
6556
|
+
if (config.systemd?.patchedServices) {
|
|
6557
|
+
config.systemd.patchedServices = config.systemd.patchedServices.map(
|
|
6558
|
+
(service) => {
|
|
6559
|
+
service.after = service.after?.map(
|
|
6560
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6561
|
+
);
|
|
6562
|
+
service.requires = service.requires?.map(
|
|
6563
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6564
|
+
);
|
|
6565
|
+
service.wantedBy = service.wantedBy?.map(
|
|
6566
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6567
|
+
);
|
|
6568
|
+
return service;
|
|
6569
|
+
}
|
|
6570
|
+
);
|
|
6571
|
+
}
|
|
6572
|
+
config.git = normalizeGitOptions(config.git);
|
|
6526
6573
|
const response = await this.freestyle._apiClient.post("/v1/vms", {
|
|
6527
6574
|
body: {
|
|
6528
6575
|
...config,
|
|
6529
|
-
template: config.template
|
|
6576
|
+
template: isVmTemplateLike(config.template) ? config.template["raw"] : config.template,
|
|
6530
6577
|
// Cast systemd since we've processed SystemdServiceInput[] to RawSystemdService[]
|
|
6531
6578
|
systemd: config.systemd,
|
|
6532
6579
|
// Normalize git options - default config to {}
|
|
@@ -6627,8 +6674,8 @@ class VmSnapshotsNamespace {
|
|
|
6627
6674
|
}
|
|
6628
6675
|
async ensure(options) {
|
|
6629
6676
|
let requestOptions = options;
|
|
6630
|
-
if (requestOptions.snapshot
|
|
6631
|
-
if (requestOptions.spec
|
|
6677
|
+
if (isVmSpecLike(requestOptions.snapshot)) {
|
|
6678
|
+
if (isVmSpecLike(requestOptions.spec)) {
|
|
6632
6679
|
if (!requestOptions.spec.raw.snapshot) {
|
|
6633
6680
|
requestOptions.spec.raw.snapshot = requestOptions.snapshot;
|
|
6634
6681
|
}
|
|
@@ -6640,7 +6687,7 @@ class VmSnapshotsNamespace {
|
|
|
6640
6687
|
const { snapshot: _snapshot, ...rest } = requestOptions;
|
|
6641
6688
|
requestOptions = rest;
|
|
6642
6689
|
}
|
|
6643
|
-
if (requestOptions.spec
|
|
6690
|
+
if (isVmSpecLike(requestOptions.spec)) {
|
|
6644
6691
|
let spec = requestOptions.spec;
|
|
6645
6692
|
spec = await processSpecTree(spec);
|
|
6646
6693
|
const { snapshot: _snapshotSpec, ...outerSpecOptions } = spec.raw;
|
|
@@ -6655,12 +6702,12 @@ class VmSnapshotsNamespace {
|
|
|
6655
6702
|
const { spec: _spec, ...rest } = requestOptions;
|
|
6656
6703
|
requestOptions = rest;
|
|
6657
6704
|
}
|
|
6658
|
-
if (requestOptions.template
|
|
6705
|
+
if (isVmTemplateLike(requestOptions.template)) {
|
|
6659
6706
|
const processedTemplate = await processTemplateTree(
|
|
6660
6707
|
requestOptions.template
|
|
6661
6708
|
);
|
|
6662
6709
|
requestOptions.template = processedTemplate;
|
|
6663
|
-
if (processedTemplate.raw.template
|
|
6710
|
+
if (isVmTemplateLike(processedTemplate.raw.template)) {
|
|
6664
6711
|
requestOptions.template = await ensureNestedTemplates(
|
|
6665
6712
|
processedTemplate,
|
|
6666
6713
|
this
|
|
@@ -6675,7 +6722,7 @@ class VmSnapshotsNamespace {
|
|
|
6675
6722
|
return this.apiClient.post("/v1/vms/snapshots", {
|
|
6676
6723
|
body: {
|
|
6677
6724
|
...requestOptions,
|
|
6678
|
-
template: requestOptions.template
|
|
6725
|
+
template: isVmTemplateLike(requestOptions.template) ? requestOptions.template.raw : requestOptions.template
|
|
6679
6726
|
}
|
|
6680
6727
|
}).catch((e) => {
|
|
6681
6728
|
enhanceError(e);
|
|
@@ -6717,7 +6764,7 @@ async function processTemplateTree(template) {
|
|
|
6717
6764
|
}
|
|
6718
6765
|
if (builder.configureNestedTemplate) {
|
|
6719
6766
|
let nestedTemplate;
|
|
6720
|
-
if (template.raw.template
|
|
6767
|
+
if (isVmTemplateLike(template.raw.template)) {
|
|
6721
6768
|
nestedTemplate = template.raw.template;
|
|
6722
6769
|
} else {
|
|
6723
6770
|
nestedTemplate = new VmTemplate({});
|
|
@@ -6729,7 +6776,46 @@ async function processTemplateTree(template) {
|
|
|
6729
6776
|
}
|
|
6730
6777
|
}
|
|
6731
6778
|
}
|
|
6732
|
-
if (template.raw.
|
|
6779
|
+
if (template.raw.git) {
|
|
6780
|
+
template.raw.git = normalizeGitOptions(
|
|
6781
|
+
template.raw.git
|
|
6782
|
+
);
|
|
6783
|
+
}
|
|
6784
|
+
if (template.raw.systemd?.services) {
|
|
6785
|
+
const normalizedServices = template.raw.systemd.services.map((service) => ({
|
|
6786
|
+
...service,
|
|
6787
|
+
after: service.after?.map((s) => s.includes(".") ? s : `${s}.service`),
|
|
6788
|
+
requires: service.requires?.map(
|
|
6789
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6790
|
+
),
|
|
6791
|
+
wantedBy: service.wantedBy?.map(
|
|
6792
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6793
|
+
)
|
|
6794
|
+
}));
|
|
6795
|
+
const { services: processedServices, additionalFiles: bashFiles } = processSystemdServices(
|
|
6796
|
+
normalizedServices,
|
|
6797
|
+
template.raw.additionalFiles ?? {}
|
|
6798
|
+
);
|
|
6799
|
+
template.raw.systemd.services = processedServices;
|
|
6800
|
+
template.raw.additionalFiles = bashFiles;
|
|
6801
|
+
}
|
|
6802
|
+
if (template.raw.systemd?.patchedServices) {
|
|
6803
|
+
template.raw.systemd.patchedServices = template.raw.systemd.patchedServices.map(
|
|
6804
|
+
(service) => ({
|
|
6805
|
+
...service,
|
|
6806
|
+
after: service.after?.map(
|
|
6807
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6808
|
+
),
|
|
6809
|
+
requires: service.requires?.map(
|
|
6810
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6811
|
+
),
|
|
6812
|
+
wantedBy: service.wantedBy?.map(
|
|
6813
|
+
(s) => s.includes(".") ? s : `${s}.service`
|
|
6814
|
+
)
|
|
6815
|
+
})
|
|
6816
|
+
);
|
|
6817
|
+
}
|
|
6818
|
+
if (isVmTemplateLike(template.raw.template)) {
|
|
6733
6819
|
template.raw.template = await processTemplateTree(
|
|
6734
6820
|
template.raw.template
|
|
6735
6821
|
);
|
|
@@ -6738,7 +6824,7 @@ async function processTemplateTree(template) {
|
|
|
6738
6824
|
}
|
|
6739
6825
|
async function ensureNestedTemplates(template, snapshots) {
|
|
6740
6826
|
const templates = [template];
|
|
6741
|
-
while (templates.at(-1)?.raw.template
|
|
6827
|
+
while (isVmTemplateLike(templates.at(-1)?.raw.template)) {
|
|
6742
6828
|
const innerTemplate = templates.at(-1).raw.template;
|
|
6743
6829
|
templates.at(-1).raw.template = void 0;
|
|
6744
6830
|
templates.push(innerTemplate);
|
|
@@ -6925,6 +7011,51 @@ async function readFiles(directory) {
|
|
|
6925
7011
|
return files;
|
|
6926
7012
|
}
|
|
6927
7013
|
|
|
7014
|
+
async function debugCreateRequests(freestyle, options = {}) {
|
|
7015
|
+
const requests = [];
|
|
7016
|
+
let snapshotCounter = 0;
|
|
7017
|
+
let vmCounter = 0;
|
|
7018
|
+
const apiClient = freestyle._apiClient;
|
|
7019
|
+
const originalPost = apiClient.post.bind(freestyle._apiClient);
|
|
7020
|
+
const mockPost = (async (path, ...args) => {
|
|
7021
|
+
const rawBody = args[0] && "body" in args[0] ? args[0].body : void 0;
|
|
7022
|
+
const clonedBody = JSON.parse(JSON.stringify(rawBody ?? null));
|
|
7023
|
+
if (path === "/v1/vms/snapshots") {
|
|
7024
|
+
requests.push({
|
|
7025
|
+
path: "/v1/vms/snapshots",
|
|
7026
|
+
body: clonedBody
|
|
7027
|
+
});
|
|
7028
|
+
snapshotCounter += 1;
|
|
7029
|
+
return {
|
|
7030
|
+
snapshotId: `__debug_snapshot_${snapshotCounter}__`
|
|
7031
|
+
};
|
|
7032
|
+
}
|
|
7033
|
+
if (path === "/v1/vms") {
|
|
7034
|
+
requests.push({
|
|
7035
|
+
path: "/v1/vms",
|
|
7036
|
+
body: clonedBody
|
|
7037
|
+
});
|
|
7038
|
+
vmCounter += 1;
|
|
7039
|
+
return {
|
|
7040
|
+
id: `__debug_vm_${vmCounter}__`,
|
|
7041
|
+
domains: [],
|
|
7042
|
+
consoleUrl: "https://debug.local/console"
|
|
7043
|
+
};
|
|
7044
|
+
}
|
|
7045
|
+
return originalPost(
|
|
7046
|
+
path,
|
|
7047
|
+
...args
|
|
7048
|
+
);
|
|
7049
|
+
});
|
|
7050
|
+
apiClient.post = mockPost;
|
|
7051
|
+
try {
|
|
7052
|
+
await freestyle.vms.create(options);
|
|
7053
|
+
} finally {
|
|
7054
|
+
apiClient.post = originalPost;
|
|
7055
|
+
}
|
|
7056
|
+
return requests;
|
|
7057
|
+
}
|
|
7058
|
+
|
|
6928
7059
|
class Freestyle {
|
|
6929
7060
|
/**
|
|
6930
7061
|
* @internal
|
|
@@ -6994,4 +7125,4 @@ function createLazyFreestyle(options = {}) {
|
|
|
6994
7125
|
}
|
|
6995
7126
|
const freestyle = createLazyFreestyle();
|
|
6996
7127
|
|
|
6997
|
-
export { CronNamespace, Deployment, errors as Errors, FileSystem, Freestyle, GitRepo, Identity, Systemd, SystemdService, Vm, VmBuilder, VmService, VmSpec, VmTemplate, VmWith, VmWithInstance, freestyle, readFiles };
|
|
7128
|
+
export { CronNamespace, Deployment, errors as Errors, FileSystem, Freestyle, GitRepo, Identity, Systemd, SystemdService, Vm, VmBuilder, VmService, VmSpec, VmTemplate, VmWith, VmWithInstance, debugCreateRequests, freestyle, readFiles };
|