feat: add baseos source presets
This commit is contained in:
@@ -12,6 +12,16 @@ import {
|
||||
} from '@design.estate/dees-element';
|
||||
|
||||
type TBaseOsImageBuild = any;
|
||||
type TBaseOsImageSourcePreset =
|
||||
| 'balena-generic-amd64'
|
||||
| 'balena-generic-aarch64'
|
||||
| 'balena-raspberrypi4-64';
|
||||
|
||||
const sourcePresetArchitectures: Record<TBaseOsImageSourcePreset, string> = {
|
||||
'balena-generic-amd64': 'amd64',
|
||||
'balena-generic-aarch64': 'arm64',
|
||||
'balena-raspberrypi4-64': 'rpi',
|
||||
};
|
||||
|
||||
@customElement('cloudly-view-baseos')
|
||||
export class CloudlyViewBaseOs extends DeesElement {
|
||||
@@ -115,10 +125,24 @@ export class CloudlyViewBaseOs extends DeesElement {
|
||||
></dees-input-dropdown>
|
||||
<dees-input-text .key=${'cloudlyUrl'} .label=${'Cloudly URL'} .value=${window.location.origin} .required=${true}></dees-input-text>
|
||||
<dees-input-text .key=${'hostname'} .label=${'Hostname'} .value=${'baseos-node'} .required=${false}></dees-input-text>
|
||||
<dees-input-dropdown
|
||||
.key=${'sourceImagePreset'}
|
||||
.label=${'balenaOS Source Preset'}
|
||||
.selectedOption=${'auto'}
|
||||
.options=${[
|
||||
{ key: 'auto', option: 'Auto by architecture', payload: null },
|
||||
{ key: 'balena-generic-amd64', option: 'Generic x86_64 (GPT)', payload: null },
|
||||
{ key: 'balena-generic-aarch64', option: 'Generic AARCH64', payload: null },
|
||||
{ key: 'balena-raspberrypi4-64', option: 'Raspberry Pi 4 64-bit', payload: null },
|
||||
{ key: 'custom-url', option: 'Custom source URL', payload: null },
|
||||
]}
|
||||
.description=${'Used for balenaOS raw images when no custom source URL is provided.'}
|
||||
></dees-input-dropdown>
|
||||
<dees-input-text .key=${'balenaOsVersion'} .label=${'balenaOS Version'} .value=${'latest'} .description=${'Use latest, or an explicit balenaOS raw_version such as 2026.1.0.'} .required=${false}></dees-input-text>
|
||||
<dees-input-text .key=${'wifiSsid'} .label=${'WiFi SSID'} .required=${false}></dees-input-text>
|
||||
<dees-input-text .key=${'wifiPassword'} .label=${'WiFi Password'} .isPasswordBool=${true} .required=${false}></dees-input-text>
|
||||
<dees-input-textarea .key=${'sshPublicKey'} .label=${'SSH Public Key'} .required=${false}></dees-input-textarea>
|
||||
<dees-input-text .key=${'sourceImageUrl'} .label=${'Source Image URL'} .description=${'Required for balenaOS raw images (.img, .img.xz, or .zip). Optional for Ubuntu ISO builds.'} .required=${false}></dees-input-text>
|
||||
<dees-input-text .key=${'sourceImageUrl'} .label=${'Custom Source Image URL'} .description=${'Optional override for balenaOS raw images (.img, .img.xz, .zip, or balena download URL with fileType=.zip).'} .required=${false}></dees-input-text>
|
||||
<dees-form-submit .text=${this.isLoading ? 'Creating...' : 'Create BaseOS Image'} .disabled=${this.isLoading}></dees-form-submit>
|
||||
</dees-form>
|
||||
</dees-panel>
|
||||
@@ -139,6 +163,7 @@ export class CloudlyViewBaseOs extends DeesElement {
|
||||
<div>
|
||||
<strong>${data.hostname || buildArg.id}</strong>
|
||||
<div class="meta">${data.imageKind || 'ubuntu-iso'} · ${data.architecture} · ${data.cloudlyUrl}</div>
|
||||
${data.sourceImagePreset ? html`<div class="meta">${data.sourceImagePreset} · balenaOS ${data.balenaOsVersion || 'latest'}</div>` : ''}
|
||||
</div>
|
||||
<dees-badge .text=${data.status} .type=${data.status === 'ready' ? 'success' : data.status === 'failed' ? 'error' : 'info'}></dees-badge>
|
||||
</div>
|
||||
@@ -163,15 +188,34 @@ export class CloudlyViewBaseOs extends DeesElement {
|
||||
}
|
||||
|
||||
private async createBuild(formDataArg: any) {
|
||||
this.isLoading = true;
|
||||
try {
|
||||
const architecture = formDataArg.architecture || 'amd64';
|
||||
const imageKind = formDataArg.imageKind || 'balena-raw';
|
||||
const sourceImageUrl = formDataArg.sourceImageUrl?.trim() || undefined;
|
||||
const selectedSourceImagePreset = formDataArg.sourceImagePreset || 'auto';
|
||||
const sourceImagePreset = this.getSourceImagePreset(selectedSourceImagePreset, imageKind, sourceImageUrl);
|
||||
const balenaOsVersion = imageKind === 'balena-raw' && !sourceImageUrl
|
||||
? formDataArg.balenaOsVersion?.trim() || 'latest'
|
||||
: undefined;
|
||||
this.validateBuildForm({
|
||||
architecture,
|
||||
imageKind,
|
||||
selectedSourceImagePreset,
|
||||
sourceImagePreset,
|
||||
sourceImageUrl,
|
||||
wifiSsid: formDataArg.wifiSsid,
|
||||
wifiPassword: formDataArg.wifiPassword,
|
||||
});
|
||||
this.isLoading = true;
|
||||
const response = await this.fireBaseOsRequest('createBaseOsImageBuild', {
|
||||
build: {
|
||||
architecture: formDataArg.architecture || 'amd64',
|
||||
imageKind: formDataArg.imageKind || undefined,
|
||||
architecture,
|
||||
imageKind,
|
||||
cloudlyUrl: formDataArg.cloudlyUrl || window.location.origin,
|
||||
hostname: formDataArg.hostname || undefined,
|
||||
sourceImageUrl: formDataArg.sourceImageUrl || undefined,
|
||||
sourceImageUrl,
|
||||
sourceImagePreset,
|
||||
balenaOsVersion,
|
||||
wifi: formDataArg.wifiSsid
|
||||
? {
|
||||
ssid: formDataArg.wifiSsid,
|
||||
@@ -190,6 +234,50 @@ export class CloudlyViewBaseOs extends DeesElement {
|
||||
}
|
||||
}
|
||||
|
||||
private getSourceImagePreset(
|
||||
sourceImagePresetArg: string | undefined,
|
||||
imageKindArg: string,
|
||||
sourceImageUrlArg?: string,
|
||||
) {
|
||||
if (imageKindArg !== 'balena-raw' || sourceImageUrlArg || sourceImagePresetArg === 'auto') {
|
||||
return undefined;
|
||||
}
|
||||
if (sourceImagePresetArg === 'custom-url') {
|
||||
return undefined;
|
||||
}
|
||||
return sourceImagePresetArg as TBaseOsImageSourcePreset | undefined;
|
||||
}
|
||||
|
||||
private validateBuildForm(optionsArg: {
|
||||
architecture: string;
|
||||
imageKind: string;
|
||||
selectedSourceImagePreset?: string;
|
||||
sourceImagePreset?: TBaseOsImageSourcePreset;
|
||||
sourceImageUrl?: string;
|
||||
wifiSsid?: string;
|
||||
wifiPassword?: string;
|
||||
}) {
|
||||
if (optionsArg.architecture === 'rpi' && optionsArg.imageKind === 'ubuntu-iso') {
|
||||
throw new Error('Raspberry Pi BaseOS images require the balenaOS raw image type.');
|
||||
}
|
||||
if (
|
||||
optionsArg.imageKind === 'balena-raw'
|
||||
&& optionsArg.selectedSourceImagePreset === 'custom-url'
|
||||
&& !optionsArg.sourceImageUrl
|
||||
) {
|
||||
throw new Error('A custom source image URL is required when the custom source preset is selected.');
|
||||
}
|
||||
if (optionsArg.imageKind === 'balena-raw' && optionsArg.sourceImagePreset) {
|
||||
const expectedArchitecture = sourcePresetArchitectures[optionsArg.sourceImagePreset];
|
||||
if (expectedArchitecture !== optionsArg.architecture) {
|
||||
throw new Error(`${optionsArg.sourceImagePreset} is only valid for ${expectedArchitecture} images.`);
|
||||
}
|
||||
}
|
||||
if (optionsArg.wifiPassword && !optionsArg.wifiSsid) {
|
||||
throw new Error('A WiFi SSID is required when a WiFi password is set.');
|
||||
}
|
||||
}
|
||||
|
||||
private async downloadBuild(buildIdArg: string) {
|
||||
const response = await this.fireBaseOsRequest('createBaseOsImageDownloadUrl', {
|
||||
buildId: buildIdArg,
|
||||
|
||||
Reference in New Issue
Block a user