Skip to content

Commit

Permalink
mgr/dashboard: Use _no_schedule label instead of maintenance mode
Browse files Browse the repository at this point in the history
While adding a host in the cluster creation/expansion wizard, use the _no_schedule label instead of maintenance mode. With maintenance mode, we won't be able to create OSDs, or fetch the facts. The best alternate is to use the _no_schedule label. Thus using _no_schedule label instead.

Fixes: https://tracker.ceph.com/issues/52298
Signed-off-by: Nizamudeen A <nia@redhat.com>
  • Loading branch information
nizamial09 authored and Aashish Sharma committed Aug 24, 2021
1 parent 986707b commit ac113a2
Show file tree
Hide file tree
Showing 19 changed files with 211 additions and 246 deletions.
Expand Up @@ -5,13 +5,7 @@ const pages = {
index: { url: '#/expand-cluster', id: 'cd-create-cluster' }
};

const osd_pages = {
index: { url: '#/osd', id: 'cd-osd-list' },
create: { url: '#/osd/(modal:create)', id: 'cd-osd-form' }
};

export class CreateClusterWizardHelper extends PageHelper {
osd_pages = osd_pages;
pages = pages;
columnIndex = {
hostname: 1,
Expand Down Expand Up @@ -99,7 +93,10 @@ export class CreateClusterWizardHelper extends PageHelper {
}
}
cy.get('cd-modal cd-submit-button').click();
this.checkLabelExists(hostname, labels, add);
}

