From 6f5816efe9ebc3d71713769e07c7ae3f7b48194a Mon Sep 17 00:00:00 2001 From: "Jingwei.Zhang" Date: Thu, 16 Sep 2021 11:18:05 +0800 Subject: [PATCH] fix: Update instance check for attach/detach volume Update instance check for attach/detach volume Change-Id: Ie6396b2b9c42d424d0396f9c840fb6182ebd45e5 --- .../Instance/actions/AttachVolume.jsx | 15 +------ .../Instance/actions/DetachVolume.jsx | 21 +++------- .../containers/Volume/actions/Attach.jsx | 13 +----- .../containers/Volume/actions/Detach.jsx | 42 +++++++++---------- src/resources/instance.jsx | 34 ++++++++++++++- src/stores/skyline/server-group-instance.js | 6 ++- 6 files changed, 68 insertions(+), 63 deletions(-) diff --git a/src/pages/compute/containers/Instance/actions/AttachVolume.jsx b/src/pages/compute/containers/Instance/actions/AttachVolume.jsx index 5ac960dc..58d9e14f 100644 --- a/src/pages/compute/containers/Instance/actions/AttachVolume.jsx +++ b/src/pages/compute/containers/Instance/actions/AttachVolume.jsx @@ -15,12 +15,7 @@ import { inject, observer } from 'mobx-react'; import globalServerStore from 'stores/nova/instance'; import { ModalAction } from 'containers/Action'; -import { - isActive, - isNotDeleting, - isNotLocked, - isIronicInstance, -} from 'resources/instance'; +import { allowAttachVolumeInstance } from 'resources/instance'; import { multiTip } from 'resources/volume'; import { get as _get } from 'lodash'; @@ -61,13 +56,7 @@ export class AttachVolume extends ModalAction { static allowed = (item, containerProps) => { const { isAdminPage } = containerProps; - return Promise.resolve( - !isAdminPage && - isActive(item) && - isNotDeleting(item) && - isNotLocked(item) && - !isIronicInstance(item) - ); + return Promise.resolve(!isAdminPage && allowAttachVolumeInstance(item)); }; get formItems() { diff --git a/src/pages/compute/containers/Instance/actions/DetachVolume.jsx b/src/pages/compute/containers/Instance/actions/DetachVolume.jsx index cf373f5e..2bf95ee6 100644 --- a/src/pages/compute/containers/Instance/actions/DetachVolume.jsx +++ b/src/pages/compute/containers/Instance/actions/DetachVolume.jsx @@ -17,12 +17,7 @@ import { VolumeStore } from 'stores/cinder/volume'; import globalServerStore from 'stores/nova/instance'; import { ModalAction } from 'containers/Action'; import { volumeStatus, isOsDisk } from 'resources/volume'; -import { - isActive, - isNotLocked, - isNotDeleting, - isIronicInstance, -} from 'resources/instance'; +import { allowAttachVolumeInstance } from 'resources/instance'; export class DetachVolume extends ModalAction { static id = 'detach-volume'; @@ -66,16 +61,10 @@ export class DetachVolume extends ModalAction { static policy = 'os_compute_api:os-volumes-attachments:delete'; - // static hasDataVolume = item => item.volumes_attached && item.volumes_attached.length > 1 - - // static allowed = item => Promise.resolve(isActive(item) && isNotDeleting(item) && isNotLocked(item) && this.hasDataVolume(item)) - static allowed = (item) => - Promise.resolve( - isActive(item) && - isNotDeleting(item) && - isNotLocked(item) && - !isIronicInstance(item) - ); + static allowed = (item, containerProps) => { + const { isAdminPage } = containerProps; + return Promise.resolve(!isAdminPage && allowAttachVolumeInstance(item)); + }; get formItems() { return [ diff --git a/src/pages/storage/containers/Volume/actions/Attach.jsx b/src/pages/storage/containers/Volume/actions/Attach.jsx index 5611e8af..850e8486 100644 --- a/src/pages/storage/containers/Volume/actions/Attach.jsx +++ b/src/pages/storage/containers/Volume/actions/Attach.jsx @@ -17,10 +17,7 @@ import { ModalAction } from 'containers/Action'; import { ServerStore } from 'stores/nova/instance'; import globalVolumeStore from 'stores/cinder/volume'; import { - isActive, - isNotDeleting, - isNotLockedOrAdmin, - isIronicInstance, + allowAttachVolumeInstance, instanceSelectTablePropsBackend, } from 'resources/instance'; import { isAvailable, isMultiAttach } from 'resources/volume'; @@ -51,12 +48,7 @@ export class Attach extends ModalAction { return 'large'; } - disabledInstance = (ins) => - !isActive(ins) || - !isNotDeleting(ins) || - !isNotLockedOrAdmin(ins) || - this.alreadyAttached(ins) || - isIronicInstance(ins); + disabledInstance = (ins) => !allowAttachVolumeInstance(ins); get defaultValue() { const { name, id, size, volume_type } = this.item; @@ -78,7 +70,6 @@ export class Attach extends ModalAction { Promise.resolve(isAvailable(item) || isMultiAttach(item)); get formItems() { - // const { multiattach } = this.item; return [ { name: 'volume', diff --git a/src/pages/storage/containers/Volume/actions/Detach.jsx b/src/pages/storage/containers/Volume/actions/Detach.jsx index 1ddb77c7..4f1d1439 100644 --- a/src/pages/storage/containers/Volume/actions/Detach.jsx +++ b/src/pages/storage/containers/Volume/actions/Detach.jsx @@ -16,7 +16,12 @@ import { inject, observer } from 'mobx-react'; import { ModalAction } from 'containers/Action'; import globalServerStore from 'stores/nova/instance'; +import { ServerGroupInstanceStore } from 'stores/skyline/server-group-instance'; import { isInUse, isOsDisk } from 'resources/volume'; +import { + instanceColumnsBackend, + allowAttachVolumeInstance, +} from 'resources/instance'; export class Detach extends ModalAction { static id = 'detach'; @@ -31,6 +36,8 @@ export class Detach extends ModalAction { init() { this.store = globalServerStore; + this.instanceStore = new ServerGroupInstanceStore(); + this.getInstances(); } static get modalSize() { @@ -40,13 +47,15 @@ export class Detach extends ModalAction { getModalSize() { return 'large'; } - // get instances() { - // return this.store.list.data || []; - // } - // async getInstances() { - // await this.store.fetchList({ limit: Infinity }); - // } + get instances() { + return this.instanceStore.list.data || []; + } + + getInstances() { + const members = (this.item.attachments || []).map((it) => it.server_id); + this.instanceStore.fetchList({ members }); + } get defaultValue() { const { name, size, volume_type } = this.item; @@ -66,6 +75,8 @@ export class Detach extends ModalAction { item.attachments.length ); + disabledInstance = (ins) => !allowAttachVolumeInstance(ins); + get formItems() { return [ { @@ -79,11 +90,7 @@ export class Detach extends ModalAction { label: t('Instance'), type: 'select-table', required: true, - data: (this.item.attachments || []).map((s) => ({ - ...s, - name: s.server_name, - id: s.server_id, - })), + data: this.instances, isMulti: true, filterParams: [ { @@ -91,16 +98,9 @@ export class Detach extends ModalAction { name: 'name', }, ], - columns: [ - { - title: t('Name'), - dataIndex: 'name', - }, - { - title: t('Attached To'), - dataIndex: 'device', - }, - ], + columns: instanceColumnsBackend, + isLoading: this.instanceStore.list.isLoading, + disabledFunc: this.disabledInstance, }, ]; } diff --git a/src/resources/instance.jsx b/src/resources/instance.jsx index 6c131f86..c94c566c 100644 --- a/src/resources/instance.jsx +++ b/src/resources/instance.jsx @@ -309,7 +309,6 @@ export const instanceColumnsBackend = [ render: (value, record) => ( ), - stringify: (_, record) => record.image_name, }, { title: t('Fixed IP'), @@ -350,6 +349,18 @@ export const instanceColumnsBackend = [ dataIndex: 'flavor', sorter: false, }, + { + title: t('Status'), + dataIndex: 'status', + sorter: false, + render: (value) => instanceStatus[value && value.toLowerCase()] || '-', + }, + { + title: t('Locked'), + dataIndex: 'locked', + isHideable: true, + render: lockRender, + }, { title: t('Created At'), dataIndex: 'created_at', @@ -379,6 +390,27 @@ export const instanceSelectTablePropsBackend = { export const canCreateIronicByLicense = () => globalRootStore.checkLicense('ironic'); +export const allowAttachVolumeInstance = (item) => { + const statusResult = checkStatus( + [ + 'active', + 'paused', + 'stopped', + 'resized', + 'soft-delete', + 'shelved', + 'shelved_offloaded', + ], + item + ); + return ( + statusResult && + isNotDeleting(item) && + isNotLocked(item) && + !isIronicInstance(item) + ); +}; + export const instanceStatusFilter = { label: t('Status'), name: 'status', diff --git a/src/stores/skyline/server-group-instance.js b/src/stores/skyline/server-group-instance.js index ccec34ef..41a72ffa 100644 --- a/src/stores/skyline/server-group-instance.js +++ b/src/stores/skyline/server-group-instance.js @@ -27,12 +27,16 @@ export class ServerGroupInstanceStore extends Base { }; } + get groupArraySize() { + return 1; + } + async requestList(params, filters) { const { members, isServerGroup, all_projects } = filters; if (members && isServerGroup && members.length === 0) { return []; } - const memberArrs = groupArray(members, 10); + const memberArrs = groupArray(members, this.groupArraySize); const results = await Promise.all( memberArrs.map((it) => { const newParams = { ...params, uuid: it, all_projects };