Skip to content

Commit

Permalink
NAS-132906 / 25.04 / Various improvements for containers (truenas#11179)
Browse files Browse the repository at this point in the history
* NAS-132906: Various improvements for containers

* NAS-132906: PR Update
  • Loading branch information
AlexKarpov98 authored Dec 13, 2024
1 parent 432ea4b commit 19789f4
Show file tree
Hide file tree
Showing 101 changed files with 460 additions and 331 deletions.
2 changes: 1 addition & 1 deletion src/app/enums/virtualization.enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,6 @@ export enum VirtualizationNicType {
}

export const virtualizationNicTypeLabels = new Map<VirtualizationNicType, string>([
[VirtualizationNicType.Bridged, T('Bridged')],
[VirtualizationNicType.Bridged, T('Bridged Adaptors')],
[VirtualizationNicType.Macvlan, T('MAC VLAN')],
]);
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<div class="new-page-feedback">
@if (customBadgeTitle(); as title) {
<span>{{ title | translate }}</span>
} @else {
<span>{{ 'NEW' | translate }}</span>

<button
*ixIfNightly
mat-button
ixTest="new-page-feedback"
(click)="leaveFeedbackPressed()"
>{{ 'Leave Feedback' | translate }}</button>
}
</div>
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@ import { provideMockStore } from '@ngrx/store/testing';
import { IfNightlyDirective } from 'app/directives/if-nightly/if-nightly.directive';
import { SystemInfo } from 'app/interfaces/system-info.interface';
import { FeedbackDialogComponent } from 'app/modules/feedback/components/feedback-dialog/feedback-dialog.component';
import { NewPageBadgeComponent } from 'app/modules/page-header/is-new-indicator/new-page-badge.component';
import { HeaderBadgeComponent } from 'app/modules/page-header/header-badge/header-badge.component';
import { selectSystemInfo } from 'app/store/system-info/system-info.selectors';

describe('NewPageBadgeComponent', () => {
let spectator: Spectator<NewPageBadgeComponent>;
describe('HeaderBadgeComponent', () => {
let spectator: Spectator<HeaderBadgeComponent>;
let loader: HarnessLoader;
const createComponent = createComponentFactory({
component: NewPageBadgeComponent,
component: HeaderBadgeComponent,
imports: [
IfNightlyDirective,
],
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { ChangeDetectionStrategy, Component, input } from '@angular/core';
import { MatButton } from '@angular/material/button';
import { MatDialog } from '@angular/material/dialog';
import { TranslateModule } from '@ngx-translate/core';
Expand All @@ -7,9 +7,9 @@ import { FeedbackDialogComponent } from 'app/modules/feedback/components/feedbac
import { TestDirective } from 'app/modules/test-id/test.directive';

@Component({
selector: 'ix-new-page-badge',
templateUrl: './new-page-badge.component.html',
styleUrls: ['./new-page-badge.component.scss'],
selector: 'ix-header-badge',
templateUrl: './header-badge.component.html',
styleUrls: ['./header-badge.component.scss'],
changeDetection: ChangeDetectionStrategy.OnPush,
standalone: true,
imports: [
Expand All @@ -19,7 +19,9 @@ import { TestDirective } from 'app/modules/test-id/test.directive';
TranslateModule,
],
})
export class NewPageBadgeComponent {
export class HeaderBadgeComponent {
readonly customBadgeTitle = input<string>();

constructor(private matDialog: MatDialog) {}

leaveFeedbackPressed(): void {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
<div class="title-container">
<div class="title-and-indicator">
<h1>{{ pageTitle() ? (pageTitle() | translate) : (currentTitle$ | async) | translate }}</h1>
@if (hasNewIndicator$ | async) {
<ix-new-page-badge></ix-new-page-badge>
@if ((hasNewIndicator$ | async) || customBadgeTitle()) {
<ix-header-badge [customBadgeTitle]="customBadgeTitle()"></ix-header-badge>
}
</div>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import { TranslateModule } from '@ngx-translate/core';
import { map } from 'rxjs/operators';
import { FakeProgressBarComponent } from 'app/modules/loader/components/fake-progress-bar/fake-progress-bar.component';
import { BreadcrumbComponent } from 'app/modules/page-header/breadcrumb/breadcrumb.component';
import { NewPageBadgeComponent } from 'app/modules/page-header/is-new-indicator/new-page-badge.component';
import { HeaderBadgeComponent } from 'app/modules/page-header/header-badge/header-badge.component';
import { LayoutService } from 'app/services/layout.service';
import { PageTitleService } from 'app/services/page-title.service';

Expand All @@ -23,14 +23,15 @@ import { PageTitleService } from 'app/services/page-title.service';
standalone: true,
imports: [
BreadcrumbComponent,
NewPageBadgeComponent,
HeaderBadgeComponent,
FakeProgressBarComponent,
TranslateModule,
AsyncPipe,
],
})
export class PageHeaderComponent implements OnInit, OnDestroy {
readonly pageTitle = input<string>();
readonly customBadgeTitle = input<string>();
readonly loading = input(false);

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@
></ix-select>
</ix-fieldset>

<ix-fieldset [title]="'Network' | translate">
<ix-fieldset [title]="'Default Network' | translate">
<ix-select
formControlName="bridge"
[label]="'Bridge' | translate"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<ix-page-header>
<ix-page-header [customBadgeTitle]="'Experimental' | translate">
<ix-all-instances-header></ix-all-instances-header>
</ix-page-header>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,6 @@
</ix-list>
</ix-fieldset>

<ix-fieldset [title]="'Network' | translate">
</ix-fieldset>

<ix-fieldset [title]="'Proxies' | translate">
<ix-list
formArrayName="proxies"
Expand Down Expand Up @@ -171,22 +168,22 @@
</ix-list>
</ix-fieldset>

<ix-fieldset [title]="'NIC' | translate">
@if (hasPendingInterfaceChanges()) {
<p class="warning">
{{ 'NIC selection is currently restricted due to pending network changes.' | translate }}
</p>
} @else {
<ix-button-group
formControlName="nic_type"
[options]="nicType$"
[inlineFields]="true"
[attr.aria-label]="'NIC Type' | translate"
></ix-button-group>
<ix-fieldset [title]="'Network' | translate">
<ix-checkbox
formControlName="use_default_network"
[label]="'Use default network settings' | translate"
></ix-checkbox>

@if (form.controls.nic_type.value === VirtualizationNicType.Bridged) {
@if (!form.controls.use_default_network.value) {
@if (hasPendingInterfaceChanges()) {
<p class="warning">
{{ 'NIC selection is currently restricted due to pending network changes.' | translate }}
</p>
} @else {
@if ((bridgedNicDevices$ | async); as devices) {
@if (devices.length > 0) {
<p>{{ bridgedNicTypeLabel | translate }}</p>

<div formGroupName="bridged_nics">
@for (device of devices; track device) {
<ix-checkbox
Expand All @@ -195,17 +192,15 @@
></ix-checkbox>
}
</div>
} @else {
<p>{{ 'No NICs Found' | translate }}</p>
}
} @else {
<ngx-skeleton-loader></ngx-skeleton-loader>
}
}

@if (form.controls.nic_type.value === VirtualizationNicType.Macvlan) {
@if ((macVlanNicDevices$ | async); as devices) {
@if (devices.length > 0) {
<p>{{ macVlanNicTypeLabel | translate }}</p>

<div formGroupName="mac_vlan_nics">
@for (device of devices; track device) {
<ix-checkbox
Expand All @@ -214,8 +209,6 @@
></ix-checkbox>
}
</div>
} @else {
<p>{{ 'No NICs Found' | translate }}</p>
}
} @else {
<ngx-skeleton-loader></ngx-skeleton-loader>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,6 +148,9 @@ describe('InstanceWizardComponent', () => {
const usbDeviceCheckbox = await loader.getHarness(IxCheckboxHarness.with({ label: 'xHCI Host Controller (0003)' }));
await usbDeviceCheckbox.setValue(true);

const useDefaultNetworkCheckbox = await loader.getHarness(IxCheckboxHarness.with({ label: 'Use default network settings' }));
await useDefaultNetworkCheckbox.setValue(false);

const nicDeviceCheckbox = await loader.getHarness(IxCheckboxHarness.with({ label: 'nic1' }));
await nicDeviceCheckbox.setValue(true);

Expand Down Expand Up @@ -185,4 +188,39 @@ describe('InstanceWizardComponent', () => {
expect(spectator.inject(DialogService).jobDialog).toHaveBeenCalled();
expect(spectator.inject(SnackbarService).success).toHaveBeenCalled();
});

it('sends no NIC devices when default network settings checkbox is set', async () => {
await form.fillForm({
Name: 'new',
Autostart: true,
'CPU Configuration': '1-2',
'Memory Size': '1 GiB',
});

const browseButton = await loader.getHarness(MatButtonHarness.with({ text: 'Browse Catalog' }));
await browseButton.click();

const useDefaultNetworkCheckbox = await loader.getHarness(IxCheckboxHarness.with({ label: 'Use default network settings' }));
await useDefaultNetworkCheckbox.setValue(false);

const nicDeviceCheckbox = await loader.getHarness(IxCheckboxHarness.with({ label: 'nic1' }));
await nicDeviceCheckbox.setValue(true);

await useDefaultNetworkCheckbox.setValue(true); // no nic1 should be send now

const createButton = await loader.getHarness(MatButtonHarness.with({ text: 'Create' }));
await createButton.click();

expect(spectator.inject(ApiService).job).toHaveBeenCalledWith('virt.instance.create', [{
name: 'new',
autostart: true,
cpu: '1-2',
devices: [],
image: 'almalinux/8/cloud',
memory: GiB,
environment: {},
}]);
expect(spectator.inject(DialogService).jobDialog).toHaveBeenCalled();
expect(spectator.inject(SnackbarService).success).toHaveBeenCalled();
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ import {
VirtualizationDevice,
} from 'app/interfaces/virtualization.interface';
import { DialogService } from 'app/modules/dialog/dialog.service';
import { IxButtonGroupComponent } from 'app/modules/forms/ix-forms/components/ix-button-group/ix-button-group.component';
import { IxCheckboxComponent } from 'app/modules/forms/ix-forms/components/ix-checkbox/ix-checkbox.component';
import { IxExplorerComponent } from 'app/modules/forms/ix-forms/components/ix-explorer/ix-explorer.component';
import { IxFieldsetComponent } from 'app/modules/forms/ix-forms/components/ix-fieldset/ix-fieldset.component';
Expand Down Expand Up @@ -76,7 +75,6 @@ import { ApiService } from 'app/services/websocket/api.service';
IxListComponent,
IxListItemComponent,
IxSelectComponent,
IxButtonGroupComponent,
IxExplorerComponent,
NgxSkeletonLoaderModule,
],
Expand All @@ -93,7 +91,8 @@ export class InstanceWizardComponent implements OnInit {
protected readonly hasPendingInterfaceChanges = toSignal(this.api.call('interface.has_pending_changes'));

protected readonly proxyProtocols$ = of(mapToOptions(virtualizationProxyProtocolLabels, this.translate));
readonly nicType$ = of(mapToOptions(virtualizationNicTypeLabels, this.translate));
protected readonly bridgedNicTypeLabel = virtualizationNicTypeLabels.get(VirtualizationNicType.Bridged);
protected readonly macVlanNicTypeLabel = virtualizationNicTypeLabels.get(VirtualizationNicType.Macvlan);

readonly directoryNodeProvider = this.filesystem.getFilesystemNodeProvider();

Expand Down Expand Up @@ -124,6 +123,7 @@ export class InstanceWizardComponent implements OnInit {
image: ['', Validators.required],
cpu: ['', [cpuValidator()]],
memory: [null as number],
use_default_network: [true],
usb_devices: this.formBuilder.record<boolean>({}),
gpu_devices: this.formBuilder.record<boolean>({}),
bridged_nics: this.formBuilder.record<boolean>({}),
Expand All @@ -139,7 +139,6 @@ export class InstanceWizardComponent implements OnInit {
destination: FormControl<string>;
}>>([]),
environment_variables: new FormArray<InstanceEnvVariablesFormGroup>([]),
nic_type: [VirtualizationNicType.Bridged],
});

get hasRequiredRoles(): Observable<boolean> {
Expand Down Expand Up @@ -303,21 +302,25 @@ export class InstanceWizardComponent implements OnInit {
dev_type: VirtualizationDeviceType.Gpu,
}));

const macVlanNics = Object.entries(this.form.controls.mac_vlan_nics.value)
.filter(([_, isSelected]) => isSelected)
.map(([parent]) => ({
parent,
dev_type: VirtualizationDeviceType.Nic,
nic_type: VirtualizationNicType.Macvlan,
}));

const bridgedNics = Object.entries(this.form.controls.bridged_nics.value)
.filter(([_, isSelected]) => isSelected)
.map(([parent]) => ({
parent,
dev_type: VirtualizationDeviceType.Nic,
nic_type: VirtualizationNicType.Bridged,
}));
const macVlanNics = !this.form.controls.use_default_network.value
? Object.entries(this.form.controls.mac_vlan_nics.value)
.filter(([_, isSelected]) => isSelected)
.map(([parent]) => ({
parent,
dev_type: VirtualizationDeviceType.Nic,
nic_type: VirtualizationNicType.Macvlan,
}))
: [];

const bridgedNics = !this.form.controls.use_default_network.value
? Object.entries(this.form.controls.bridged_nics.value)
.filter(([_, isSelected]) => isSelected)
.map(([parent]) => ({
parent,
dev_type: VirtualizationDeviceType.Nic,
nic_type: VirtualizationNicType.Bridged,
}))
: [];

const proxies = this.form.controls.proxies.value.map((proxy) => ({
dev_type: VirtualizationDeviceType.Proxy,
Expand Down
7 changes: 4 additions & 3 deletions src/assets/i18n/af.json
Original file line number Diff line number Diff line change
Expand Up @@ -640,7 +640,7 @@
"Bridge Members": "",
"Bridge Settings": "",
"Bridge interface": "",
"Bridged": "",
"Bridged Adaptors": "",
"Browsable to Network Clients": "",
"Browse Catalog": "",
"Browse to a CD-ROM file present on the system storage.": "",
Expand Down Expand Up @@ -1214,6 +1214,7 @@
"Default ACL Options": "",
"Default Checksum Warning": "",
"Default Gateway": "",
"Default Network": "",
"Default Route": "",
"Default TrueNAS controller": "",
"Default is UTF-8 which supports all characters in all languages.": "",
Expand Down Expand Up @@ -1827,6 +1828,7 @@
"Expand pool ": "",
"Expand pool to fit all available disk space.": "",
"Expander Status": "",
"Experimental": "",
"Expiration Date": "",
"Expires": "",
"Expires at": "",
Expand Down Expand Up @@ -2755,7 +2757,6 @@
"NFSv4 DNS Domain": "",
"NIC": "",
"NIC To Attach": "",
"NIC Type": "",
"NIC modifications are currently restricted due to pending network changes.": "",
"NIC selection is currently restricted due to pending network changes.": "",
"NIC was added": "",
Expand Down Expand Up @@ -2920,7 +2921,6 @@
"No Inherit": "",
"No Isolated GPU Device(s) configured": "",
"No Logs": "",
"No NICs Found": "",
"No NICs added.": "",
"No Pods Found": "",
"No Pools": "",
Expand Down Expand Up @@ -4819,6 +4819,7 @@
"Use an exported encryption key file to unlock datasets.": "",
"Use as Home Share": "",
"Use compressed WRITE records to make the stream more efficient. The destination system must also support compressed WRITE records. See <a href=\"https://linux.die.net/man/8/zfs\" target=\"_blank\">zfs(8)</a>.": "",
"Use default network settings": "",
"Use existing disk image": "",
"Use settings from a saved replication.": "",
"Use snapshot <i>{snapshot}</i> to roll <b>{dataset}</b> back to {datetime}?": "",
Expand Down
Loading

0 comments on commit 19789f4

Please sign in to comment.