Skip to content

Commit

Permalink
feat(VDiskPage): add force evict (#1093)
Browse files Browse the repository at this point in the history
  • Loading branch information
artemmufazalov authored Jul 31, 2024
1 parent 8b2fb41 commit 97dfcfb
Show file tree
Hide file tree
Showing 5 changed files with 62 additions and 45 deletions.
9 changes: 6 additions & 3 deletions src/containers/PDiskPage/PDiskPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -81,9 +81,12 @@ export function PDiskPage() {

const handleRestart = async (isRetry?: boolean) => {
if (pDiskParamsDefined) {
return window.api.restartPDisk({nodeId, pDiskId, force: isRetry}).then((res) => {
if (res?.result === false) {
const err = {statusText: res.error, retryPossible: res.forceRetryPossible};
return window.api.restartPDisk({nodeId, pDiskId, force: isRetry}).then((response) => {
if (response?.result === false) {
const err = {
statusText: response.error,
retryPossible: response.forceRetryPossible,
};
throw err;
}
});
Expand Down
49 changes: 30 additions & 19 deletions src/containers/VDiskPage/VDiskPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -56,24 +56,34 @@ export function VDiskPage() {
const loading = isFetching && currentData === undefined;
const {vDiskData = {}, groupData} = currentData || {};
const {NodeHost, NodeId, NodeType, NodeDC, PDiskId, PDiskType, Severity, VDiskId} = vDiskData;

const handleEvictVDisk = async () => {
const {GroupID, GroupGeneration, Ring, Domain, VDisk} = VDiskId || {};

if (
valueIsDefined(GroupID) &&
valueIsDefined(GroupGeneration) &&
valueIsDefined(Ring) &&
valueIsDefined(Domain) &&
valueIsDefined(VDisk)
) {
return window.api.evictVDisk({
groupId: GroupID,
groupGeneration: GroupGeneration,
failRealmIdx: Ring,
failDomainIdx: Domain,
vDiskIdx: VDisk,
});
const {GroupID, GroupGeneration, Ring, Domain, VDisk} = VDiskId || {};
const vDiskIdParamsDefined =
valueIsDefined(GroupID) &&
valueIsDefined(GroupGeneration) &&
valueIsDefined(Ring) &&
valueIsDefined(Domain) &&
valueIsDefined(VDisk);

const handleEvictVDisk = async (isRetry?: boolean) => {
if (vDiskIdParamsDefined) {
return window.api
.evictVDisk({
groupId: GroupID,
groupGeneration: GroupGeneration,
failRealmIdx: Ring,
failDomainIdx: Domain,
vDiskIdx: VDisk,
force: isRetry,
})
.then((response) => {
if (response?.result === false) {
const err = {
statusText: response.error,
retryPossible: response.forceRetryPossible,
};
throw err;
}
});
}

return undefined;
Expand Down Expand Up @@ -131,9 +141,10 @@ export function VDiskPage() {
<ButtonWithConfirmDialog
onConfirmAction={handleEvictVDisk}
onConfirmActionSuccess={handleAfterEvictVDisk}
buttonDisabled={!VDiskId || !isUserAllowedToMakeChanges}
buttonDisabled={!vDiskIdParamsDefined || !isUserAllowedToMakeChanges}
buttonView="normal"
dialogContent={vDiskPageKeyset('evict-vdisk-dialog')}
retryButtonText={vDiskPageKeyset('force-evict-vdisk-button')}
withPopover
popoverContent={vDiskPageKeyset('evict-vdisk-not-allowed')}
popoverDisabled={isUserAllowedToMakeChanges}
Expand Down
1 change: 1 addition & 0 deletions src/containers/VDiskPage/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
"group": "Group",

"evict-vdisk-button": "Evict VDisk",
"force-evict-vdisk-button": "Evict anyway",
"evict-vdisk-dialog": "VDisk will be evicted. Do you want to proceed?",
"evict-vdisk-not-allowed": "You don't have enough rights to evict VDisk"
}
43 changes: 21 additions & 22 deletions src/services/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import AxiosWrapper from '@gravity-ui/axios-wrapper';
import type {AxiosWrapperOptions} from '@gravity-ui/axios-wrapper';
import type {AxiosRequestConfig} from 'axios';
import axiosRetry from 'axios-retry';
import qs from 'qs';

import {backend as BACKEND, metaBackend as META_BACKEND} from '../store';
import type {ComputeApiRequestParams, NodesApiRequestParams} from '../store/reducers/nodes/types';
Expand All @@ -14,13 +15,13 @@ import type {DescribeConsumerResult} from '../types/api/consumer';
import type {HealthCheckAPIResponse} from '../types/api/healthcheck';
import type {JsonHotKeysResponse} from '../types/api/hotkeys';
import type {MetaCluster, MetaClusters, MetaTenants} from '../types/api/meta';
import type {ModifyDiskResponse} from '../types/api/modifyDisk';
import type {TNetInfo} from '../types/api/netInfo';
import type {TNodesInfo} from '../types/api/nodes';
import type {TEvNodesInfo} from '../types/api/nodesList';
import type {TEvPDiskStateResponse, TPDiskInfoResponse} from '../types/api/pdisk';
import type {Actions, ErrorResponse, QueryAPIResponse, Schemas} from '../types/api/query';
import type {JsonRenderRequestParams, JsonRenderResponse} from '../types/api/render';
import type {RestartPDiskResponse} from '../types/api/restartPDisk';
import type {TEvDescribeSchemeResult} from '../types/api/schema';
import type {TStorageInfo} from '../types/api/storage';
import type {TEvSystemStateResponse} from '../types/api/systemState';
Expand Down Expand Up @@ -500,36 +501,34 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
failRealmIdx,
failDomainIdx,
vDiskIdx,
force,
}: {
groupId: string | number;
groupGeneration: string | number;
failRealmIdx: string | number;
failDomainIdx: string | number;
vDiskIdx: string | number;
force?: boolean;
}) {
// BSC Id is constant for all ydb clusters
const BSC_TABLET_ID = '72057594037932033';
const params = {
group_id: groupId,
group_generation_id: groupGeneration,
fail_realm_idx: failRealmIdx,
fail_domain_idx: failDomainIdx,
vdisk_idx: vDiskIdx,

return this.post(
this.getPath(`/tablets/app?TabletID=${BSC_TABLET_ID}&exec=1`),
{
Command: {
ReassignGroupDisk: {
GroupId: groupId,
GroupGeneration: groupGeneration,
FailRealmIdx: failRealmIdx,
FailDomainIdx: failDomainIdx,
VDiskIdx: vDiskIdx,
},
},
},
force,
};

const paramsString = qs.stringify(params);

const path = this.getPath(`/vdisk/evict?${paramsString}`);

return this.post<ModifyDiskResponse>(
path,
{},
{},
{
headers: {
// This handler requires exactly this string
// Automatic headers may not suit
Accept: 'application/json',
},
requestConfig: {'axios-retry': {retries: 0}},
},
);
Expand All @@ -543,7 +542,7 @@ export class YdbEmbeddedAPI extends AxiosWrapper {
pDiskId: number | string;
force?: boolean;
}) {
return this.post<RestartPDiskResponse>(
return this.post<ModifyDiskResponse>(
this.getPath(`/pdisk/restart?node_id=${nodeId}&pdisk_id=${pDiskId}&force=${force}`),
{},
{},
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
export interface RestartPDiskResponse {
/**
* endpoints: pdisk/restart and vdiks/evict
*/
export interface ModifyDiskResponse {
// true if successful, false if not
result?: boolean;
// Error message
Expand Down

0 comments on commit 97dfcfb

Please sign in to comment.