Unverified Commit bb60e1cc authored by Evgeny Stepanovych's avatar Evgeny Stepanovych Committed by GitHub
Browse files

Merge pull request #6075 from truenas/NAS-113104

NAS-113104 / 22.02-RC.2 / NAS-113104: Removing multipath support and some other unused components
parents f74a045e a51777b9
Showing with 35 additions and 318 deletions
+35 -318
......@@ -6,7 +6,6 @@ import { ApiDirectory, ApiMethod } from 'app/interfaces/api-directory.interface'
import { Dataset, ExtraDatasetQueryOptions } from 'app/interfaces/dataset.interface';
import { Enclosure } from 'app/interfaces/enclosure.interface';
import { CoreEvent } from 'app/interfaces/events';
import { Multipath } from 'app/interfaces/multipath.interface';
import { NetworkInterface } from 'app/interfaces/network-interface.interface';
import { Pool } from 'app/interfaces/pool.interface';
import { QueryParams } from 'app/interfaces/query-api.interface';
......@@ -88,13 +87,6 @@ export class ApiService {
responseEvent: 'DisksData',
},
},
MultipathRequest: {
apiCall: {
args: [] as QueryParams<Multipath>[],
namespace: 'multipath.query',
responseEvent: 'MultipathData',
},
},
EnclosureDataRequest: {
apiCall: {
namespace: 'enclosure.query',
......
......@@ -143,7 +143,6 @@ import { KubernetesConfig, KubernetesConfigUpdate } from 'app/interfaces/kuberne
import { LdapConfig, LdapConfigUpdate, LdapConfigUpdateResult } from 'app/interfaces/ldap-config.interface';
import { LldpConfig, LldpConfigUpdate } from 'app/interfaces/lldp-config.interface';
import { MailConfig, MailConfigUpdate, SendMailParams } from 'app/interfaces/mail-config.interface';
import { Multipath } from 'app/interfaces/multipath.interface';
import {
NetworkActivityChoice,
NetworkConfiguration,
......@@ -501,9 +500,6 @@ export type ApiDirectory = {
'kubernetes.update': { params: [Partial<KubernetesConfigUpdate>]; response: KubernetesConfig };
'kubernetes.bindip_choices': { params: void; response: Choices };
// Multipath
'multipath.query': { params: QueryParams<Multipath>; response: Multipath[] };
// Mail
'mail.config': { params: void; response: MailConfig };
'mail.update': { params: [MailConfigUpdate]; response: MailConfig };
......
......@@ -7,7 +7,6 @@ import { ForceSidenavEvent } from 'app/interfaces/events/force-sidenav-event.int
import { LabelDrivesEvent } from 'app/interfaces/events/label-drives-event.interface';
import { MediaChangeEvent } from 'app/interfaces/events/media-change-event.interface';
import { MemoryStatsEvent } from 'app/interfaces/events/memory-stats-event.interface';
import { MultipathDataEvent, MultipathRequestEvent } from 'app/interfaces/events/multipath-event.interface';
import { NetworkInterfacesChangedEvent } from 'app/interfaces/events/network-interfaces-changed-event.interface';
import { NicInfoEvent } from 'app/interfaces/events/nic-info-event.interface';
import { PoolDataEvent } from 'app/interfaces/events/pool-data-event.interface';
......@@ -66,6 +65,4 @@ export type CoreEvent =
| UserPreferencesEvent
| LabelDrivesEvent
| MemoryStatsEvent
| MultipathRequestEvent
| MultipathDataEvent
| EnclosureLabelChangedEvent;
import { Multipath } from 'app/interfaces/multipath.interface';
import { QueryParams } from 'app/interfaces/query-api.interface';
export interface MultipathRequestEvent {
name: 'MultipathRequest';
sender: unknown;
data: QueryParams<Multipath>;
}
export interface MultipathDataEvent {
name: 'MultipathData';
sender: unknown;
data: Multipath[];
}
export interface Multipath {
type: string;
name: string;
status: string;
children: MultipathChild[];
}
export interface MultipathChild {
type: string;
name: string;
status: string;
lun_id: string;
}
<!-- <ng-template [ngTemplateOutlet]="templateTop" [ngTemplateOutletContext]="this"></ng-template> -->
<mat-card class="card">
<div class="center">
<mat-icon class="icon" role="img" fontSet="mdi-set" fontIcon="mdi-tools" ></mat-icon>
<h1>Coming soon!</h1>
<a [href]="helpurl" target="_blank">Click to learn more.</a>
</div>
</mat-card>
.center {
text-align: center;
}
.icon {
font-size: 96px;
height: auto;
width: 96px;
}
.card {
align-items: center;
flex-direction: column;
justify-content: center;
margin: auto;
position: relative;
top: 150px;
width: 275px;
}
import { Component, Input } from '@angular/core';
import urls from 'app/helptext/urls';
@Component({
selector: 'entity-comingsoon',
templateUrl: './entity-comingsoon.component.html',
styleUrls: ['./entity-comingsoon.component.scss', '../entity-form/entity-form.component.scss'],
providers: [],
})
export class EntityComingsoonComponent {
@Input() conf = { help_path: 'hub/scale/dev-notes/' };
helpurl: string;
constructor() {
this.helpurl = urls.docurl;
if (this.conf['help_path']) {
this.helpurl = this.helpurl.concat(this.conf['help_path']);
}
}
}
<div>
<div fxLayout="row wrap" fxLayout.xs="column" >
<div *ngFor="let item of routeParts" fxFlex="50">
<mat-card>
<mat-card-content>
<div fxLayout="row" fxLayoutAlign="space-between center">
<div>
<button mat-icon-button (click)="goList(item)">
<mat-icon aria-label="Example icon-button with a heart icon">{{item.data.icon}}</mat-icon>
</button>
<span><a class="text-click" (click)="goList(item)">{{item.data.title}}</a></span>
</div>
<div>
<button mat-icon-button (click)="goAdd(item)" *ngIf="item.addPath">
<mat-icon aria-label="Example icon-button with a heart icon">add_circle</mat-icon>
</button>
</div>
</div>
</mat-card-content>
</mat-card>
</div>
</div>
</div>
.text-click {
cursor: pointer;
}
import { Component, OnInit } from '@angular/core';
import { Router, ActivatedRoute, Route } from '@angular/router';
import { UntilDestroy, untilDestroyed } from '@ngneat/until-destroy';
import { TranslateService } from '@ngx-translate/core';
import * as _ from 'lodash';
import { ProductType } from 'app/enums/product-type.enum';
import { WebSocketService } from 'app/services/ws.service';
export interface EntityDashboardRoutePart extends Route {
addPath?: string;
}
@UntilDestroy()
@Component({
selector: 'entity-dashboard',
templateUrl: './entity-dashboard.component.html',
styleUrls: ['./entity-dashboard.component.scss'],
})
export class EntityDashboardComponent implements OnInit {
routeParts: EntityDashboardRoutePart[] = [];
protected parent = '';
protected scale_exclude = ['nis', 'multipaths'];
protected enterpriseOnly = ['viewenclosure'];
productType = window.localStorage.getItem('product_type') as ProductType;
constructor(
protected ws: WebSocketService,
protected router: Router,
protected aroute: ActivatedRoute,
public translate: TranslateService,
) {
}
ngOnInit(): void {
this.parent = this.aroute.parent.parent.routeConfig.path;
const routeConfigs: EntityDashboardRoutePart[] = this.aroute.parent.routeConfig.children;
routeConfigs.forEach((routeConfig) => {
if (routeConfig.path !== '' && !routeConfig.path.includes(':')) {
if (_.find(routeConfig.children, { path: 'add' })) {
routeConfig['addPath'] = 'add';
} else if (_.find(routeConfig.children, { path: 'import' })) {
routeConfig['addPath'] = 'import';
}
this.routeParts.push(routeConfig);
}
});
let exclude: string[] = [];
if (this.productType.includes(ProductType.Scale)) {
exclude = exclude.concat(this.scale_exclude);
}
if (!this.productType.includes(ProductType.Enterprise)) {
exclude = exclude.concat(this.enterpriseOnly);
}
this.ws.call('ipmi.is_loaded').pipe(untilDestroyed(this)).subscribe((isIpmiLoaded) => {
if (!isIpmiLoaded) {
this.remove('ipmi');
}
});
this.ws.call('multipath.query').pipe(untilDestroyed(this)).subscribe((res) => {
if (!res || res.length === 0) {
this.remove('multipaths');
}
});
exclude.forEach((element) => {
this.remove(element);
});
}
remove(element: string): void {
this.routeParts = _.remove(this.routeParts, (r) => r['path'] !== element);
}
goList(item: EntityDashboardRoutePart): void {
this.router.navigate(new Array('/').concat([this.parent, item.path]));
}
goAdd(item: EntityDashboardRoutePart): void {
this.router.navigate(new Array('/').concat([this.parent, item.path, item.addPath]));
}
}
......@@ -31,8 +31,6 @@ import { DocsService } from 'app/services/docs.service';
import { JobService } from 'app/services/index';
import { EntityCardActionsComponent } from './entity-card/entity-card-actions.component';
import { EntityCardComponent } from './entity-card/entity-card.component';
import { EntityComingsoonComponent } from './entity-comingsoon/entity-comingsoon.component';
import { EntityDashboardComponent } from './entity-dashboard/entity-dashboard.component';
import { EntityDialogComponent } from './entity-dialog/entity-dialog.component';
import { EntityEmptyComponent } from './entity-empty/entity-empty.component';
import { DynamicFieldDirective } from './entity-form/components/dynamic-field/dynamic-field.directive';
......@@ -88,10 +86,25 @@ import { TableService } from './table/table.service';
@NgModule({
imports: [
CommonModule, FormsModule, ReactiveFormsModule, DragDropModule, RouterModule,
MaterialModule, ColorPickerModule, NgxDatatableModule, CdkTableModule, TreeModule.forRoot(),
NgxUploaderModule, FlexLayoutModule, TranslateModule, CdkTreeModule,
OverlayModule, A11yModule, TreeTableModule, NgxFilesizeModule, CommonDirectivesModule,
CommonModule,
FormsModule,
ReactiveFormsModule,
DragDropModule,
RouterModule,
MaterialModule,
ColorPickerModule,
NgxDatatableModule,
CdkTableModule,
TreeModule.forRoot(),
NgxUploaderModule,
FlexLayoutModule,
TranslateModule,
CdkTreeModule,
OverlayModule,
A11yModule,
TreeTableModule,
NgxFilesizeModule,
CommonDirectivesModule,
TooltipModule,
],
declarations: [
......@@ -150,10 +163,8 @@ import { TableService } from './table/table.service';
ToolbarMultimenuComponent,
ToolbarMultiSelectComponent,
FormStatusComponent,
EntityComingsoonComponent,
TableComponent,
ExpandableTableComponent,
EntityDashboardComponent,
EntityEmptyComponent,
FormDictComponent,
WizardSummaryComponent,
......@@ -184,7 +195,6 @@ import { TableService } from './table/table.service';
ToolbarMenuComponent,
ToolbarMultimenuComponent,
ToolbarMultiSelectComponent,
EntityComingsoonComponent,
TableComponent,
ExpandableTableComponent,
CdkTreeModule,
......
......@@ -241,7 +241,6 @@
</span>
<span *ngIf="vdev.type == 'DISK'" class="vdev" >
<mat-icon *ngIf="trimMultipath(vdev.disk).isMultipath" class="multipath-icon" role="img" svgIcon="multipath"></mat-icon>
<span>
{{trimMultipath(vdev.disk).name}}
</span>
......@@ -251,8 +250,7 @@
<span *ngIf="vdev.type !== 'DISK' && vdev.children.length <= 3;" class="vdev" >
<span *ngFor="let device of vdev.children; let child = index">
<div *ngIf="device.disk">
<mat-icon *ngIf="trimMultipath(device.disk.name).isMultipath" class="multipath-icon" role="img" svgIcon="multipath"></mat-icon>
<span>{{trimMultipath(device.disk.name).isMultipath ? device.disk.name : device.disk}}</span>
<span>{{device.disk}}</span>
{{trimMultipath(device.disk.name).name}}
<span *ngIf="child < 3 - 1 && child !== vdev.children.length - 1">,</span>&nbsp;&nbsp;
</div>
......@@ -262,8 +260,7 @@
<span *ngIf="vdev.children.length > 3;" class="vdev">
<span *ngFor="let device of vdev.children; let child = index" [ngClass]="{'hidden': child >= 3}">
<div *ngIf="device.disk">
<mat-icon *ngIf="trimMultipath(device.disk).isMultipath" class="multipath-icon" role="img" svgIcon="multipath"></mat-icon>
<span>{{trimMultipath(device.disk).isMultipath ? trimMultipath(device.disk).name : device.disk}}</span>
<span>{{device.disk}}</span>
<span *ngIf="child < 3 - 1 && child !== vdev.children.length - 1">,</span>&nbsp;&nbsp;
</div>
</span>
......@@ -285,11 +282,10 @@
*ngFor="let disk of path[currentSlideIndex].dataSource.children; let i=index"
role="listitem"
(click)="updateSlide('disk details', true, currentSlideIndex + 1, i, currentSlideTopology, disk )"
(click)="getDiskDetails('name', disk.disk, checkMultipath(disk.disk))"
(click)="getDiskDetails('name', disk.disk)"
[ngClass]="{'clickable': true}"
>
<strong >
<mat-icon *ngIf="checkMultipath(disk.disk)" class="multipath-icon" role="img" svgIcon="multipath"></mat-icon>
<strong>
<span *ngIf="disk.status !== 'UNAVAIL'">{{trimMultipath(disk.disk).fullName}}</span>
<span *ngIf="disk.status == 'UNAVAIL'">Unknown Disk</span>
:
......@@ -314,13 +310,10 @@
<mat-list-item
role="listitem"
(click)="updateSlide('disk details', true, currentSlideIndex + 1, undefined, currentSlideTopology, path[currentSlideIndex].dataSource)"
(click)="getDiskDetails('name', path[currentSlideIndex].dataSource.disk, checkMultipath(path[currentSlideIndex].dataSource.disk))"
(click)="getDiskDetails('name', path[currentSlideIndex].dataSource.disk)"
[ngClass]="{'clickable': true}"
>
<strong>
<span *ngIf="checkMultipath(path[2].dataSource.disk)">
<mat-icon class="multipath-icon" role="img" svgIcon="multipath"></mat-icon>
</span>
{{trimMultipath(path[2].dataSource.disk).fullName}}
:
</strong>
......@@ -338,20 +331,10 @@
<ng-template #disk_details>
<div class="list-subheader"><span class="capitalize">{{"Disk Details" | translate}}</span></div>
<mat-list >
<mat-list-item *ngIf="!currentMultipathDetails" role="listitem">
<strong> {{"Name" | translate}}:</strong>&nbsp;&nbsp; {{currentMultipathDetails ? checkMultipathLabel(path[currentSlideIndex].dataSource.disk) : path[currentSlideIndex].dataSource.disk}}
<mat-list-item role="listitem">
<strong> {{"Name" | translate}}:</strong>&nbsp;&nbsp; {{path[currentSlideIndex].dataSource.disk}}
</mat-list-item>
<ng-template [ngIf]="currentMultipathDetails">
<mat-list-item role="listitem">
<strong> {{"Multipath Name" | translate}}:</strong>&nbsp;&nbsp; {{currentMultipathDetails ? checkMultipathLabel(path[currentSlideIndex].dataSource.disk) : path[currentSlideIndex].dataSource.disk}}
</mat-list-item>
<mat-list-item *ngFor="let child of currentMultipathDetails.children" role="listitem">
<strong class="multipath-detail-label"><span class="capitalize">{{child.status.toLowerCase()}}</span> {{"Disk" | translate}}:</strong>&nbsp;&nbsp; {{child.name}}
</mat-list-item>
</ng-template>
<mat-list-item role="listitem">
<strong> GUID:</strong>&nbsp;&nbsp; {{path[currentSlideIndex].dataSource.guid}}
</mat-list-item>
......
......@@ -22,16 +22,6 @@
z-index: 2;
}
.mat-icon.multipath-icon {
color: var(--fg2);
height: 18px;
margin-right: 4px;
padding: 0 1px 2px;
position: relative;
top: 3px;
width: 18px;
}
.xs.widget mat-toolbar-row.view-overview .controls,
.widget mat-toolbar-row.view-overview .primary-nav {
color: #efefef; /* Dont use CSS var here as it is over a dark image*/
......
......@@ -19,8 +19,6 @@ import { styler, tween } from 'popmotion';
import { PoolStatus } from 'app/enums/pool-status.enum';
import { VDevType } from 'app/enums/v-dev-type.enum';
import { DisksDataEvent } from 'app/interfaces/events/disks-data-event.interface';
import { MultipathDataEvent } from 'app/interfaces/events/multipath-event.interface';
import { Multipath } from 'app/interfaces/multipath.interface';
import { Pool, PoolTopologyCategory } from 'app/interfaces/pool.interface';
import { Disk, VDev } from 'app/interfaces/storage.interface';
import { VolumeData } from 'app/interfaces/volume-data.interface';
......@@ -169,7 +167,6 @@ export class WidgetPoolComponent extends WidgetComponent implements OnInit, Afte
level: 'safe',
};
currentMultipathDetails: Multipath;
currentDiskDetails: Disk;
get currentDiskDetailsKeys(): (keyof Disk)[] {
return this.currentDiskDetails ? Object.keys(this.currentDiskDetails) as (keyof Disk)[] : [];
......@@ -213,23 +210,9 @@ export class WidgetPoolComponent extends WidgetComponent implements OnInit, Afte
this.cdr.detectChanges();
this.core.register({ observerClass: this, eventName: 'MultipathData' }).pipe(untilDestroyed(this)).subscribe((evt: MultipathDataEvent) => {
this.currentMultipathDetails = evt.data[0];
const activeDisk = evt.data[0].children.find((prop) => prop.status == 'ACTIVE');
this.core.emit({ name: 'DisksRequest', data: [[['name', '=', activeDisk.name]]] });
});
this.core.register({ observerClass: this, eventName: 'DisksData' }).pipe(untilDestroyed(this)).subscribe((evt: DisksDataEvent) => {
const currentPath = this.path[this.currentSlideIndex];
let currentName = 'unknown';
if (currentPath?.dataSource) {
if (this.currentMultipathDetails) {
currentName = this.checkMultipathLabel(currentPath.dataSource.disk);
} else if (currentPath.dataSource.disk) {
currentName = currentPath.dataSource.disk;
}
}
const currentName = currentPath?.dataSource?.disk || 'unknown';
if ((!currentName || currentName === 'unknown') && evt.data.length == 0) {
this.currentDiskDetails = null;
......@@ -292,54 +275,25 @@ export class WidgetPoolComponent extends WidgetComponent implements OnInit, Afte
this.checkVolumeHealth();
}
getDiskDetails(key: string, value: string, isMultipath?: boolean): void {
if (isMultipath && key == 'name') {
const v = 'multipath/' + this.checkMultipathLabel(value);
this.core.emit({ name: 'MultipathRequest', data: [[[key, '=', v]]] });
} else if (!isMultipath) {
delete this.currentMultipathDetails;
this.core.emit({ name: 'DisksRequest', data: [[[key, '=', value]]] });
} else {
console.warn('If this is a multipath disk, you must query by name!');
}
}
checkMultipathLabel(name: string): string {
if (name == null) {
name = 'N/A';
}
const truth = this.checkMultipath(name);
let diskName = name;
if (truth) {
const str = name.replace('multipath/', '');
const spl = str.split('p');
diskName = spl[0];
}
return diskName;
}
checkMultipath(name: string): boolean {
if (name) {
const truth = name.startsWith('multipath/');
return truth;
}
return false;
getDiskDetails(key: string, value: string): void {
this.core.emit({ name: 'DisksRequest', data: [[[key, '=', value]]] });
}
trimMultipath(disk: string): { isMultipath?: boolean; name: string; fullName?: string } {
/**
* @deprecated Multipath is not supported
*/
trimMultipath(disk: string): { name: string; fullName?: string } {
if (!disk || disk == null) {
return { name: disk };
}
const isMultipath = disk.includes('multipath/');
const fullName = isMultipath ? disk.replace('multipath/', '') : disk;
const fullName = disk;
const spl = fullName.split('-');
const suffix = spl.length > 1 ? '... ' : '';
const name = spl[0] + suffix;
return {
isMultipath,
name,
fullName,
};
......
......@@ -11,10 +11,6 @@
<mat-card-title fxFlex="65%">
<h3 class="mat-card-title-text">
{{ reportTitle }}
<span *ngIf="multipathTitle">
{{ multipathTitle }}
<mat-icon class="multipath-icon" role="img" svgIcon="multipath"></mat-icon>
</span>
</h3>
</mat-card-title>
<!-- Controls/Tools -->
......
......@@ -10,12 +10,6 @@
margin: 0;
}
.mat-icon.multipath-icon {
color: var(--fg2);
position: relative;
top: 3px;
}
.card-title-text {
display: table;
font-size: 1.42em;
......
......@@ -62,7 +62,6 @@ export class ReportComponent extends WidgetComponent implements AfterViewInit, O
@Input() localControls?: boolean = true;
@Input() dateFormat?: DateTime;
@Input() report: Report;
@Input() multipathTitle?: string;
@Input() identifier?: string;
// TODO: Make boolean
@Input() retroLogo?: string | number;
......@@ -76,11 +75,7 @@ export class ReportComponent extends WidgetComponent implements AfterViewInit, O
readonly ProductType = ProductType;
get reportTitle(): string {
let trimmed = this.report.title.replace(/[\(\)]/g, '');
if (this.multipathTitle) {
trimmed = trimmed.replace(this.identifier, '');
return trimmed;
}
const trimmed = this.report.title.replace(/[\(\)]/g, '');
return this.identifier ? trimmed.replace(/{identifier}/, this.identifier) : this.report.title;
}
......
export interface MultipathDisk {
disk: string;
name: string;
status: string;
}
......@@ -14,7 +14,6 @@
*ngIf="retroLogo && activeReports[key] && activeReports[key].identifiers.length > 0"
[retroLogo]="retroLogo"
[report]="activeReports[key]"
[multipathTitle]="multipathTitles[activeReports[key].identifiers[0]]"
[identifier]="activeReports[key].identifiers[0]"
></report>
<report *ngIf="activeReports[key].identifiers.length == 0" [report]="activeReports[key]"></report>
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment