feat: support quota info && check when resize instance
1. Support cores/ram quota info when resize instance 2. Disable select flavor which vcpus or ram is bigger then left quota 3. Update FlavorSelectTable to support disable select 4. Update resize action check: only check status, not status and vm_state 5. Update current flavor display: show vcpus && ram info Change-Id: Ie96ca42de999eba80772314b967aaa0e8b1215ff
This commit is contained in:
parent
b6d2eb512f
commit
cf5a24645c
@ -22,8 +22,96 @@ import {
|
||||
checkStatus,
|
||||
isIronicInstance,
|
||||
} from 'resources/nova/instance';
|
||||
import globalProjectStore from 'stores/keystone/project';
|
||||
import { isEmpty } from 'lodash';
|
||||
import { getGiBValue, formatSize } from 'utils/index';
|
||||
import FlavorSelectTable from '../components/FlavorSelectTable';
|
||||
|
||||
export async function fetchQuota(self) {
|
||||
self.setState({
|
||||
quota: {},
|
||||
quotaLoading: true,
|
||||
});
|
||||
const result = await globalProjectStore.fetchProjectNovaQuota();
|
||||
self.setState({
|
||||
quota: result,
|
||||
quotaLoading: false,
|
||||
});
|
||||
}
|
||||
|
||||
export const getQuota = (novaQuota) => {
|
||||
if (isEmpty(novaQuota)) {
|
||||
return {};
|
||||
}
|
||||
const { cores = {}, ram = {} } = novaQuota || {};
|
||||
return {
|
||||
cores,
|
||||
ram,
|
||||
};
|
||||
};
|
||||
|
||||
export const getAdd = (self, flavor) => {
|
||||
if (isEmpty(flavor)) {
|
||||
return {};
|
||||
}
|
||||
const { vcpus: itemVcpus, ram: itemRam } = self.item.flavor_info || {};
|
||||
const { vcpus, ram: flavorRam } = flavor || {};
|
||||
const newVcpu = vcpus - itemVcpus;
|
||||
const newRamGiB = getGiBValue(flavorRam - itemRam);
|
||||
return {
|
||||
vcpuAdd: newVcpu,
|
||||
ramAdd: newRamGiB,
|
||||
};
|
||||
};
|
||||
|
||||
export const checkFlavorDisable = (flavor, self) => {
|
||||
const { quotaLoading = true, quota } = self.state;
|
||||
if (quotaLoading || isEmpty(quota)) {
|
||||
return false;
|
||||
}
|
||||
const {
|
||||
cores: { left },
|
||||
ram: { left: ramLeft },
|
||||
} = getQuota(quota);
|
||||
const { vcpuAdd, ramAdd } = getAdd(self, flavor);
|
||||
const vcpuOK = left === -1 || left >= vcpuAdd;
|
||||
const ramOK = ramLeft === -1 || ramLeft >= ramAdd;
|
||||
return !vcpuOK || !ramOK;
|
||||
};
|
||||
|
||||
export const getQuotaInfo = (self) => {
|
||||
const { quota = {}, quotaLoading, flavor = {} } = self.state;
|
||||
if (quotaLoading || isEmpty(quota)) {
|
||||
return [];
|
||||
}
|
||||
const { cores = {}, ram = {} } = getQuota(quota);
|
||||
const { vcpuAdd = 0, ramAdd = 0 } = getAdd(self, flavor || {});
|
||||
|
||||
const cpuQuotaInfo = {
|
||||
...cores,
|
||||
add: vcpuAdd,
|
||||
name: 'cpu',
|
||||
title: t('CPU'),
|
||||
};
|
||||
|
||||
const ramQuotaInfo = {
|
||||
...ram,
|
||||
add: ramAdd,
|
||||
name: 'ram',
|
||||
title: t('Memory (GiB)'),
|
||||
type: 'line',
|
||||
};
|
||||
return [cpuQuotaInfo, ramQuotaInfo];
|
||||
};
|
||||
|
||||
export const getFlavorLabel = (self) => {
|
||||
const { flavor, flavor_info: { vcpus, ram } = {} } = self.item;
|
||||
return `${flavor} (${t('VCPUs')}: ${vcpus}, ${t('Memory')}: ${formatSize(
|
||||
ram,
|
||||
2
|
||||
)})`;
|
||||
};
|
||||
|
||||
export class Resize extends ModalAction {
|
||||
static id = 'resize';
|
||||
|
||||
@ -33,6 +121,7 @@ export class Resize extends ModalAction {
|
||||
|
||||
init() {
|
||||
this.store = globalFlavorStore;
|
||||
fetchQuota(this);
|
||||
}
|
||||
|
||||
get name() {
|
||||
@ -71,8 +160,17 @@ export class Resize extends ModalAction {
|
||||
);
|
||||
}
|
||||
|
||||
get showQuota() {
|
||||
return true;
|
||||
}
|
||||
|
||||
get quotaInfo() {
|
||||
return getQuotaInfo(this);
|
||||
}
|
||||
|
||||
get defaultValue() {
|
||||
const { name, flavor } = this.item;
|
||||
const { name } = this.item;
|
||||
const flavor = getFlavorLabel(this);
|
||||
const value = {
|
||||
instance: name,
|
||||
flavor,
|
||||
@ -82,7 +180,8 @@ export class Resize extends ModalAction {
|
||||
|
||||
static policy = 'os_compute_api:servers:resize';
|
||||
|
||||
static isActiveOrShutOff = (item) => checkStatus(['active', 'shutoff'], item);
|
||||
static isActiveOrShutOff = (item) =>
|
||||
checkStatus(['active', 'shutoff'], item, false);
|
||||
|
||||
static allowed = (item, containerProps) => {
|
||||
const { isAdminPage } = containerProps;
|
||||
@ -94,6 +193,17 @@ export class Resize extends ModalAction {
|
||||
);
|
||||
};
|
||||
|
||||
onFlavorChange = (flavor) => {
|
||||
const { selectedRows = [] } = flavor || {};
|
||||
this.setState({
|
||||
flavor: selectedRows[0],
|
||||
});
|
||||
};
|
||||
|
||||
disabledFlavor = (flavor) => {
|
||||
return checkFlavorDisable(flavor, this);
|
||||
};
|
||||
|
||||
get formItems() {
|
||||
const { flavor } = this.item;
|
||||
return [
|
||||
@ -114,7 +224,11 @@ export class Resize extends ModalAction {
|
||||
label: t('Flavor'),
|
||||
type: 'select-table',
|
||||
component: (
|
||||
<FlavorSelectTable flavor={flavor} onChange={this.onFlavorChange} />
|
||||
<FlavorSelectTable
|
||||
flavor={flavor}
|
||||
onChange={this.onFlavorChange}
|
||||
disabledFunc={this.disabledFlavor}
|
||||
/>
|
||||
),
|
||||
required: true,
|
||||
wrapperCol: {
|
||||
|
@ -329,7 +329,7 @@ export class FlavorSelectTable extends Component {
|
||||
}
|
||||
|
||||
render() {
|
||||
const { value } = this.props;
|
||||
const { value, disabledFunc } = this.props;
|
||||
const isLoading =
|
||||
this.settingStore.list.isLoading && this.flavorStore.list.isLoading;
|
||||
const props = {
|
||||
@ -345,6 +345,7 @@ export class FlavorSelectTable extends Component {
|
||||
],
|
||||
value,
|
||||
onChange: this.onChange,
|
||||
disabledFunc,
|
||||
};
|
||||
return <SelectTable {...props} />;
|
||||
}
|
||||
|
@ -144,11 +144,11 @@ export const isLocked = (instance) => !!instance.locked;
|
||||
|
||||
export const lockRender = (value) => (value ? lockIcon : unlockIcon);
|
||||
|
||||
export const checkStatus = (statusList = [], instance) => {
|
||||
export const checkStatus = (statusList = [], instance, checkState = true) => {
|
||||
const { status, vm_state } = instance;
|
||||
return (
|
||||
statusList.includes(status.toLowerCase()) ||
|
||||
(vm_state && statusList.includes(vm_state.toLowerCase()))
|
||||
(checkState && vm_state && statusList.includes(vm_state.toLowerCase()))
|
||||
);
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user