Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 14 additions & 0 deletions src/app/enums/virtualization.enum.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,20 @@
import { marker as T } from '@biesbjerg/ngx-translate-extract-marker';
import { iconMarker } from 'app/modules/ix-icon/icon-marker.util';

export enum ImageOs {
Linux = 'LINUX',
FreeBsd = 'FREEBSD',
Windows = 'WINDOWS',
ArchLinux = 'ARCHLINUX',
}

export const imageOsLabels = new Map<ImageOs, string>([
[ImageOs.Linux, 'Linux'],
[ImageOs.FreeBsd, 'FreeBSD'],
[ImageOs.Windows, 'Windows'],
[ImageOs.ArchLinux, 'Arch Linux'],
]);

export enum VirtualizationType {
Container = 'CONTAINER',
Vm = 'VM',
Expand Down
6 changes: 6 additions & 0 deletions src/app/helptext/instances/instances.ts
Original file line number Diff line number Diff line change
Expand Up @@ -88,4 +88,10 @@ Ideal for legacy applications, full-featured desktops, or software with strict O
moveTooltip: T('Renames the ZFS dataset to a path in the `ix-virt` dataset in which the zvol is located.'),
description: T('Importing a zvol as Instances volume allows its lifecycle to be managed, including backups, restores, and snapshots. This allows portability between systems using standard tools.'),
},