checkLabelExists(hostname: string, labels: string[], add: boolean) {
// Verify labels are added or removed from Labels column
// First find row with hostname, then find labels in the row
this.getTableCell(this.columnIndex.hostname, hostname)
Expand All @@ -118,9 +115,6 @@ export class CreateClusterWizardHelper extends PageHelper {
}

create(deviceType: 'hdd' | 'ssd') {
cy.get('.btn.btn-accent').first().click();

cy.get('cd-modal').should('exist');
// Click Primary devices Add button
cy.get('cd-osd-devices-selection-groups[name="Primary"]').as('primaryGroups');
cy.get('@primaryGroups').find('button').click();
Expand All @@ -135,8 +129,5 @@ export class CreateClusterWizardHelper extends PageHelper {
cy.get('@primaryGroups').within(() => {
this.getTableCount('total').as('newOSDCount');
});

cy.get(`${this.osd_pages.create.id} .modal-footer .tc_submitButton`).click();
cy.get(`cd-osd-creation-preview-modal .modal-footer .tc_submitButton`).click();
}
}
Expand Up @@ -2,7 +2,7 @@ import { PageHelper } from '../page-helper.po';

const pages = {
index: { url: '#/osd', id: 'cd-osd-list' },
create: { url: '#/osd/(modal:create)', id: 'cd-osd-form' }
create: { url: '#/osd/create', id: 'cd-osd-form' }
};

export class OSDsPageHelper extends PageHelper {
Expand Down
Expand Up @@ -8,7 +8,7 @@ describe('Create cluster add host page', () => {
'ceph-node-02.cephlab.com'
];
const addHost = (hostname: string, exist?: boolean) => {
createCluster.add(hostname, exist, true);
createCluster.add(hostname, exist, false);
createCluster.checkExist(hostname, true);
};

Expand All @@ -25,13 +25,18 @@ describe('Create cluster add host page', () => {
cy.get('.title').should('contain.text', 'Add Hosts');
});

it('should check existing host and add new hosts into maintenance mode', () => {
it('should check existing host and add new hosts', () => {
createCluster.checkExist(hostnames[0], true);

addHost(hostnames[1], false);
addHost(hostnames[2], false);
});

it('should verify "_no_schedule" label is added', () => {
createCluster.checkLabelExists(hostnames[1], ['_no_schedule'], true);
createCluster.checkLabelExists(hostnames[2], ['_no_schedule'], true);
});

it('should not add an existing host', () => {
createCluster.add(hostnames[0], true);
});
Expand Down
@@ -1,4 +1,7 @@
import { CreateClusterWizardHelper } from 'cypress/integration/cluster/create-cluster.po';
import { OSDsPageHelper } from 'cypress/integration/cluster/osds.po';

const osds = new OSDsPageHelper();

describe('Create cluster create osds page', () => {
const createCluster = new CreateClusterWizardHelper();
Expand All @@ -19,10 +22,16 @@ describe('Create cluster create osds page', () => {

describe('when Orchestrator is available', () => {
it('should create OSDs', () => {
createCluster.getTableCount('total').as('initOSDCount');

createCluster.create('hdd');

cy.get('button[aria-label="Next"]').click();
cy.get('button[aria-label="Next"]').click();

cy.wait(3000);

osds.navigateTo();
osds.getTableCount('total').as('initOSDCount');

cy.get('@newOSDCount').then((newCount) => {
cy.get('@initOSDCount').then((oldCount) => {
const expectedCount = Number(oldCount) + Number(newCount);
Expand All @@ -36,25 +45,4 @@ describe('Create cluster create osds page', () => {
});
});
});

describe('by selecting one row in OSDs List', () => {
beforeEach(() => {
createCluster.getExpandCollapseElement().click();
});

it('should show the correct text for the tab labels', () => {
cy.get('#tabset-osd-details > li > a').then(($tabs) => {
const tabHeadings = $tabs.map((_i, e) => e.textContent).get();

expect(tabHeadings).to.eql([
'Devices',
'Attributes (OSD map)',
'Metadata',
'Device health',
'Performance counter',
'Performance Details'
]);
});
});
});
});
Expand Up @@ -26,6 +26,7 @@ describe('Create Cluster Review page', () => {

// check for fields in table
createCluster.getStatusTables().should('contain.text', 'Hosts');
createCluster.getStatusTables().should('contain.text', 'Storage Capacity');
});

it('should check Hosts by Label and Host Details tables are present', () => {
Expand Down
@@ -1,6 +1,5 @@
import { CreateClusterWizardHelper } from 'cypress/integration/cluster/create-cluster.po';
import { HostsPageHelper } from 'cypress/integration/cluster/hosts.po';
import { OSDsPageHelper } from 'cypress/integration/cluster/osds.po';

describe('when cluster creation is completed', () => {
const createCluster = new CreateClusterWizardHelper();
Expand All @@ -21,30 +20,16 @@ describe('when cluster creation is completed', () => {
cy.get('cd-dashboard').should('exist');
});

describe('OSDs page', () => {
const osds = new OSDsPageHelper();

beforeEach(() => {
osds.navigateTo();
});

it('should display osds', () => {
cy.get('cd-osd-list').within(() => {
osds.getTableCount('total').should('be.gte', 0);
});
});
});

describe('Hosts page', () => {
const hosts = new HostsPageHelper();
const hostnames = ['ceph-node-00.cephlab.com', 'ceph-node-02.cephlab.com'];

beforeEach(() => {
hosts.navigateTo();
});
it('should have already exited from maintenance', () => {
it('should have removed "_no_schedule" label', () => {
for (let host = 0; host < hostnames.length; host++) {
cy.get('datatable-row-wrapper').should('not.have.text', 'maintenance');
cy.get('datatable-row-wrapper').should('not.have.text', '_no_schedule');
}
});

Expand Down
Expand Up @@ -159,13 +159,13 @@ const routes: Routes = [
},
{
path: 'osd',
component: OsdListComponent,
data: { breadcrumbs: 'Cluster/OSDs' },
children: [
{ path: '', component: OsdListComponent },
{
path: URLVerbs.CREATE,
component: OsdFormComponent,
outlet: 'modal'
data: { breadcrumbs: ActionLabels.CREATE }
}
]
},
Expand Down
Expand Up @@ -9,6 +9,13 @@
class="bold">Hosts</td>
<td>{{ hostsCount }}</td>
</tr>
<tr>
<td i18n
class="bold">Storage Capacity</td>
<td><span i18n
*ngIf="filteredDevices && capacity">Number of devices: {{ filteredDevices.length }}. Raw capacity:
{{ capacity | dimlessBinary }}.</span></td>
</tr>
</table>
</fieldset>
</div>
Expand Down
Expand Up @@ -4,6 +4,8 @@ import _ from 'lodash';

import { HostService } from '~/app/shared/api/host.service';
import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';
import { InventoryDevice } from '../inventory/inventory-devices/inventory-device.model';

@Component({
selector: 'cd-create-cluster-review',
Expand All @@ -18,8 +20,10 @@ export class CreateClusterReviewComponent implements OnInit {
labelOccurrences = {};
hostsCountPerLabel: object[] = [];
uniqueLabels: Set<string> = new Set();
filteredDevices: InventoryDevice[] = [];
capacity = 0;

constructor(private hostService: HostService) {}
constructor(private hostService: HostService, public wizardStepService: WizardStepsService) {}

ngOnInit() {
this.hostsDetails = {
Expand Down Expand Up @@ -82,5 +86,8 @@ export class CreateClusterReviewComponent implements OnInit {
this.hostsByLabel['data'] = [...this.hostsCountPerLabel];
this.hostsDetails['data'] = [...this.hosts];
});

this.filteredDevices = this.wizardStepService.osdDevices;
this.capacity = this.wizardStepService.osdCapacity;
}
}
Expand Up @@ -110,34 +110,40 @@ export class CreateClusterComponent implements OnDestroy {
});

this.taskWrapper
.wrapTaskAroundCall({
task: new FinishedTask('osd/' + URLVerbs.CREATE, {
tracking_id: _.join(_.map(this.driveGroups, 'service_id'), ', ')
}),
call: this.osdService.create(this.driveGroups)
})
.subscribe({
error: () => {
},
complete: () => {
this.submitAction.emit();
}
});
.wrapTaskAroundCall({
task: new FinishedTask('osd/' + URLVerbs.CREATE, {
tracking_id: _.join(_.map(this.driveGroups, 'service_id'), ', ')
}),
call: this.osdService.create(this.driveGroups)
})
.subscribe({
error: (error) => error.preventDefault(),
complete: () => {
this.submitAction.emit();
}
});
}

onNextStep() {
if (!this.stepsService.isLastStep()) {
this.hostService.list().subscribe((hosts) => {
hosts.forEach((host) => {
if (host['status'] === 'maintenance') {
this.observables.push(this.hostService.update(host['hostname'], false, [], true));
const index = host['labels'].indexOf('_no_schedule', 0);
if (index > -1) {
host['labels'].splice(index, 1);
this.observables.push(this.hostService.update(host['hostname'], true, host['labels']));
}
});
});
const user = this.authStorageService.getUsername();
this.driveGroup = this.wizardStepService.sharedData;
this.driveGroup.setName(`dashboard-${user}-${_.now()}`);
this.driveGroups.push(this.driveGroup.spec);
this.stepsService.getCurrentStep().subscribe((step: WizardStepModel) => {
this.currentStep = step;
});
if (this.currentStep.stepIndex === 2 && this.driveGroup) {
const user = this.authStorageService.getUsername();
this.driveGroup.setName(`dashboard-${user}-${_.now()}`);
this.driveGroups.push(this.driveGroup.spec);
}
this.stepsService.moveToNextStep();
} else {
this.onSubmit();
Expand Down
Expand Up @@ -25,7 +25,7 @@ export class HostFormComponent extends CdForm implements OnInit {
hostnames: string[];
addr: string;
status: string;
allLabels: any;
allLabels: string[];
pageURL: string;

messages = new SelectMessages({
Expand Down Expand Up @@ -60,7 +60,6 @@ export class HostFormComponent extends CdForm implements OnInit {
}

private createForm() {
const disableMaintenance = this.pageURL !== 'hosts';
this.hostForm = new CdFormGroup({
hostname: new FormControl('', {
validators: [
Expand All @@ -74,7 +73,7 @@ export class HostFormComponent extends CdForm implements OnInit {
validators: [CdValidators.ip()]
}),
labels: new FormControl([]),
maintenance: new FormControl({ value: disableMaintenance, disabled: disableMaintenance })
maintenance: new FormControl(false)
});
}

Expand All @@ -83,6 +82,9 @@ export class HostFormComponent extends CdForm implements OnInit {
this.addr = this.hostForm.get('addr').value;
this.status = this.hostForm.get('maintenance').value ? 'maintenance' : '';
this.allLabels = this.hostForm.get('labels').value;
if (this.pageURL !== 'hosts' && !this.allLabels.includes('_no_schedule')) {
this.allLabels.push('_no_schedule');
}
this.taskWrapper
.wrapTaskAroundCall({
task: new FinishedTask('host/' + URLVerbs.ADD, {
Expand Down
Expand Up @@ -115,21 +115,15 @@ export class HostsComponent extends ListWithDetails implements OnInit {
icon: Icons.enter,
click: () => this.hostMaintenance(),
disable: (selection: CdTableSelection) =>
this.getDisable('maintenance', selection) ||
this.isExecuting ||
this.enableButton ||
this.clusterCreation
this.getDisable('maintenance', selection) || this.isExecuting || this.enableButton
},
{
name: this.actionLabels.EXIT_MAINTENANCE,
permission: 'update',
icon: Icons.exit,
click: () => this.hostMaintenance(),
disable: (selection: CdTableSelection) =>
this.getDisable('maintenance', selection) ||
this.isExecuting ||
!this.enableButton ||
this.clusterCreation
this.getDisable('maintenance', selection) || this.isExecuting || !this.enableButton
}
];
}
Expand Down
Expand Up @@ -11,6 +11,7 @@ import { Icons } from '~/app/shared/enum/icons.enum';
import { CdFormBuilder } from '~/app/shared/forms/cd-form-builder';
import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change';
import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';

@Component({
selector: 'cd-osd-devices-selection-modal',
Expand Down Expand Up @@ -42,7 +43,8 @@ export class OsdDevicesSelectionModalComponent implements AfterViewInit {
constructor(
private formBuilder: CdFormBuilder,
public activeModal: NgbActiveModal,
public actionLabels: ActionLabelsI18n
public actionLabels: ActionLabelsI18n,
public wizardStepService: WizardStepsService
) {
this.action = actionLabels.ADD;
this.createForm();
Expand Down Expand Up @@ -80,6 +82,8 @@ export class OsdDevicesSelectionModalComponent implements AfterViewInit {
this.filteredDevices = event.data;
this.capacity = _.sumBy(this.filteredDevices, 'sys_api.size');
this.event = event;
this.wizardStepService.osdDevices = this.filteredDevices;
this.wizardStepService.osdCapacity = this.capacity;
}
}

Expand Down

0 comments on commit ac113a2

Please sign in to comment.