From: Pere Diaz Bou Date: Fri, 17 Jun 2022 11:02:28 +0000 (+0200) Subject: mgr/dashboard: fix tests and iscsi rbd list X-Git-Tag: v18.0.0~511^2~14 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=78523ec030621be548c4e3ecb8802d0b5c7bd8e8;p=ceph-ci.git mgr/dashboard: fix tests and iscsi rbd list Signed-off-by: Pere Diaz Bou --- diff --git a/src/pybind/mgr/dashboard/controllers/rbd.py b/src/pybind/mgr/dashboard/controllers/rbd.py index 99c48e21b88..9a499f92016 100644 --- a/src/pybind/mgr/dashboard/controllers/rbd.py +++ b/src/pybind/mgr/dashboard/controllers/rbd.py @@ -27,7 +27,6 @@ from . import APIDoc, APIRouter, BaseController, CreatePermission, \ logger = logging.getLogger(__name__) RBD_SCHEMA = ([{ - "status": (int, 'Status of the image'), "value": ([str], ''), "pool_name": (str, 'pool name') }]) @@ -92,7 +91,7 @@ class Rbd(RESTController): for i, image in enumerate(images): pool = image['pool'] if pool not in pool_result: - pool_result[pool] = {'status': 1, 'value': [], 'pool_name': image['pool']} + pool_result[pool] = {'value': [], 'pool_name': image['pool']} pool_result[pool]['value'].append(image) images[i]['configuration'] = RbdConfiguration( diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts index 10475872a2e..9f2738bbd48 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.spec.ts @@ -89,9 +89,8 @@ describe('IscsiTargetFormComponent', () => { }; const RBD_LIST: any[] = [ - { status: 0, value: [], pool_name: 'ganesha' }, + { value: [], pool_name: 'ganesha' }, { - status: 0, value: [ { size: 96636764160, @@ -168,7 +167,7 @@ describe('IscsiTargetFormComponent', () => { httpTesting.expectOne('ui-api/iscsi/settings').flush(SETTINGS); httpTesting.expectOne('ui-api/iscsi/portals').flush(PORTALS); httpTesting.expectOne('ui-api/iscsi/version').flush(VERSION); - httpTesting.expectOne('api/block/image').flush(RBD_LIST); + httpTesting.expectOne('api/block/image?offset=0&limit=-1').flush(RBD_LIST); httpTesting.expectOne('api/iscsi/target').flush(LIST_TARGET); httpTesting.verify(); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts index 115987f0315..bf9e73ccbe5 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/iscsi-target-form/iscsi-target-form.component.ts @@ -15,6 +15,7 @@ import { Icons } from '~/app/shared/enum/icons.enum'; import { CdForm } from '~/app/shared/forms/cd-form'; import { CdFormGroup } from '~/app/shared/forms/cd-form-group'; import { CdValidators } from '~/app/shared/forms/cd-validators'; +import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context'; import { FinishedTask } from '~/app/shared/models/finished-task'; import { ModalService } from '~/app/shared/services/modal.service'; import { TaskWrapperService } from '~/app/shared/services/task-wrapper.service'; @@ -86,9 +87,13 @@ export class IscsiTargetFormComponent extends CdForm implements OnInit { } ngOnInit() { + const rbdListContext = new CdTableFetchDataContext(() => {}); + /* limit -1 to specify all images */ + rbdListContext.pageInfo.limit = -1; const promises: any[] = [ this.iscsiService.listTargets(), - this.rbdService.list({ offset: 0, limit: 5 }), + /* tslint:disable:no-empty */ + this.rbdService.list(rbdListContext.toParams()), this.iscsiService.portals(), this.iscsiService.settings(), this.iscsiService.version() diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html index f3d58703419..004ff22c3a4 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.html @@ -12,7 +12,7 @@ selectionType="single" [hasDetails]="true" [status]="tableStatus" - [autoReload]="5000" + [autoReload]="-1" (fetchData)="taskListService.fetch($event)" (setExpandedRow)="setExpandedRow($event)" (updateSelection)="updateSelection($event)"> diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts index f192d25e6f7..c2ce6b87f8b 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.spec.ts @@ -8,9 +8,7 @@ import { ToastrModule } from 'ngx-toastr'; import { BehaviorSubject, of } from 'rxjs'; import { RbdService } from '~/app/shared/api/rbd.service'; -import { TableStatusViewCache } from '~/app/shared/classes/table-status-view-cache'; import { TableActionsComponent } from '~/app/shared/datatable/table-actions/table-actions.component'; -import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum'; import { ExecutingTask } from '~/app/shared/models/executing-task'; import { SummaryService } from '~/app/shared/services/summary.service'; import { TaskListService } from '~/app/shared/services/task-list.service'; @@ -88,9 +86,6 @@ describe('RbdListComponent', () => { spyOn(component.table, 'reset'); summaryService['summaryDataSource'].error(undefined); expect(component.table.reset).toHaveBeenCalled(); - expect(component.tableStatus).toEqual( - new TableStatusViewCache(ViewCacheStatus.ValueException) - ); }); }); @@ -121,7 +116,7 @@ describe('RbdListComponent', () => { }); it('should display N/A for Provisioned & Total Provisioned columns if disk usage is null', () => { - rbdServiceListSpy.and.callFake(() => of([{ pool_name: 'rbd', status: 1, value: images }])); + rbdServiceListSpy.and.callFake(() => of([{ pool_name: 'rbd', value: images }])); fixture.detectChanges(); const spanWithoutFastDiff = fixture.debugElement.nativeElement.querySelectorAll( '.datatable-body-cell-label span' @@ -133,7 +128,7 @@ describe('RbdListComponent', () => { component.images = images; refresh({ executing_tasks: [], finished_tasks: [] }); - rbdServiceListSpy.and.callFake(() => of([{ pool_name: 'rbd', status: 1, value: images }])); + rbdServiceListSpy.and.callFake(() => of([{ pool_name: 'rbd', value: images }])); fixture.detectChanges(); const spanWithFastDiff = fixture.debugElement.nativeElement.querySelectorAll( @@ -257,9 +252,7 @@ describe('RbdListComponent', () => { addImage('c'); component.images = images; refresh({ executing_tasks: [], finished_tasks: [] }); - spyOn(rbdService, 'list').and.callFake(() => - of([{ pool_name: 'rbd', status: 1, value: images }]) - ); + spyOn(rbdService, 'list').and.callFake(() => of([{ pool_name: 'rbd', value: images }])); fixture.detectChanges(); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts index 15aa06ab896..f9729ad5f49 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/block/rbd-list/rbd-list.component.ts @@ -12,7 +12,6 @@ import { CriticalConfirmationModalComponent } from '~/app/shared/components/crit import { ActionLabelsI18n } from '~/app/shared/constants/app.constants'; import { TableComponent } from '~/app/shared/datatable/table/table.component'; import { Icons } from '~/app/shared/enum/icons.enum'; -import { ViewCacheStatus } from '~/app/shared/enum/view-cache-status.enum'; import { CdTableAction } from '~/app/shared/models/cd-table-action'; import { CdTableColumn } from '~/app/shared/models/cd-table-column'; import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context'; @@ -361,7 +360,6 @@ export class RbdListComponent extends ListWithDetails implements OnInit { onFetchError() { this.table.reset(); // Disable loading indicator. - this.tableStatus = new TableStatusViewCache(ViewCacheStatus.ValueException); } getRbdImages(context: CdTableFetchDataContext = null) { @@ -615,26 +613,3 @@ export class RbdListComponent extends ListWithDetails implements OnInit { return false; } } - -/* - for pool in pools - for namespace in namespaces - refs = get_image_refs - for ref in refs: - get_data(ref) - -@ttl_cache(5) -def get_refs(); - joint_refs = [] - for pool in pools - for namespace in namespaces - refs = get_image_refs - for ref in refs: - joint_refs.append(ref) - return joint_refs - -sort(joint_refs) - for ref in joint_refs[offset:offset+limit]: -get_data(ref) - -*/ diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts index a66d861e464..dc51614ffed 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/api/rbd.service.spec.ts @@ -1,6 +1,7 @@ import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; import { TestBed } from '@angular/core/testing'; +import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context'; import { configureTestBed } from '~/testing/unit-test-helper'; import { ImageSpec } from '../models/image-spec'; import { RbdConfigurationService } from '../services/rbd-configuration.service'; @@ -55,8 +56,10 @@ describe('RbdService', () => { }); it('should call list', () => { - service.list().subscribe(); - const req = httpTesting.expectOne('api/block/image'); + /* tslint:disable:no-empty */ + const context = new CdTableFetchDataContext(() => {}); + service.list(context.toParams()).subscribe(); + const req = httpTesting.expectOne('api/block/image?offset=0&limit=10'); expect(req.request.method).toBe('GET'); }); diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html index 0042d9f2757..2c19dfbd237 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.html @@ -172,8 +172,8 @@ [rowClass]="getRowClass()" [headerHeight]="header ? 'auto' : 0" [footerHeight]="footer ? 'auto' : 0" - [count]="count" - [externalPaging]="serverSide" + [count]="count" + [externalPaging]="serverSide" [limit]="userConfig.limit > 0 ? userConfig.limit : undefined" [offset]="userConfig.offset >= 0 ? userConfig.offset : 0" (page)="changePage($event)" diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts index 6099d82d1a5..e09aa7687ab 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/datatable/table/table.component.ts @@ -32,10 +32,10 @@ import { CdTableColumn } from '~/app/shared/models/cd-table-column'; import { CdTableColumnFilter } from '~/app/shared/models/cd-table-column-filter'; import { CdTableColumnFiltersChange } from '~/app/shared/models/cd-table-column-filters-change'; import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context'; +import { PageInfo } from '~/app/shared/models/cd-table-paging'; import { CdTableSelection } from '~/app/shared/models/cd-table-selection'; import { CdUserConfig } from '~/app/shared/models/cd-user-config'; import { TimerService } from '~/app/shared/services/timer.service'; -import { PageInfo } from '../../models/cd-table-paging'; @Component({ selector: 'cd-table', diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.ts index c4c08039650..f302a6896f3 100644 --- a/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.ts +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/services/cd-table-server-side.service.ts @@ -5,6 +5,7 @@ import { Injectable } from '@angular/core'; providedIn: 'root' }) export class CdTableServerSideService { + /* tslint:disable:no-empty */ constructor() {} static getCount(resp: HttpResponse): number { diff --git a/src/pybind/mgr/dashboard/openapi.yaml b/src/pybind/mgr/dashboard/openapi.yaml index 2d24c7a2493..2889bbea646 100644 --- a/src/pybind/mgr/dashboard/openapi.yaml +++ b/src/pybind/mgr/dashboard/openapi.yaml @@ -154,6 +154,18 @@ paths: name: pool_name schema: type: string + - default: 0 + description: offset + in: query + name: offset + schema: + type: integer + - default: 5 + description: limit + in: query + name: limit + schema: + type: integer responses: '200': content: @@ -164,9 +176,6 @@ paths: pool_name: description: pool name type: string - status: - description: Status of the image - type: integer value: description: '' items: @@ -174,7 +183,6 @@ paths: type: array type: object required: - - status - value - pool_name type: array diff --git a/src/pybind/mgr/dashboard/services/rbd.py b/src/pybind/mgr/dashboard/services/rbd.py index eec5a6277cc..25b9a919779 100644 --- a/src/pybind/mgr/dashboard/services/rbd.py +++ b/src/pybind/mgr/dashboard/services/rbd.py @@ -9,7 +9,6 @@ import rbd from .. import mgr from ..exceptions import DashboardException -from ..tools import ViewCache from .ceph_service import CephService try: @@ -413,7 +412,6 @@ class RbdService(object): rbd_inst = rbd.RBD() for pool in pool_names: with mgr.rados.open_ioctx(pool) as ioctx: - result = [] if namespace: namespaces = [namespace] else: @@ -433,7 +431,9 @@ class RbdService(object): def rbd_pool_list(cls, pool_names: List[str], namespace=None, offset=0, limit=0): offset = int(offset) limit = int(limit) - if limit < 0: + # let's use -1 to denotate we want ALL images for now. Iscsi currently gathers + # all images therefore, we need this. + if limit < -1: return [] refs = cls._rbd_pool_image_refs(pool_names, namespace) @@ -441,9 +441,12 @@ class RbdService(object): # transform to list so that we can count for i in refs: image_refs.append(i) - + result = [] - for image_ref in sorted(image_refs, key=lambda v: v['name'])[offset:offset+limit]: + end = offset + limit + if limit == -1: + end = len(image_refs) + for image_ref in sorted(image_refs, key=lambda v: v['name'])[offset:end]: with mgr.rados.open_ioctx(image_ref['pool']) as ioctx: ioctx.set_namespace(image_ref['namespace']) try: diff --git a/src/pybind/mgr/dashboard/tests/test_rbd_service.py b/src/pybind/mgr/dashboard/tests/test_rbd_service.py index 89b062a7c91..64382d92913 100644 --- a/src/pybind/mgr/dashboard/tests/test_rbd_service.py +++ b/src/pybind/mgr/dashboard/tests/test_rbd_service.py @@ -129,17 +129,18 @@ class RbdServiceTest(unittest.TestCase): 'namespace': '' } - rbd_pool_list = RbdService.rbd_pool_list('test_pool') - self.assertEqual(rbd_pool_list, (0, [{ + rbd_pool_list = RbdService.rbd_pool_list(['test_pool'], offset=0, limit=5) + self.assertEqual(rbd_pool_list, ([{ 'id': '3c1a5ee60a88', 'unique_id': 'test_pool/3c1a5ee60a88', 'name': 'test_rbd', 'source': 'REMOVING', 'deletion_time': '{}Z'.format(time.isoformat()), 'deferment_end_time': '{}Z'.format(time.isoformat()), + 'pool': 'test_pool', 'pool_name': 'test_pool', 'namespace': '' - }])) + }], 1)) def test_valid_interval(self): test_cases = [