osImage: {
tooltip: T('Optionally specify the operating system for VM-based instances.\
Common options are Windows, Linux, FreeBSD, or Arch Linux, but you can also enter a custom value.\
Leaving this field empty is allowed.'),
},
};
5 changes: 4 additions & 1 deletion src/app/interfaces/virtualization.interface.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { FormControl, FormGroup } from '@angular/forms';
import { NetworkInterfaceAliasType } from 'app/enums/network-interface.enum';
import {
DiskIoBus,
ImageOs,
VirtualizationDeviceType,
VirtualizationGlobalState,
VirtualizationGpuType,
Expand Down Expand Up @@ -86,6 +87,7 @@ export interface CreateVirtualizationInstance {
zvol_path?: string | null;
storage_pool: string | null;
volume?: string | null;
image_os?: ImageOs | null;
}

export interface UpdateVirtualizationInstance {
Expand All @@ -99,6 +101,7 @@ export interface UpdateVirtualizationInstance {
root_disk_io_bus?: DiskIoBus;
vnc_password?: string | null;
root_disk_size?: number;
image_os?: ImageOs | null;
}

export type VirtualizationDevice =
Expand Down Expand Up @@ -206,7 +209,7 @@ export interface VirtualizationImage {
archs: string[];
description: string;
label: string;
os: string;
os: ImageOs | null | string;
release: string;
variant: string;
instance_types: VirtualizationType[];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,11 +98,16 @@ export class IxComboboxComponent implements ControlValueAccessor, OnInit {

writeValue(value: string | number): void {
this.value = value;

if (!this.value) {
this.selectedOption = null;
}
if (this.value && this.options?.length) {
this.selectedOption = { ...(this.options.find((option: Option) => option.value === this.value)) };
let existingOption = this.options.find((option: Option) => option.value === this.value);
if (!existingOption && this.allowCustomValue()) {
existingOption = { label: this.value as string, value: this.value };
}
this.selectedOption = { ...existingOption };
}
this.cdr.markForCheck();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
<h1 mat-dialog-title>
{{ 'Map User And Group IDs' | translate }}

<ix-tooltip class="tooltip" [message]="containersHelptext.idMapHint | translate"></ix-tooltip>
<ix-tooltip class="tooltip" [message]="instancesHelptext.idMapHint | translate"></ix-tooltip>
</h1>

<button
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ import { ErrorHandlerService } from 'app/services/errors/error-handler.service';
})
export class MapUserGroupIdsDialog implements OnInit {
protected readonly columns = ['name', 'hostUidOrGid', 'instanceUidOrGid', 'actions'];
protected readonly containersHelptext = instancesHelptext;
protected readonly instancesHelptext = instancesHelptext;

protected readonly isLoading = signal(false);
protected readonly mappings = signal<IdMapping[]>([]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
formControlName="mapDirectly"
class="default-checkbox"
[label]="isUserType() ? ('Map to the same UID in the instance' | translate) : ('Map to the same GID in the instance' | translate)"
[tooltip]="containersHelptext.mapDirectlyTooltip | translate"
[tooltip]="instancesHelptext.mapDirectlyTooltip | translate"
></ix-checkbox>

@if (!form.value.mapDirectly) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ export class NewMappingFormComponent implements OnChanges, OnInit {
readonly mappingAdded = output();

protected readonly ViewType = ViewType;
protected readonly containersHelptext = instancesHelptext;
protected readonly instancesHelptext = instancesHelptext;

protected form = this.formBuilder.group({
hostUidOrGid: [null as number | null, Validators.required],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ <h3 mat-card-title>
{{ rootDiskSize | ixFileSize }}

@if (instance().root_disk_io_bus) {
({{ instance().root_disk_io_bus | mapValue: diskIoBusLabels}})
({{ instance().root_disk_io_bus | mapValue: diskIoBusLabels }})
}
</span>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,29 +9,40 @@
></ix-checkbox>
</ix-fieldset>

@if (isVm) {
<ix-fieldset [title]="'Operating System' | translate">
<ix-combobox
formControlName="image_os"
[label]="'OS Image' | translate"
[allowCustomValue]="true"
[tooltip]="instancesHelptext.osImage.tooltip| translate"
[provider]="imageOsProvider"
></ix-combobox>
</ix-fieldset>
}

<ix-fieldset [title]="'CPU & Memory' | translate">
<ix-input
formControlName="cpu"
[label]="'CPU Configuration' | translate"
[tooltip]="containersHelptext.cpuTooltip | translate"
[tooltip]="instancesHelptext.cpuTooltip | translate"
[required]="isVm"
[hint]="isVm ? undefined : (containersHelptext.cpuHint | translate)"
[hint]="isVm ? undefined : (instancesHelptext.cpuHint | translate)"
></ix-input>

<ix-input
formControlName="memory"
[label]="'Memory Size' | translate"
[tooltip]="containersHelptext.memoryTooltip | translate"
[tooltip]="instancesHelptext.memoryTooltip | translate"
[format]="formatter.memorySizeFormatting"
[parse]="formatter.memorySizeParsing"
[required]="isVm"
[hint]="isVm ? undefined : (containersHelptext.memoryHint | translate)"
[hint]="isVm ? undefined : (instancesHelptext.memoryHint | translate)"
></ix-input>
</ix-fieldset>

@if (isVm) {
<ix-fieldset [title]="'VNC' | translate">

<div [matTooltip]="isStopped ? '' : ('Instance must be stopped to update VNC.' | translate)">
<ix-checkbox
formControlName="enable_vnc"
Expand Down Expand Up @@ -95,7 +106,7 @@
<ix-checkbox
formControlName="secure_boot"
[label]="'Secure Boot' | translate"
[tooltip]="containersHelptext.secureBootTooltip | translate"
[tooltip]="instancesHelptext.secureBootTooltip | translate"
></ix-checkbox>
</ix-fieldset>
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ describe('InstanceEditFormComponent', () => {
status: VirtualizationStatus.Stopped,
vnc_password: null,
secure_boot: true,
image: {
os: 'FreeBSD',
},
} as VirtualizationInstance;

const createComponent = createComponentFactory({
Expand Down Expand Up @@ -95,6 +98,7 @@ describe('InstanceEditFormComponent', () => {
'VNC Port': '9001',
'VNC Password': '',
'Secure Boot': true,
'OS Image': 'FreeBSD',
});
});

Expand All @@ -117,6 +121,7 @@ describe('InstanceEditFormComponent', () => {
memory: GiB,
enable_vnc: true,
vnc_port: 9000,
image_os: 'FreeBSD',
vnc_password: 'testing',
secure_boot: false,
}]);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,21 @@ import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { TranslateModule, TranslateService } from '@ngx-translate/core';
import { of } from 'rxjs';
import { Role } from 'app/enums/role.enum';
import { VirtualizationStatus, VirtualizationType } from 'app/enums/virtualization.enum';
import {
ImageOs, imageOsLabels, VirtualizationStatus, VirtualizationType,
} from 'app/enums/virtualization.enum';
import { choicesToOptions } from 'app/helpers/operators/options.operators';
import { mapToOptions } from 'app/helpers/options.helper';
import { instancesHelptext } from 'app/helptext/instances/instances';
import {
InstanceEnvVariablesFormGroup,
UpdateVirtualizationInstance,
VirtualizationInstance,
} from 'app/interfaces/virtualization.interface';
import { DialogService } from 'app/modules/dialog/dialog.service';
import { SimpleAsyncComboboxProvider } from 'app/modules/forms/ix-forms/classes/simple-async-combobox-provider';
import { IxCheckboxComponent } from 'app/modules/forms/ix-forms/components/ix-checkbox/ix-checkbox.component';
import { IxComboboxComponent } from 'app/modules/forms/ix-forms/components/ix-combobox/ix-combobox.component';
import { IxFieldsetComponent } from 'app/modules/forms/ix-forms/components/ix-fieldset/ix-fieldset.component';
import { IxInputComponent } from 'app/modules/forms/ix-forms/components/ix-input/ix-input.component';
import { IxListItemComponent } from 'app/modules/forms/ix-forms/components/ix-list/ix-list-item/ix-list-item.component';
Expand Down Expand Up @@ -49,6 +54,7 @@ import { defaultVncPort } from 'app/pages/instances/instances.constants';
IxListComponent,
IxListItemComponent,
MatTooltip,
IxComboboxComponent,
],
templateUrl: './instance-edit-form.component.html',
styleUrls: ['./instance-edit-form.component.scss'],
Expand All @@ -61,8 +67,9 @@ export class InstanceEditFormComponent {
title: string;
editingInstance: VirtualizationInstance;
poolOptions$ = this.api.call('virt.global.pool_choices').pipe(choicesToOptions());
readonly imageOsProvider = new SimpleAsyncComboboxProvider(of(mapToOptions(imageOsLabels, this.translate)));

protected readonly containersHelptext = instancesHelptext;
protected readonly instancesHelptext = instancesHelptext;

get isVm(): boolean {
return this.editingInstance.type === VirtualizationType.Vm;
Expand All @@ -84,6 +91,7 @@ export class InstanceEditFormComponent {
vnc_port: [defaultVncPort as number | null, [Validators.min(5900), Validators.max(65535)]],
vnc_password: [null as string | null],
secure_boot: [false],
image_os: ['' as ImageOs | null],
environmentVariables: new FormArray<InstanceEnvVariablesFormGroup>([]),
});

Expand Down Expand Up @@ -112,6 +120,7 @@ export class InstanceEditFormComponent {
vnc_port: this.editingInstance.vnc_port,
vnc_password: this.editingInstance.vnc_password,
secure_boot: this.editingInstance.secure_boot,
image_os: this.editingInstance?.image?.os as ImageOs,
});

this.setVncControls();
Expand Down Expand Up @@ -177,6 +186,7 @@ export class InstanceEditFormComponent {

if (this.isVm) {
payload.secure_boot = values.secure_boot;
payload.image_os = values.image_os;
}

return payload;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ <h3 mat-card-title>
</p>
<p>
<span class="label">{{ 'Base Image' | translate }}:</span>
{{ instance.image.description || '-' }}
{{ instance.image.description || instance.image.os || '-' }}
</p>
<p>
<span class="label">{{ 'CPU' | translate }}:</span>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@
(click)="onSelectRootVolume()"
>{{ 'Select Volume' | translate }}</button>
</div>

@if (form.value.volume_type === VolumeContentType.Iso) {
<ix-combobox
formControlName="image_os"
[label]="'OS Image' | translate"
[allowCustomValue]="true"
[tooltip]="instancesHelptext.osImage.tooltip| translate"
[provider]="imageOsProvider"
></ix-combobox>
}
}
}
</ix-form-section>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import { mockApi, mockCall, mockJob } from 'app/core/testing/utils/mock-api.util
import { mockAuth } from 'app/core/testing/utils/mock-auth.utils';
import {
DiskIoBus,
ImageOs,
VirtualizationDeviceType,
VirtualizationGpuType,
VirtualizationNicType,
Expand Down Expand Up @@ -384,6 +385,7 @@ describe('InstanceWizardComponent', () => {
root_disk_io_bus: DiskIoBus.Nvme,
instance_type: VirtualizationType.Vm,
iso_volume: null,
image_os: null,
devices: [
{
dev_type: VirtualizationDeviceType.Disk,
Expand Down Expand Up @@ -418,6 +420,7 @@ describe('InstanceWizardComponent', () => {
jest.spyOn(spectator.inject(MatDialog), 'open').mockReturnValue({
afterClosed: () => of({
id: 'myiso.iso',
name: 'win10.iso',
content_type: VolumeContentType.Iso,
} as VirtualizationVolume),
} as MatDialogRef<VolumesDialog>);
Expand Down Expand Up @@ -447,6 +450,7 @@ describe('InstanceWizardComponent', () => {
instance_type: VirtualizationType.Vm,
devices: [],
image: null,
image_os: ImageOs.Windows,
iso_volume: 'myiso.iso',
source_type: VirtualizationSource.Iso,
storage_pool: 'poolio',
Expand Down Expand Up @@ -493,6 +497,7 @@ describe('InstanceWizardComponent', () => {
instance_type: VirtualizationType.Vm,
devices: [],
image: null,
image_os: null,
iso_volume: null,
source_type: VirtualizationSource.Volume,
enable_vnc: false,
Expand Down
Loading