@flightctl/ui-components 1.1.0-rc1 → 1.1.0-rc2
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/dist/src/components/Repository/CreateRepository/CreateRepositoryForm.css +5 -1
- package/dist/types/imagebuilder/index.d.ts +1 -0
- package/dist/types/imagebuilder/index.d.ts.map +1 -1
- package/dist/types/imagebuilder/models/Status.d.ts +30 -0
- package/dist/types/imagebuilder/models/Status.d.ts.map +1 -0
- package/dist/types/imagebuilder/models/Status.js +3 -0
- package/dist/types/imagebuilder/models/Status.js.map +1 -0
- package/dist/types/index.d.ts +7 -0
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/index.js.map +1 -1
- package/dist/types/models/ApplicationProviderBase.d.ts +12 -0
- package/dist/types/models/ApplicationProviderBase.d.ts.map +1 -0
- package/dist/types/models/ApplicationProviderBase.js +3 -0
- package/dist/types/models/ApplicationProviderBase.js.map +1 -0
- package/dist/types/models/ApplicationProviderSpec.d.ts +5 -15
- package/dist/types/models/ApplicationProviderSpec.d.ts.map +1 -1
- package/dist/types/models/ApplicationUser.d.ts +7 -0
- package/dist/types/models/ApplicationUser.d.ts.map +1 -0
- package/dist/types/models/ApplicationUser.js +3 -0
- package/dist/types/models/ApplicationUser.js.map +1 -0
- package/dist/types/models/ComposeApplication.d.ts +7 -0
- package/dist/types/models/ComposeApplication.d.ts.map +1 -0
- package/dist/types/models/ComposeApplication.js +3 -0
- package/dist/types/models/ComposeApplication.js.map +1 -0
- package/dist/types/models/ContainerApplication.d.ts +18 -0
- package/dist/types/models/ContainerApplication.d.ts.map +1 -0
- package/dist/types/models/ContainerApplication.js +3 -0
- package/dist/types/models/ContainerApplication.js.map +1 -0
- package/dist/types/models/ContainerApplicationProperties.d.ts +13 -0
- package/dist/types/models/ContainerApplicationProperties.d.ts.map +1 -0
- package/dist/types/models/ContainerApplicationProperties.js +3 -0
- package/dist/types/models/ContainerApplicationProperties.js.map +1 -0
- package/dist/types/models/HelmApplication.d.ts +20 -0
- package/dist/types/models/HelmApplication.d.ts.map +1 -0
- package/dist/types/models/HelmApplication.js +3 -0
- package/dist/types/models/HelmApplication.js.map +1 -0
- package/dist/types/models/ImageApplicationProviderSpec.d.ts +2 -22
- package/dist/types/models/ImageApplicationProviderSpec.d.ts.map +1 -1
- package/dist/types/models/InlineApplicationProviderSpec.d.ts +2 -3
- package/dist/types/models/InlineApplicationProviderSpec.d.ts.map +1 -1
- package/dist/types/models/QuadletApplication.d.ts +8 -0
- package/dist/types/models/QuadletApplication.d.ts.map +1 -0
- package/dist/types/models/QuadletApplication.js +3 -0
- package/dist/types/models/QuadletApplication.js.map +1 -0
- package/dist/ui-components/src/components/AuthProvider/CreateAuthProvider/utils.js +1 -1
- package/dist/ui-components/src/components/AuthProvider/CreateAuthProvider/utils.js.map +1 -1
- package/dist/ui-components/src/components/DetailsPage/Tables/ApplicationsTable.js +1 -1
- package/dist/ui-components/src/components/DetailsPage/Tables/ApplicationsTable.js.map +1 -1
- package/dist/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.js +5 -4
- package/dist/ui-components/src/components/Device/DeviceDetails/DeviceDetailsPage.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.d.ts +3 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.js +308 -363
- package/dist/ui-components/src/components/Device/EditDeviceWizard/deviceSpecUtils.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.js +18 -19
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.js +4 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.js +2 -2
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.d.ts +3 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.js +20 -23
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationIntegritySettings.js +3 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationIntegritySettings.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.js +25 -45
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.d.ts +8 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.d.ts.map +1 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.js +37 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.js.map +1 -0
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.d.ts +1 -3
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.js +5 -8
- package/dist/ui-components/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.js.map +1 -1
- package/dist/ui-components/src/components/Device/EditDeviceWizard/utils.d.ts +18 -18
- package/dist/ui-components/src/components/Fleet/CreateFleet/utils.js +2 -2
- package/dist/ui-components/src/components/Fleet/CreateFleet/utils.js.map +1 -1
- package/dist/ui-components/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.d.ts.map +1 -1
- package/dist/ui-components/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.js +3 -1
- package/dist/ui-components/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.d.ts +7 -0
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.d.ts.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.js +40 -0
- package/dist/ui-components/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.js.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.d.ts +8 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.d.ts.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.js +30 -0
- package/dist/ui-components/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.js.map +1 -0
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/utils.js +2 -2
- package/dist/ui-components/src/components/ImageBuilds/CreateImageBuildWizard/utils.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.js +22 -11
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.js +103 -36
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.d.ts +5 -2
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.js +22 -12
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildRow.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildsPage.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildsPage.js +17 -8
- package/dist/ui-components/src/components/ImageBuilds/ImageBuildsPage.js.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.d.ts +10 -9
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.d.ts.map +1 -1
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.js +109 -25
- package/dist/ui-components/src/components/ImageBuilds/ImageExportCards.js.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.d.ts.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.js +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/CreateRepositoryForm.js.map +1 -1
- package/dist/ui-components/src/components/Repository/CreateRepository/utils.js +3 -3
- package/dist/ui-components/src/components/Repository/CreateRepository/utils.js.map +1 -1
- package/dist/ui-components/src/components/form/validations.d.ts +20 -18
- package/dist/ui-components/src/components/form/validations.d.ts.map +1 -1
- package/dist/ui-components/src/components/form/validations.js +40 -11
- package/dist/ui-components/src/components/form/validations.js.map +1 -1
- package/dist/ui-components/src/constants.d.ts +7 -6
- package/dist/ui-components/src/constants.d.ts.map +1 -1
- package/dist/ui-components/src/constants.js +19 -11
- package/dist/ui-components/src/constants.js.map +1 -1
- package/dist/ui-components/src/types/deviceSpec.d.ts +44 -76
- package/dist/ui-components/src/types/deviceSpec.d.ts.map +1 -1
- package/dist/ui-components/src/types/deviceSpec.js +13 -26
- package/dist/ui-components/src/types/deviceSpec.js.map +1 -1
- package/dist/ui-components/src/types/extraTypes.d.ts +1 -7
- package/dist/ui-components/src/types/extraTypes.d.ts.map +1 -1
- package/dist/ui-components/src/types/extraTypes.js.map +1 -1
- package/dist/ui-components/src/types/rbac.d.ts +7 -1
- package/dist/ui-components/src/types/rbac.d.ts.map +1 -1
- package/dist/ui-components/src/types/rbac.js +6 -0
- package/dist/ui-components/src/types/rbac.js.map +1 -1
- package/dist/ui-components/src/utils/imageBuilds.d.ts +1 -0
- package/dist/ui-components/src/utils/imageBuilds.d.ts.map +1 -1
- package/dist/ui-components/src/utils/imageBuilds.js +7 -1
- package/dist/ui-components/src/utils/imageBuilds.js.map +1 -1
- package/dist/ui-components/src/utils/search.js +1 -1
- package/dist/ui-components/src/utils/search.js.map +1 -1
- package/package.json +1 -1
- package/src/components/AuthProvider/CreateAuthProvider/utils.ts +2 -2
- package/src/components/DetailsPage/Tables/ApplicationsTable.tsx +2 -2
- package/src/components/Device/DeviceDetails/DeviceDetailsPage.tsx +10 -4
- package/src/components/Device/EditDeviceWizard/deviceSpecUtils.ts +359 -425
- package/src/components/Device/EditDeviceWizard/steps/ApplicationContainerForm.tsx +19 -29
- package/src/components/Device/EditDeviceWizard/steps/ApplicationHelmForm.tsx +4 -12
- package/src/components/Device/EditDeviceWizard/steps/ApplicationImageForm.tsx +2 -16
- package/src/components/Device/EditDeviceWizard/steps/ApplicationInlineForm.tsx +8 -7
- package/src/components/Device/EditDeviceWizard/steps/ApplicationIntegritySettings.tsx +5 -5
- package/src/components/Device/EditDeviceWizard/steps/ApplicationTemplates.tsx +29 -101
- package/src/components/Device/EditDeviceWizard/steps/ApplicationVariablesForm.tsx +87 -0
- package/src/components/Device/EditDeviceWizard/steps/ApplicationVolumeForm.tsx +5 -10
- package/src/components/Fleet/CreateFleet/utils.ts +4 -4
- package/src/components/Fleet/ImportFleetWizard/steps/RepositoryStep.tsx +11 -8
- package/src/components/ImageBuilds/CancelImageBuildModal/CancelImageBuildModal.tsx +81 -0
- package/src/components/ImageBuilds/ConfirmImageExportModal/ConfirmImageExportModal.tsx +48 -0
- package/src/components/ImageBuilds/CreateImageBuildWizard/utils.ts +3 -3
- package/src/components/ImageBuilds/ImageBuildDetails/ImageBuildDetailsPage.tsx +35 -16
- package/src/components/ImageBuilds/ImageBuildDetails/ImageBuildExportsGallery.tsx +120 -42
- package/src/components/ImageBuilds/ImageBuildRow.tsx +41 -20
- package/src/components/ImageBuilds/ImageBuildsPage.tsx +34 -15
- package/src/components/ImageBuilds/ImageExportCards.tsx +176 -77
- package/src/components/Repository/CreateRepository/CreateRepositoryForm.css +5 -1
- package/src/components/Repository/CreateRepository/CreateRepositoryForm.tsx +1 -0
- package/src/components/Repository/CreateRepository/utils.ts +4 -4
- package/src/components/form/validations.ts +112 -82
- package/src/constants.ts +19 -6
- package/src/types/deviceSpec.ts +68 -108
- package/src/types/extraTypes.ts +2 -12
- package/src/types/rbac.ts +6 -0
- package/src/utils/imageBuilds.ts +8 -0
- package/src/utils/search.ts +2 -2
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.hasMicroshiftRegistrationConfig = exports.MicroshiftRegistrationHook = exports.ACMImportConfig = exports.ACMCrdConfig = exports.formatFileMode = exports.getConfigTemplatesValues = exports.getSystemdUnitsValues = exports.getApplicationValues = exports.createInitialAppForm = exports.getApiConfig = exports.getApplicationPatches = exports.
|
|
3
|
+
exports.hasMicroshiftRegistrationConfig = exports.MicroshiftRegistrationHook = exports.ACMImportConfig = exports.ACMCrdConfig = exports.formatFileMode = exports.getConfigTemplatesValues = exports.getSystemdUnitsValues = exports.getApplicationValues = exports.createInitialAppForm = exports.getApiConfig = exports.getApplicationPatches = exports.toApiApplication = exports.getDeviceSpecConfigPatches = exports.getConfigType = exports.ACM_REPO_NAME = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
const js_yaml_1 = tslib_1.__importDefault(require("js-yaml"));
|
|
6
6
|
const types_1 = require("@flightctl/types");
|
|
@@ -150,308 +150,314 @@ const getDeviceSpecConfigPatches = (currentConfigs, newConfigs, configPath) => {
|
|
|
150
150
|
return allPatches;
|
|
151
151
|
};
|
|
152
152
|
exports.getDeviceSpecConfigPatches = getDeviceSpecConfigPatches;
|
|
153
|
-
const
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
if (app.namespace) {
|
|
162
|
-
data.namespace = app.namespace;
|
|
163
|
-
}
|
|
164
|
-
if (app.valuesYaml) {
|
|
165
|
-
try {
|
|
166
|
-
const values = js_yaml_1.default.load(app.valuesYaml);
|
|
167
|
-
if (values && Object.keys(values).length > 0) {
|
|
168
|
-
data.values = values;
|
|
169
|
-
}
|
|
170
|
-
}
|
|
171
|
-
catch (error) {
|
|
172
|
-
throw new Error('Values content is not valid YAML.');
|
|
173
|
-
}
|
|
174
|
-
}
|
|
175
|
-
const fileNames = app.valuesFiles.filter((file) => file && file.trim() !== '');
|
|
176
|
-
if (fileNames.length > 0) {
|
|
177
|
-
data.valuesFiles = fileNames;
|
|
178
|
-
}
|
|
179
|
-
return data;
|
|
180
|
-
}
|
|
181
|
-
const envVars = app.variables.reduce((acc, variable) => {
|
|
182
|
-
acc[variable.name] = variable.value;
|
|
183
|
-
return acc;
|
|
184
|
-
}, {});
|
|
185
|
-
const volumes = (_a = app.volumes) === null || _a === void 0 ? void 0 : _a.map((v) => {
|
|
186
|
-
const volume = {
|
|
187
|
-
name: v.name || '',
|
|
188
|
-
};
|
|
189
|
-
if (v.imageRef) {
|
|
190
|
-
volume.image = {
|
|
191
|
-
reference: v.imageRef,
|
|
192
|
-
pullPolicy: v.imagePullPolicy || types_1.ImagePullPolicy.PullIfNotPresent,
|
|
193
|
-
};
|
|
194
|
-
}
|
|
195
|
-
if (v.mountPath) {
|
|
196
|
-
volume.mount = {
|
|
197
|
-
path: v.mountPath,
|
|
198
|
-
};
|
|
199
|
-
}
|
|
200
|
-
return volume;
|
|
153
|
+
const haveInlineFilesChanged = (current, updated) => {
|
|
154
|
+
if (current.length !== updated.length)
|
|
155
|
+
return true;
|
|
156
|
+
return current.some((file, index) => {
|
|
157
|
+
const other = updated[index];
|
|
158
|
+
const aBase64 = file.contentEncoding === types_1.EncodingType.EncodingBase64;
|
|
159
|
+
const bBase64 = other.contentEncoding === types_1.EncodingType.EncodingBase64;
|
|
160
|
+
return (aBase64 !== bBase64 || (file.path || '') !== (other.path || '') || (file.content || '') !== (other.content || ''));
|
|
201
161
|
});
|
|
202
|
-
if ((0, deviceSpec_1.isSingleContainerAppForm)(app)) {
|
|
203
|
-
const data = {
|
|
204
|
-
image: app.image,
|
|
205
|
-
appType: app.appType,
|
|
206
|
-
envVars,
|
|
207
|
-
volumes,
|
|
208
|
-
};
|
|
209
|
-
if (app.name) {
|
|
210
|
-
data.name = app.name;
|
|
211
|
-
}
|
|
212
|
-
if (app.ports) {
|
|
213
|
-
data.ports = app.ports.map((p) => `${p.hostPort}:${p.containerPort}`);
|
|
214
|
-
}
|
|
215
|
-
// Removed fields must not appear in the resources object
|
|
216
|
-
const appLimits = {};
|
|
217
|
-
if ((_b = app.limits) === null || _b === void 0 ? void 0 : _b.cpu) {
|
|
218
|
-
appLimits.cpu = app.limits.cpu;
|
|
219
|
-
}
|
|
220
|
-
if ((_c = app.limits) === null || _c === void 0 ? void 0 : _c.memory) {
|
|
221
|
-
appLimits.memory = app.limits.memory;
|
|
222
|
-
}
|
|
223
|
-
if (Object.keys(appLimits).length > 0) {
|
|
224
|
-
data.resources = {
|
|
225
|
-
limits: appLimits,
|
|
226
|
-
};
|
|
227
|
-
}
|
|
228
|
-
data.runAs = app.runAs || deviceSpec_1.RUN_AS_DEFAULT_USER;
|
|
229
|
-
return data;
|
|
230
|
-
}
|
|
231
|
-
if ((0, deviceSpec_1.isQuadletImageAppForm)(app) || (0, deviceSpec_1.isComposeImageAppForm)(app)) {
|
|
232
|
-
const data = {
|
|
233
|
-
image: app.image,
|
|
234
|
-
appType: app.appType,
|
|
235
|
-
envVars,
|
|
236
|
-
volumes,
|
|
237
|
-
};
|
|
238
|
-
if (app.name) {
|
|
239
|
-
data.name = app.name;
|
|
240
|
-
}
|
|
241
|
-
if ((0, deviceSpec_1.isQuadletImageAppForm)(app) && app.runAs) {
|
|
242
|
-
data.runAs = app.runAs;
|
|
243
|
-
}
|
|
244
|
-
return data;
|
|
245
|
-
}
|
|
246
|
-
// Inline applications (Quadlet or Compose)
|
|
247
|
-
const inlineData = {
|
|
248
|
-
name: app.name,
|
|
249
|
-
appType: app.appType,
|
|
250
|
-
inline: toAPIFiles(app.files),
|
|
251
|
-
envVars,
|
|
252
|
-
volumes,
|
|
253
|
-
};
|
|
254
|
-
if ((0, deviceSpec_1.isQuadletInlineAppForm)(app) && app.runAs) {
|
|
255
|
-
inlineData.runAs = app.runAs;
|
|
256
|
-
}
|
|
257
|
-
return inlineData;
|
|
258
162
|
};
|
|
259
|
-
|
|
260
|
-
const
|
|
261
|
-
|
|
163
|
+
const haveEnvVarsChanged = (current, updated) => {
|
|
164
|
+
const aKeys = Object.keys(current);
|
|
165
|
+
const bKeys = Object.keys(updated);
|
|
166
|
+
if (aKeys.length !== bKeys.length)
|
|
262
167
|
return true;
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
return ((updatedFile.base64 || false) !== isCurrentBase64 ||
|
|
268
|
-
updatedFile.path !== file.path ||
|
|
269
|
-
updatedFile.content !== file.content);
|
|
270
|
-
});
|
|
271
|
-
if (filesChanged) {
|
|
168
|
+
return aKeys.some((key) => current[key] !== updated[key]);
|
|
169
|
+
};
|
|
170
|
+
const haveVolumesChanged = (current, updated) => {
|
|
171
|
+
if (current.length !== updated.length)
|
|
272
172
|
return true;
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
173
|
+
return current.some((currentVol, index) => {
|
|
174
|
+
var _a, _b, _c, _d, _e, _f;
|
|
175
|
+
const updatedVol = updated[index];
|
|
176
|
+
if (currentVol.name !== updatedVol.name)
|
|
177
|
+
return true;
|
|
178
|
+
if ((currentVol.reclaimPolicy || types_1.ApplicationVolumeReclaimPolicy.RETAIN) !==
|
|
179
|
+
(updatedVol.reclaimPolicy || types_1.ApplicationVolumeReclaimPolicy.RETAIN))
|
|
180
|
+
return true;
|
|
181
|
+
const currentFull = currentVol;
|
|
182
|
+
const updatedFull = updatedVol;
|
|
183
|
+
const currentImageRef = ((_a = currentFull.image) === null || _a === void 0 ? void 0 : _a.reference) || '';
|
|
184
|
+
const updatedImageRef = ((_b = updatedFull.image) === null || _b === void 0 ? void 0 : _b.reference) || '';
|
|
185
|
+
if (currentImageRef !== updatedImageRef)
|
|
278
186
|
return true;
|
|
279
|
-
}
|
|
280
|
-
}
|
|
281
|
-
return !areVolumesEqual(currentApp.volumes || [], updatedApp.volumes || []);
|
|
282
|
-
};
|
|
283
|
-
const areVolumesEqual = (currentVolumes, updatedFormVolumes) => {
|
|
284
|
-
if (currentVolumes.length !== updatedFormVolumes.length) {
|
|
285
|
-
return false;
|
|
286
|
-
}
|
|
287
|
-
return currentVolumes.every((currentVol, index) => {
|
|
288
|
-
var _a, _b, _c;
|
|
289
|
-
const updatedFormVol = updatedFormVolumes[index];
|
|
290
|
-
const currentFullVol = currentVol;
|
|
291
|
-
if (currentFullVol.name !== updatedFormVol.name) {
|
|
292
|
-
return false;
|
|
293
|
-
}
|
|
294
|
-
const currentImageRef = ((_a = currentFullVol.image) === null || _a === void 0 ? void 0 : _a.reference) || '';
|
|
295
|
-
const updatedImageRef = (updatedFormVol === null || updatedFormVol === void 0 ? void 0 : updatedFormVol.imageRef) || '';
|
|
296
|
-
if (currentImageRef !== updatedImageRef) {
|
|
297
|
-
return false;
|
|
298
|
-
}
|
|
299
187
|
if (currentImageRef || updatedImageRef) {
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
return false;
|
|
304
|
-
}
|
|
305
|
-
}
|
|
306
|
-
const currentMountPath = ((_c = currentFullVol.mount) === null || _c === void 0 ? void 0 : _c.path) || '';
|
|
307
|
-
const updatedMountPath = (updatedFormVol === null || updatedFormVol === void 0 ? void 0 : updatedFormVol.mountPath) || '';
|
|
308
|
-
if (currentMountPath !== updatedMountPath) {
|
|
309
|
-
return false;
|
|
188
|
+
if ((((_c = currentFull.image) === null || _c === void 0 ? void 0 : _c.pullPolicy) || types_1.ImagePullPolicy.PullIfNotPresent) !==
|
|
189
|
+
(((_d = updatedFull.image) === null || _d === void 0 ? void 0 : _d.pullPolicy) || types_1.ImagePullPolicy.PullIfNotPresent))
|
|
190
|
+
return true;
|
|
310
191
|
}
|
|
311
|
-
return
|
|
192
|
+
return (((_e = currentFull.mount) === null || _e === void 0 ? void 0 : _e.path) || '') !== (((_f = updatedFull.mount) === null || _f === void 0 ? void 0 : _f.path) || '');
|
|
312
193
|
});
|
|
313
194
|
};
|
|
314
|
-
const
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
return currentPorts.every((currentPort, index) => {
|
|
320
|
-
const updatedPort = updatedPorts[index];
|
|
321
|
-
return currentPort === `${updatedPort.hostPort}:${updatedPort.containerPort}`;
|
|
322
|
-
});
|
|
195
|
+
const hasStringChanged = (current, updated, defaultValue = '') => (current || defaultValue) !== (updated || defaultValue);
|
|
196
|
+
const havePortsChanged = (current, updated) => {
|
|
197
|
+
if (current.length !== updated.length)
|
|
198
|
+
return true;
|
|
199
|
+
return current.some((port, index) => port !== updated[index]);
|
|
323
200
|
};
|
|
324
|
-
const
|
|
325
|
-
|
|
326
|
-
const updatedCpu = (updatedLimits === null || updatedLimits === void 0 ? void 0 : updatedLimits.cpu) || '';
|
|
327
|
-
const currentMemory = (currentLimits === null || currentLimits === void 0 ? void 0 : currentLimits.memory) || '';
|
|
328
|
-
const updatedMemory = (updatedLimits === null || updatedLimits === void 0 ? void 0 : updatedLimits.memory) || '';
|
|
329
|
-
return currentCpu === updatedCpu && currentMemory === updatedMemory;
|
|
201
|
+
const haveResourceLimitsChanged = (current, updated) => {
|
|
202
|
+
return ((current === null || current === void 0 ? void 0 : current.cpu) || '') !== ((updated === null || updated === void 0 ? void 0 : updated.cpu) || '') || ((current === null || current === void 0 ? void 0 : current.memory) || '') !== ((updated === null || updated === void 0 ? void 0 : updated.memory) || '');
|
|
330
203
|
};
|
|
331
|
-
const
|
|
332
|
-
const
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
return
|
|
337
|
-
// Envvars may have "falsy" values (eg. number 0) when they are defined
|
|
338
|
-
return variable.name in envVars && envVars[variable.name] === variable.value;
|
|
339
|
-
});
|
|
204
|
+
const haveValuesFilesChanged = (current, updated) => {
|
|
205
|
+
const a = current.filter((f) => f.trim() !== '');
|
|
206
|
+
const b = updated.filter((f) => f.trim() !== '');
|
|
207
|
+
if (a.length !== b.length)
|
|
208
|
+
return true;
|
|
209
|
+
return a.some((file, i) => file !== b[i]);
|
|
340
210
|
};
|
|
341
|
-
const
|
|
342
|
-
|
|
343
|
-
if (!
|
|
211
|
+
const haveHelmValuesChanged = (current, updated) => JSON.stringify(current) !== JSON.stringify(updated);
|
|
212
|
+
const hasRunAsChanged = (current, updated) => {
|
|
213
|
+
if (!current) {
|
|
214
|
+
// For empty "runAs", we mark the app as changed.
|
|
215
|
+
// This means that we'll set the field explicitly to the default user (currently "root").
|
|
344
216
|
return true;
|
|
345
217
|
}
|
|
346
|
-
|
|
347
|
-
|
|
218
|
+
return current !== updated;
|
|
219
|
+
};
|
|
220
|
+
// Single container apps always have an image, and it doesn't have an inline variant
|
|
221
|
+
const hasContainerAppChanged = (current, updated) => {
|
|
222
|
+
var _a, _b;
|
|
223
|
+
return hasStringChanged(current.name, updated.name) ||
|
|
224
|
+
hasStringChanged(current.image, updated.image) ||
|
|
225
|
+
havePortsChanged(current.ports || [], updated.ports || []) ||
|
|
226
|
+
haveResourceLimitsChanged((_a = current.resources) === null || _a === void 0 ? void 0 : _a.limits, (_b = updated.resources) === null || _b === void 0 ? void 0 : _b.limits) ||
|
|
227
|
+
haveEnvVarsChanged(current.envVars || {}, updated.envVars || {}) ||
|
|
228
|
+
hasRunAsChanged(current.runAs, updated.runAs) ||
|
|
229
|
+
haveVolumesChanged(current.volumes || [], updated.volumes || []);
|
|
230
|
+
};
|
|
231
|
+
// Helm apps always have an image (chart), and it doesn't have an inline variant
|
|
232
|
+
const hasHelmAppChanged = (current, updated) => hasStringChanged(current.name, updated.name) ||
|
|
233
|
+
hasStringChanged(current.image, updated.image) ||
|
|
234
|
+
hasStringChanged(current.namespace, updated.namespace) ||
|
|
235
|
+
haveValuesFilesChanged(current.valuesFiles || [], updated.valuesFiles || []) ||
|
|
236
|
+
haveHelmValuesChanged(current.values || {}, updated.values || {});
|
|
237
|
+
const hasComposeAppChanged = (current, updated, specType) => {
|
|
238
|
+
const baseChanged = hasStringChanged(current.name, updated.name) ||
|
|
239
|
+
haveEnvVarsChanged(current.envVars || {}, updated.envVars || {}) ||
|
|
240
|
+
haveVolumesChanged(current.volumes || [], updated.volumes || []);
|
|
241
|
+
if (baseChanged) {
|
|
348
242
|
return true;
|
|
349
243
|
}
|
|
350
|
-
if (
|
|
351
|
-
return
|
|
244
|
+
if (specType === deviceSpec_1.AppSpecType.OCI_IMAGE) {
|
|
245
|
+
return hasStringChanged(current.image, updated.image);
|
|
352
246
|
}
|
|
353
|
-
|
|
247
|
+
return haveInlineFilesChanged(current.inline, updated.inline);
|
|
248
|
+
};
|
|
249
|
+
// Quadlet apps are currently the same as Compose apps, plus an optional "runAs" field.
|
|
250
|
+
const hasQuadletAppChanged = (current, updated, specType) => {
|
|
251
|
+
const baseChanged = hasComposeAppChanged(current, updated, specType);
|
|
252
|
+
if (baseChanged) {
|
|
354
253
|
return true;
|
|
355
254
|
}
|
|
356
|
-
|
|
255
|
+
return hasRunAsChanged(current.runAs, updated.runAs);
|
|
256
|
+
};
|
|
257
|
+
const hasApplicationChanged = (current, updated) => {
|
|
258
|
+
if (current.appType !== updated.appType) {
|
|
357
259
|
return true;
|
|
358
260
|
}
|
|
359
|
-
|
|
261
|
+
const currentSpectType = (0, deviceSpec_1.isImageVariantApp)(current) ? deviceSpec_1.AppSpecType.OCI_IMAGE : deviceSpec_1.AppSpecType.INLINE;
|
|
262
|
+
const updatedSpectType = (0, deviceSpec_1.isImageVariantApp)(updated) ? deviceSpec_1.AppSpecType.OCI_IMAGE : deviceSpec_1.AppSpecType.INLINE;
|
|
263
|
+
if (currentSpectType !== updatedSpectType) {
|
|
360
264
|
return true;
|
|
361
265
|
}
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
return true;
|
|
266
|
+
switch (current.appType) {
|
|
267
|
+
case types_1.AppType.AppTypeContainer:
|
|
268
|
+
return hasContainerAppChanged(current, updated);
|
|
269
|
+
case types_1.AppType.AppTypeHelm:
|
|
270
|
+
return hasHelmAppChanged(current, updated);
|
|
271
|
+
case types_1.AppType.AppTypeQuadlet:
|
|
272
|
+
return hasQuadletAppChanged(current, updated, currentSpectType);
|
|
273
|
+
case types_1.AppType.AppTypeCompose:
|
|
274
|
+
return hasComposeAppChanged(current, updated, currentSpectType);
|
|
372
275
|
}
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
276
|
+
};
|
|
277
|
+
const variablesToEnvVars = (variables) => {
|
|
278
|
+
if (variables.length === 0) {
|
|
279
|
+
return undefined;
|
|
376
280
|
}
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
if (imageApp.image !== updatedApp.image || imageApp.namespace !== updatedApp.namespace) {
|
|
381
|
-
return true;
|
|
281
|
+
return variables.reduce((acc, v) => {
|
|
282
|
+
if (v.name) {
|
|
283
|
+
acc[v.name] = v.value || '';
|
|
382
284
|
}
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
285
|
+
return acc;
|
|
286
|
+
}, {});
|
|
287
|
+
};
|
|
288
|
+
/**
|
|
289
|
+
* Converts form volumes to API volumes, ignoring fields that are not allowed for the given app type.
|
|
290
|
+
* Quadlet/Compose apps --> can only be image volumes (mount is not allowed)
|
|
291
|
+
* Container apps --> can either be mount or image mount volumes
|
|
292
|
+
*/
|
|
293
|
+
const formVolumesToApi = (volumes, appType) => {
|
|
294
|
+
return volumes.map((v) => {
|
|
295
|
+
const vol = {
|
|
296
|
+
name: v.name || '',
|
|
297
|
+
};
|
|
298
|
+
if (v.imageRef) {
|
|
299
|
+
vol.image = {
|
|
300
|
+
reference: v.imageRef,
|
|
301
|
+
pullPolicy: v.imagePullPolicy || types_1.ImagePullPolicy.PullIfNotPresent,
|
|
302
|
+
};
|
|
388
303
|
}
|
|
389
|
-
if (
|
|
390
|
-
|
|
304
|
+
if (v.mountPath && appType === types_1.AppType.AppTypeContainer) {
|
|
305
|
+
vol.mount = { path: v.mountPath };
|
|
391
306
|
}
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
307
|
+
return vol;
|
|
308
|
+
});
|
|
309
|
+
};
|
|
310
|
+
const formFilesToApi = (files) => files.map((f) => ({
|
|
311
|
+
path: f.path,
|
|
312
|
+
content: f.content || '',
|
|
313
|
+
contentEncoding: f.base64 ? types_1.EncodingType.EncodingBase64 : types_1.EncodingType.EncodingPlain,
|
|
314
|
+
}));
|
|
315
|
+
const toFormFiles = (files) => files.map((file) => ({
|
|
316
|
+
path: file.path || '',
|
|
317
|
+
content: file.content || '',
|
|
318
|
+
base64: file.contentEncoding === types_1.EncodingType.EncodingBase64,
|
|
319
|
+
}));
|
|
320
|
+
const toApiHelmApp = (app) => {
|
|
321
|
+
const helmApp = {
|
|
322
|
+
name: app.name,
|
|
323
|
+
image: app.image,
|
|
324
|
+
appType: app.appType,
|
|
325
|
+
};
|
|
326
|
+
if (app.namespace) {
|
|
327
|
+
helmApp.namespace = app.namespace;
|
|
328
|
+
}
|
|
329
|
+
if (app.valuesYaml) {
|
|
330
|
+
try {
|
|
331
|
+
const values = js_yaml_1.default.load(app.valuesYaml);
|
|
332
|
+
if (values && Object.keys(values).length > 0)
|
|
333
|
+
helmApp.values = values;
|
|
334
|
+
}
|
|
335
|
+
catch (_a) {
|
|
336
|
+
// leave values unset on invalid YAML
|
|
395
337
|
}
|
|
396
|
-
return false;
|
|
397
338
|
}
|
|
398
|
-
|
|
399
|
-
|
|
339
|
+
const fileNames = (app.valuesFiles || []).filter((f) => f.trim() !== '');
|
|
340
|
+
if (fileNames.length > 0) {
|
|
341
|
+
helmApp.valuesFiles = fileNames;
|
|
400
342
|
}
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
343
|
+
return helmApp;
|
|
344
|
+
};
|
|
345
|
+
const toApiContainerApp = (app) => {
|
|
346
|
+
const containerApp = {
|
|
347
|
+
image: app.image,
|
|
348
|
+
appType: app.appType,
|
|
349
|
+
runAs: app.runAs || deviceSpec_1.RUN_AS_ROOT_USER,
|
|
350
|
+
envVars: variablesToEnvVars(app.variables || []),
|
|
351
|
+
volumes: formVolumesToApi(app.volumes || [], types_1.AppType.AppTypeContainer),
|
|
352
|
+
};
|
|
353
|
+
if (app.name) {
|
|
354
|
+
containerApp.name = app.name;
|
|
355
|
+
}
|
|
356
|
+
if (app.ports.length > 0) {
|
|
357
|
+
containerApp.ports = app.ports.map((p) => `${p.hostPort}:${p.containerPort}`);
|
|
358
|
+
}
|
|
359
|
+
const cpu = app.cpuLimit;
|
|
360
|
+
const memory = app.memoryLimit;
|
|
361
|
+
if (cpu || memory) {
|
|
362
|
+
const limits = {};
|
|
363
|
+
if (cpu) {
|
|
364
|
+
limits.cpu = cpu;
|
|
407
365
|
}
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
if ((currentApp.runAs || deviceSpec_1.RUN_AS_DEFAULT_USER) !== (updatedApp.runAs || deviceSpec_1.RUN_AS_DEFAULT_USER)) {
|
|
411
|
-
return true;
|
|
412
|
-
}
|
|
366
|
+
if (memory) {
|
|
367
|
+
limits.memory = memory;
|
|
413
368
|
}
|
|
414
|
-
|
|
369
|
+
containerApp.resources = { limits };
|
|
370
|
+
}
|
|
371
|
+
return containerApp;
|
|
372
|
+
};
|
|
373
|
+
const toApiComposeApp = (app) => {
|
|
374
|
+
const formApp = {
|
|
375
|
+
appType: app.appType,
|
|
376
|
+
envVars: variablesToEnvVars(app.variables || []),
|
|
377
|
+
volumes: formVolumesToApi(app.volumes || [], app.appType),
|
|
378
|
+
};
|
|
379
|
+
if (app.name) {
|
|
380
|
+
formApp.name = app.name;
|
|
381
|
+
}
|
|
382
|
+
if (app.specType === deviceSpec_1.AppSpecType.OCI_IMAGE) {
|
|
383
|
+
formApp.image = app.image;
|
|
384
|
+
}
|
|
385
|
+
else {
|
|
386
|
+
formApp.inline = formFilesToApi(app.files);
|
|
387
|
+
}
|
|
388
|
+
return formApp;
|
|
389
|
+
};
|
|
390
|
+
// Quadlet apps are currently the same as Compose apps, plus an optional "runAs" field.
|
|
391
|
+
const toApiQuadletApp = (app) => {
|
|
392
|
+
const baseApp = toApiComposeApp(app);
|
|
393
|
+
return Object.assign(Object.assign({}, baseApp), { appType: types_1.AppType.AppTypeQuadlet, runAs: app.runAs || deviceSpec_1.RUN_AS_ROOT_USER });
|
|
394
|
+
};
|
|
395
|
+
const toApiApplication = (app) => {
|
|
396
|
+
switch (app.appType) {
|
|
397
|
+
case types_1.AppType.AppTypeHelm:
|
|
398
|
+
return toApiHelmApp(app);
|
|
399
|
+
case types_1.AppType.AppTypeContainer:
|
|
400
|
+
return toApiContainerApp(app);
|
|
401
|
+
case types_1.AppType.AppTypeQuadlet:
|
|
402
|
+
return toApiQuadletApp(app);
|
|
403
|
+
case types_1.AppType.AppTypeCompose:
|
|
404
|
+
return toApiComposeApp(app);
|
|
405
|
+
default:
|
|
406
|
+
throw new Error('Unknown application type');
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
exports.toApiApplication = toApiApplication;
|
|
410
|
+
const toFormVariables = (envVars) => Object.entries(envVars).map(([name, value]) => ({ name, value: value || '' }));
|
|
411
|
+
const toFormVolumes = (volumes) => {
|
|
412
|
+
if (!volumes)
|
|
413
|
+
return [];
|
|
414
|
+
return volumes.map((vol) => {
|
|
415
|
+
var _a, _b, _c;
|
|
416
|
+
const fullVolume = vol;
|
|
417
|
+
return {
|
|
418
|
+
name: fullVolume.name,
|
|
419
|
+
imageRef: ((_a = fullVolume.image) === null || _a === void 0 ? void 0 : _a.reference) || '',
|
|
420
|
+
mountPath: ((_b = fullVolume.mount) === null || _b === void 0 ? void 0 : _b.path) || '',
|
|
421
|
+
imagePullPolicy: ((_c = fullVolume.image) === null || _c === void 0 ? void 0 : _c.pullPolicy) || types_1.ImagePullPolicy.PullIfNotPresent,
|
|
422
|
+
};
|
|
423
|
+
});
|
|
424
|
+
};
|
|
425
|
+
const toFormApps = (app) => {
|
|
426
|
+
switch (app.appType) {
|
|
427
|
+
case types_1.AppType.AppTypeContainer:
|
|
428
|
+
return toContainerAppForm(app);
|
|
429
|
+
case types_1.AppType.AppTypeHelm:
|
|
430
|
+
return toHelmAppForm(app);
|
|
431
|
+
case types_1.AppType.AppTypeQuadlet:
|
|
432
|
+
return toQuadletAppForm(app);
|
|
433
|
+
case types_1.AppType.AppTypeCompose:
|
|
434
|
+
return toComposeAppForm(app);
|
|
435
|
+
default:
|
|
436
|
+
throw new Error('Unknown application type');
|
|
415
437
|
}
|
|
416
|
-
// The app must be an inline application
|
|
417
|
-
return hasInlineApplicationChanged(currentApp, updatedApp);
|
|
418
438
|
};
|
|
419
439
|
const getApplicationPatches = (basePath, currentApps, updatedApps) => {
|
|
420
440
|
const patches = [];
|
|
421
441
|
const currentLen = currentApps.length;
|
|
422
442
|
const newLen = updatedApps.length;
|
|
423
443
|
if (currentLen === 0 && newLen > 0) {
|
|
424
|
-
|
|
425
|
-
patches.push({
|
|
426
|
-
path: `${basePath}/applications`,
|
|
427
|
-
op: 'add',
|
|
428
|
-
value: updatedApps.map(exports.toAPIApplication),
|
|
429
|
-
});
|
|
444
|
+
patches.push({ path: `${basePath}/applications`, op: 'add', value: updatedApps.map(exports.toApiApplication) });
|
|
430
445
|
}
|
|
431
446
|
else if (currentLen > 0 && newLen === 0) {
|
|
432
|
-
|
|
433
|
-
patches.push({
|
|
434
|
-
path: `${basePath}/applications`,
|
|
435
|
-
op: 'remove',
|
|
436
|
-
});
|
|
447
|
+
patches.push({ path: `${basePath}/applications`, op: 'remove' });
|
|
437
448
|
}
|
|
438
449
|
else if (currentLen !== newLen) {
|
|
439
|
-
|
|
440
|
-
patches.push({
|
|
441
|
-
path: `${basePath}/applications`,
|
|
442
|
-
op: 'replace',
|
|
443
|
-
value: updatedApps.map(exports.toAPIApplication),
|
|
444
|
-
});
|
|
450
|
+
patches.push({ path: `${basePath}/applications`, op: 'replace', value: updatedApps.map(exports.toApiApplication) });
|
|
445
451
|
}
|
|
446
452
|
else {
|
|
447
|
-
// Apps length has not changed. We only PATCH the applications that have actually changed
|
|
448
453
|
currentApps.forEach((currentApp, index) => {
|
|
449
454
|
const updatedApp = updatedApps[index];
|
|
450
|
-
|
|
455
|
+
const updatedApi = (0, exports.toApiApplication)(updatedApp);
|
|
456
|
+
if (hasApplicationChanged(currentApp, updatedApi)) {
|
|
451
457
|
patches.push({
|
|
452
458
|
path: `${basePath}/applications/${index}`,
|
|
453
459
|
op: 'replace',
|
|
454
|
-
value:
|
|
460
|
+
value: updatedApi,
|
|
455
461
|
});
|
|
456
462
|
}
|
|
457
463
|
});
|
|
@@ -511,40 +517,15 @@ const getApiConfig = (ct) => {
|
|
|
511
517
|
};
|
|
512
518
|
};
|
|
513
519
|
exports.getApiConfig = getApiConfig;
|
|
514
|
-
const
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
};
|
|
522
|
-
const toAPIFiles = (files) => {
|
|
523
|
-
return files.map((file) => ({
|
|
524
|
-
path: file.path,
|
|
525
|
-
content: file.content || '',
|
|
526
|
-
contentEncoding: file.base64 ? types_1.EncodingType.EncodingBase64 : types_1.EncodingType.EncodingPlain,
|
|
527
|
-
}));
|
|
528
|
-
};
|
|
529
|
-
const convertVolumesToForm = (volumes) => {
|
|
530
|
-
if (!volumes)
|
|
531
|
-
return [];
|
|
532
|
-
return volumes.map((vol) => {
|
|
533
|
-
var _a, _b;
|
|
534
|
-
const fullVolume = vol;
|
|
535
|
-
const volForm = {
|
|
536
|
-
name: fullVolume.name,
|
|
537
|
-
imageRef: ((_a = fullVolume.image) === null || _a === void 0 ? void 0 : _a.reference) || '',
|
|
538
|
-
mountPath: ((_b = fullVolume.mount) === null || _b === void 0 ? void 0 : _b.path) || '',
|
|
539
|
-
};
|
|
540
|
-
// Only set imagePullPolicy if there's an image
|
|
541
|
-
if (fullVolume.image) {
|
|
542
|
-
volForm.imagePullPolicy = fullVolume.image.pullPolicy || types_1.ImagePullPolicy.PullIfNotPresent;
|
|
543
|
-
}
|
|
544
|
-
return volForm;
|
|
545
|
-
});
|
|
520
|
+
const getRunAsUser = (app) => {
|
|
521
|
+
if (app) {
|
|
522
|
+
// Existing apps that don't have a "runAs" user are actually running as the "root" user.
|
|
523
|
+
return app.runAs || deviceSpec_1.RUN_AS_ROOT_USER;
|
|
524
|
+
}
|
|
525
|
+
// For new applications, we want to promote "flightctl" as the default user.
|
|
526
|
+
return deviceSpec_1.RUN_AS_FLIGHTCTL_USER;
|
|
546
527
|
};
|
|
547
|
-
const
|
|
528
|
+
const toContainerAppForm = (containerApp) => {
|
|
548
529
|
var _a, _b;
|
|
549
530
|
const ports = ((_a = containerApp === null || containerApp === void 0 ? void 0 : containerApp.ports) === null || _a === void 0 ? void 0 : _a.map((portString) => {
|
|
550
531
|
const [hostPort, containerPort] = portString.split(':');
|
|
@@ -556,114 +537,78 @@ const createContainerApp = (containerApp) => {
|
|
|
556
537
|
specType: deviceSpec_1.AppSpecType.OCI_IMAGE,
|
|
557
538
|
name: (containerApp === null || containerApp === void 0 ? void 0 : containerApp.name) || '',
|
|
558
539
|
image: (containerApp === null || containerApp === void 0 ? void 0 : containerApp.image) || '',
|
|
559
|
-
variables:
|
|
560
|
-
volumes:
|
|
540
|
+
variables: toFormVariables((containerApp === null || containerApp === void 0 ? void 0 : containerApp.envVars) || {}),
|
|
541
|
+
volumes: toFormVolumes(containerApp === null || containerApp === void 0 ? void 0 : containerApp.volumes),
|
|
561
542
|
ports,
|
|
562
|
-
limits: limits
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
memory: limits.memory || '',
|
|
566
|
-
}
|
|
567
|
-
: undefined,
|
|
568
|
-
runAs: (containerApp === null || containerApp === void 0 ? void 0 : containerApp.runAs) || deviceSpec_1.RUN_AS_DEFAULT_USER,
|
|
543
|
+
cpuLimit: (limits === null || limits === void 0 ? void 0 : limits.cpu) || '',
|
|
544
|
+
memoryLimit: (limits === null || limits === void 0 ? void 0 : limits.memory) || '',
|
|
545
|
+
runAs: getRunAsUser(containerApp),
|
|
569
546
|
};
|
|
570
547
|
};
|
|
571
|
-
const
|
|
548
|
+
const toHelmAppForm = (helmApp) => {
|
|
549
|
+
var _a;
|
|
550
|
+
// We want to always show at least one values file field, even when no files have been added yet.
|
|
572
551
|
const values = (helmApp === null || helmApp === void 0 ? void 0 : helmApp.values) || {};
|
|
552
|
+
const valuesFiles = ((_a = helmApp === null || helmApp === void 0 ? void 0 : helmApp.valuesFiles) === null || _a === void 0 ? void 0 : _a.length) ? helmApp.valuesFiles : [''];
|
|
553
|
+
const valuesYaml = Object.keys(values || {}).length > 0 ? js_yaml_1.default.dump(values) : '';
|
|
573
554
|
return {
|
|
574
555
|
appType: types_1.AppType.AppTypeHelm,
|
|
575
556
|
specType: deviceSpec_1.AppSpecType.OCI_IMAGE,
|
|
576
557
|
name: (helmApp === null || helmApp === void 0 ? void 0 : helmApp.name) || '',
|
|
577
558
|
image: (helmApp === null || helmApp === void 0 ? void 0 : helmApp.image) || '',
|
|
578
|
-
namespace: helmApp === null || helmApp === void 0 ? void 0 : helmApp.namespace,
|
|
579
|
-
valuesYaml
|
|
580
|
-
valuesFiles
|
|
581
|
-
};
|
|
582
|
-
};
|
|
583
|
-
const createQuadletImageApp = (quadletApp) => {
|
|
584
|
-
return {
|
|
585
|
-
appType: types_1.AppType.AppTypeQuadlet,
|
|
586
|
-
specType: deviceSpec_1.AppSpecType.OCI_IMAGE,
|
|
587
|
-
name: (quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.name) || '',
|
|
588
|
-
image: (quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.image) || '',
|
|
589
|
-
variables: getAppFormVariables(quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.envVars),
|
|
590
|
-
volumes: convertVolumesToForm(quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.volumes),
|
|
591
|
-
runAs: (quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.runAs) || deviceSpec_1.RUN_AS_DEFAULT_USER,
|
|
559
|
+
namespace: (helmApp === null || helmApp === void 0 ? void 0 : helmApp.namespace) || '',
|
|
560
|
+
valuesYaml,
|
|
561
|
+
valuesFiles,
|
|
592
562
|
};
|
|
593
563
|
};
|
|
594
|
-
const
|
|
595
|
-
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
name: (quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.name) || '',
|
|
599
|
-
files: toFormFiles((quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.inline) || []),
|
|
600
|
-
variables: getAppFormVariables(quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.envVars),
|
|
601
|
-
volumes: convertVolumesToForm(quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.volumes),
|
|
602
|
-
runAs: (quadletApp === null || quadletApp === void 0 ? void 0 : quadletApp.runAs) || deviceSpec_1.RUN_AS_DEFAULT_USER,
|
|
603
|
-
};
|
|
604
|
-
};
|
|
605
|
-
const createComposeImageApp = (composeApp) => {
|
|
606
|
-
return {
|
|
564
|
+
const toComposeAppForm = (app) => {
|
|
565
|
+
const isInlineVariant = app && (0, deviceSpec_1.isInlineVariantApp)(app);
|
|
566
|
+
const specType = isInlineVariant ? deviceSpec_1.AppSpecType.INLINE : deviceSpec_1.AppSpecType.OCI_IMAGE;
|
|
567
|
+
const formApp = {
|
|
607
568
|
appType: types_1.AppType.AppTypeCompose,
|
|
608
|
-
specType
|
|
609
|
-
name: (
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
volumes: convertVolumesToForm(composeApp === null || composeApp === void 0 ? void 0 : composeApp.volumes),
|
|
569
|
+
specType,
|
|
570
|
+
name: (app === null || app === void 0 ? void 0 : app.name) || '',
|
|
571
|
+
variables: toFormVariables((app === null || app === void 0 ? void 0 : app.envVars) || {}),
|
|
572
|
+
volumes: toFormVolumes(app === null || app === void 0 ? void 0 : app.volumes),
|
|
613
573
|
};
|
|
574
|
+
// We want to have both fields initialized for the formik form
|
|
575
|
+
if (isInlineVariant) {
|
|
576
|
+
formApp.files = toFormFiles((app === null || app === void 0 ? void 0 : app.inline) || []);
|
|
577
|
+
formApp.image = '';
|
|
578
|
+
}
|
|
579
|
+
else {
|
|
580
|
+
formApp.image = (app === null || app === void 0 ? void 0 : app.image) || '';
|
|
581
|
+
formApp.files = [];
|
|
582
|
+
}
|
|
583
|
+
return formApp;
|
|
614
584
|
};
|
|
615
|
-
const
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
specType: deviceSpec_1.AppSpecType.INLINE,
|
|
619
|
-
name: (composeApp === null || composeApp === void 0 ? void 0 : composeApp.name) || '',
|
|
620
|
-
files: toFormFiles((composeApp === null || composeApp === void 0 ? void 0 : composeApp.inline) || []),
|
|
621
|
-
variables: getAppFormVariables(composeApp === null || composeApp === void 0 ? void 0 : composeApp.envVars),
|
|
622
|
-
volumes: convertVolumesToForm(composeApp === null || composeApp === void 0 ? void 0 : composeApp.volumes),
|
|
623
|
-
};
|
|
585
|
+
const toQuadletAppForm = (app) => {
|
|
586
|
+
const baseApp = toComposeAppForm(app);
|
|
587
|
+
return Object.assign(Object.assign({}, baseApp), { appType: types_1.AppType.AppTypeQuadlet, runAs: getRunAsUser(app) });
|
|
624
588
|
};
|
|
625
|
-
const createInitialAppForm = (appType,
|
|
589
|
+
const createInitialAppForm = (appType, name = '') => {
|
|
626
590
|
let app;
|
|
627
591
|
switch (appType) {
|
|
628
592
|
case types_1.AppType.AppTypeContainer:
|
|
629
|
-
app =
|
|
593
|
+
app = toContainerAppForm(undefined);
|
|
630
594
|
break;
|
|
631
595
|
case types_1.AppType.AppTypeHelm:
|
|
632
|
-
app =
|
|
596
|
+
app = toHelmAppForm(undefined);
|
|
633
597
|
break;
|
|
634
598
|
case types_1.AppType.AppTypeQuadlet:
|
|
635
|
-
app =
|
|
599
|
+
app = toQuadletAppForm(undefined);
|
|
636
600
|
break;
|
|
637
601
|
case types_1.AppType.AppTypeCompose:
|
|
638
|
-
app =
|
|
602
|
+
app = toComposeAppForm(undefined);
|
|
639
603
|
break;
|
|
604
|
+
default:
|
|
605
|
+
throw new Error('Unknown application type');
|
|
640
606
|
}
|
|
641
607
|
app.name = name;
|
|
642
608
|
return app;
|
|
643
609
|
};
|
|
644
610
|
exports.createInitialAppForm = createInitialAppForm;
|
|
645
|
-
const getApplicationValues = (deviceSpec) =>
|
|
646
|
-
const apps = (deviceSpec === null || deviceSpec === void 0 ? void 0 : deviceSpec.applications) || [];
|
|
647
|
-
return apps.map((app) => {
|
|
648
|
-
if (!app.appType) {
|
|
649
|
-
throw new Error('Application appType is required');
|
|
650
|
-
}
|
|
651
|
-
switch (app.appType) {
|
|
652
|
-
case types_1.AppType.AppTypeContainer:
|
|
653
|
-
return createContainerApp(app);
|
|
654
|
-
case types_1.AppType.AppTypeHelm:
|
|
655
|
-
return createHelmApp(app);
|
|
656
|
-
case types_1.AppType.AppTypeQuadlet:
|
|
657
|
-
return (0, deviceSpec_1.isImageAppProvider)(app)
|
|
658
|
-
? createQuadletImageApp(app)
|
|
659
|
-
: createQuadletInlineApp(app);
|
|
660
|
-
case types_1.AppType.AppTypeCompose:
|
|
661
|
-
return (0, deviceSpec_1.isImageAppProvider)(app)
|
|
662
|
-
? createComposeImageApp(app)
|
|
663
|
-
: createComposeInlineApp(app);
|
|
664
|
-
}
|
|
665
|
-
});
|
|
666
|
-
};
|
|
611
|
+
const getApplicationValues = (deviceSpec) => ((deviceSpec === null || deviceSpec === void 0 ? void 0 : deviceSpec.applications) || []).map(toFormApps);
|
|
667
612
|
exports.getApplicationValues = getApplicationValues;
|
|
668
613
|
const getSystemdUnitsValues = (deviceSpec) => {
|
|
669
614
|
var _a, _b;
|