mirror of
https://github.com/ceph/ceph
synced 2025-02-24 03:27:10 +00:00
Merge pull request #46433 from rhcs-dashboard/rbd-mirroring-replay
mgr/dashboard: move replaying images to Syncing tab Reviewed-by: Avan Thakkar <athakkar@redhat.com> Reviewed-by: Ernesto Puerta <epuertat@redhat.com> Reviewed-by: Ilya Dryomov <idryomov@redhat.com> Reviewed-by: nSedrickm <NOT@FOUND>
This commit is contained in:
commit
bf5c7ff65e
@ -4,7 +4,7 @@ import json
|
||||
import logging
|
||||
import re
|
||||
from functools import partial
|
||||
from typing import no_type_check
|
||||
from typing import NamedTuple, Optional, no_type_check
|
||||
|
||||
import cherrypy
|
||||
import rbd
|
||||
@ -199,6 +199,13 @@ def get_daemons_and_pools(): # pylint: disable=R0915
|
||||
}
|
||||
|
||||
|
||||
class ReplayingData(NamedTuple):
|
||||
bytes_per_second: Optional[int] = None
|
||||
seconds_until_synced: Optional[int] = None
|
||||
syncing_percent: Optional[float] = None
|
||||
entries_behind_primary: Optional[int] = None
|
||||
|
||||
|
||||
@ViewCache()
|
||||
@no_type_check
|
||||
def _get_pool_datum(pool_name):
|
||||
@ -228,15 +235,17 @@ def _get_pool_datum(pool_name):
|
||||
'state': 'Error'
|
||||
},
|
||||
rbd.MIRROR_IMAGE_STATUS_STATE_SYNCING: {
|
||||
'health': 'syncing'
|
||||
'health': 'syncing',
|
||||
'state_color': 'success',
|
||||
'state': 'Syncing'
|
||||
},
|
||||
rbd.MIRROR_IMAGE_STATUS_STATE_STARTING_REPLAY: {
|
||||
'health': 'ok',
|
||||
'health': 'syncing',
|
||||
'state_color': 'success',
|
||||
'state': 'Starting'
|
||||
},
|
||||
rbd.MIRROR_IMAGE_STATUS_STATE_REPLAYING: {
|
||||
'health': 'ok',
|
||||
'health': 'syncing',
|
||||
'state_color': 'success',
|
||||
'state': 'Replaying'
|
||||
},
|
||||
@ -248,8 +257,9 @@ def _get_pool_datum(pool_name):
|
||||
rbd.MIRROR_IMAGE_STATUS_STATE_STOPPED: {
|
||||
'health': 'ok',
|
||||
'state_color': 'info',
|
||||
'state': 'Primary'
|
||||
'state': 'Stopped'
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
rbdctx = rbd.RBD()
|
||||
@ -271,6 +281,29 @@ def _get_pool_datum(pool_name):
|
||||
return data
|
||||
|
||||
|
||||
def _update_syncing_image_data(mirror_image, image):
|
||||
if mirror_image['state'] == 'Replaying':
|
||||
p = re.compile("replaying, ({.*})")
|
||||
replaying_data = p.findall(mirror_image['description'])
|
||||
assert len(replaying_data) == 1
|
||||
replaying_data = json.loads(replaying_data[0])
|
||||
if 'replay_state' in replaying_data and replaying_data['replay_state'] == 'idle':
|
||||
image.update({
|
||||
'state_color': 'info',
|
||||
'state': 'Idle'
|
||||
})
|
||||
for field in ReplayingData._fields:
|
||||
try:
|
||||
image[field] = replaying_data[field]
|
||||
except KeyError:
|
||||
pass
|
||||
else:
|
||||
p = re.compile("bootstrapping, IMAGE_COPY/COPY_OBJECT (.*)%")
|
||||
image.update({
|
||||
'progress': (p.findall(mirror_image['description']) or [0])[0]
|
||||
})
|
||||
|
||||
|
||||
@ViewCache()
|
||||
def _get_content_data(): # pylint: disable=R0914
|
||||
pool_names = [pool['pool_name'] for pool in CephService.get_pool_list('rbd')
|
||||
@ -296,26 +329,21 @@ def _get_content_data(): # pylint: disable=R0914
|
||||
for mirror_image in mirror_images:
|
||||
image = {
|
||||
'pool_name': pool_name,
|
||||
'name': mirror_image['name']
|
||||
'name': mirror_image['name'],
|
||||
'state_color': mirror_image['state_color'],
|
||||
'state': mirror_image['state']
|
||||
}
|
||||
|
||||
if mirror_image['health'] == 'ok':
|
||||
image.update({
|
||||
'state_color': mirror_image['state_color'],
|
||||
'state': mirror_image['state'],
|
||||
'description': mirror_image['description']
|
||||
})
|
||||
image_ready.append(image)
|
||||
elif mirror_image['health'] == 'syncing':
|
||||
p = re.compile("bootstrapping, IMAGE_COPY/COPY_OBJECT (.*)%")
|
||||
image.update({
|
||||
'progress': (p.findall(mirror_image['description']) or [0])[0]
|
||||
})
|
||||
_update_syncing_image_data(mirror_image, image)
|
||||
image_syncing.append(image)
|
||||
else:
|
||||
image.update({
|
||||
'state_color': mirror_image['state_color'],
|
||||
'state': mirror_image['state'],
|
||||
'description': mirror_image['description']
|
||||
})
|
||||
image_error.append(image)
|
||||
|
@ -20,9 +20,9 @@ describe('Mirroring page', () => {
|
||||
});
|
||||
|
||||
it('should show text for all tabs', () => {
|
||||
mirroring.getTabText(0).should('eq', 'Issues');
|
||||
mirroring.getTabText(1).should('eq', 'Syncing');
|
||||
mirroring.getTabText(2).should('eq', 'Ready');
|
||||
mirroring.getTabText(0).should('eq', 'Issues (0)');
|
||||
mirroring.getTabText(1).should('eq', 'Syncing (0)');
|
||||
mirroring.getTabText(2).should('eq', 'Ready (0)');
|
||||
});
|
||||
|
||||
describe('checks that edit mode functionality shows in the pools table', () => {
|
||||
|
@ -4,7 +4,7 @@
|
||||
cdStatefulTab="image-list">
|
||||
<li ngbNavItem="issues">
|
||||
<a ngbNavLink
|
||||
i18n>Issues</a>
|
||||
i18n>Issues ({{ image_error.data.length }})</a>
|
||||
<ng-template ngbNavContent>
|
||||
<cd-table [data]="image_error.data"
|
||||
columnMode="flex"
|
||||
@ -17,7 +17,7 @@
|
||||
</li>
|
||||
<li ngbNavItem="syncing">
|
||||
<a ngbNavLink
|
||||
i18n>Syncing</a>
|
||||
i18n>Syncing ({{ image_syncing.data.length }})</a>
|
||||
<ng-template ngbNavContent>
|
||||
<cd-table [data]="image_syncing.data"
|
||||
columnMode="flex"
|
||||
@ -30,7 +30,7 @@
|
||||
</li>
|
||||
<li ngbNavItem="ready">
|
||||
<a ngbNavLink
|
||||
i18n>Ready</a>
|
||||
i18n>Ready ({{ image_ready.data.length }})</a>
|
||||
<ng-template ngbNavContent>
|
||||
<cd-table [data]="image_ready.data"
|
||||
columnMode="flex"
|
||||
@ -51,14 +51,13 @@
|
||||
<span [ngClass]="row.state_color | mirrorHealthColor">{{ value }}</span>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #syncTmpl>
|
||||
<span class="badge badge-info"
|
||||
i18n>Syncing</span>
|
||||
</ng-template>
|
||||
|
||||
<ng-template #progressTmpl
|
||||
let-row="row"
|
||||
let-value="value">
|
||||
<ngb-progressbar type="info"
|
||||
<div *ngIf="row.state === 'Replaying'">
|
||||
</div>
|
||||
<ngb-progressbar *ngIf="row.state === 'Syncing'"
|
||||
type="info"
|
||||
[value]="value"
|
||||
[showValue]="true"></ngb-progressbar>
|
||||
</ng-template>
|
||||
|
@ -41,42 +41,44 @@ export class ImageListComponent implements OnInit, OnDestroy {
|
||||
this.image_error.columns = [
|
||||
{ prop: 'pool_name', name: $localize`Pool`, flexGrow: 2 },
|
||||
{ prop: 'name', name: $localize`Image`, flexGrow: 2 },
|
||||
{ prop: 'description', name: $localize`Issue`, flexGrow: 4 },
|
||||
{
|
||||
prop: 'state',
|
||||
name: $localize`State`,
|
||||
cellTemplate: this.stateTmpl,
|
||||
flexGrow: 1
|
||||
}
|
||||
},
|
||||
{ prop: 'description', name: $localize`Issue`, flexGrow: 4 }
|
||||
];
|
||||
|
||||
this.image_syncing.columns = [
|
||||
{ prop: 'pool_name', name: $localize`Pool`, flexGrow: 2 },
|
||||
{ prop: 'name', name: $localize`Image`, flexGrow: 2 },
|
||||
{
|
||||
prop: 'state',
|
||||
name: $localize`State`,
|
||||
cellTemplate: this.stateTmpl,
|
||||
flexGrow: 1
|
||||
},
|
||||
{
|
||||
prop: 'progress',
|
||||
name: $localize`Progress`,
|
||||
cellTemplate: this.progressTmpl,
|
||||
flexGrow: 2
|
||||
},
|
||||
{
|
||||
prop: 'state',
|
||||
name: $localize`State`,
|
||||
cellTemplate: this.syncTmpl,
|
||||
flexGrow: 1
|
||||
}
|
||||
{ prop: 'bytes_per_second', name: $localize`Bytes per second`, flexGrow: 2 },
|
||||
{ prop: 'entries_behind_primary', name: $localize`Entries behind primary`, flexGrow: 2 }
|
||||
];
|
||||
|
||||
this.image_ready.columns = [
|
||||
{ prop: 'pool_name', name: $localize`Pool`, flexGrow: 2 },
|
||||
{ prop: 'name', name: $localize`Image`, flexGrow: 2 },
|
||||
{ prop: 'description', name: $localize`Description`, flexGrow: 4 },
|
||||
{
|
||||
prop: 'state',
|
||||
name: $localize`State`,
|
||||
cellTemplate: this.stateTmpl,
|
||||
flexGrow: 1
|
||||
}
|
||||
},
|
||||
{ prop: 'description', name: $localize`Description`, flexGrow: 4 }
|
||||
];
|
||||
|
||||
this.subs = this.rbdMirroringService.subscribeSummary((data) => {
|
||||
|
Loading…
Reference in New Issue
Block a user