feature: support search filters and fix image in zun ui
1. support search filters to capsules 2. support search filters to containers 3. support search filters to hosts 4. support search filters to services 5. because the glance image's name can be repeated, change params from name to id if use glance image Change-Id: If3ceed8d0027f230afd72784c48161048fe61faf
This commit is contained in:
parent
5f5b8c3cd5
commit
317a81acc4
@ -2352,7 +2352,7 @@
|
|||||||
"The name of the physical network to which a port is connected": "The name of the physical network to which a port is connected",
|
"The name of the physical network to which a port is connected": "The name of the physical network to which a port is connected",
|
||||||
"The name should contain letter or number, the length is 1 to 16, characters can only contain \"0-9, a-z, A-Z, -, _.\"": "The name should contain letter or number, the length is 1 to 16, characters can only contain \"0-9, a-z, A-Z, -, _.\"",
|
"The name should contain letter or number, the length is 1 to 16, characters can only contain \"0-9, a-z, A-Z, -, _.\"": "The name should contain letter or number, the length is 1 to 16, characters can only contain \"0-9, a-z, A-Z, -, _.\"",
|
||||||
"The name should contain letter or number, the length is 2 to 64, characters can only contain \"0-9, a-z, A-Z, -, _.\"": "The name should contain letter or number, the length is 2 to 64, characters can only contain \"0-9, a-z, A-Z, -, _.\"",
|
"The name should contain letter or number, the length is 2 to 64, characters can only contain \"0-9, a-z, A-Z, -, _.\"": "The name should contain letter or number, the length is 2 to 64, characters can only contain \"0-9, a-z, A-Z, -, _.\"",
|
||||||
"The name should start with letter or number, characters can only contain \"0-9, a-z, A-Z, -, _, .\"": "The name should start with letter or number, characters can only contain \"0-9, a-z, A-Z, -, _, .\"",
|
"The name should start with letter or number, and be a string of 2 to 255, characters can only contain \"0-9, a-z, A-Z, -, _, .\"": "The name should start with letter or number, and be a string of 2 to 255, characters can only contain \"0-9, a-z, A-Z, -, _, .\"",
|
||||||
"The name should start with upper letter or lower letter, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].:^\".": "The name should start with upper letter or lower letter, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].:^\".",
|
"The name should start with upper letter or lower letter, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].:^\".": "The name should start with upper letter or lower letter, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].:^\".",
|
||||||
"The name should start with upper letter or lower letter, characters can only contain \"0-9, a-z, A-Z, -, _, .\"": "The name should start with upper letter or lower letter, characters can only contain \"0-9, a-z, A-Z, -, _, .\"",
|
"The name should start with upper letter or lower letter, characters can only contain \"0-9, a-z, A-Z, -, _, .\"": "The name should start with upper letter or lower letter, characters can only contain \"0-9, a-z, A-Z, -, _, .\"",
|
||||||
"The name should start with upper letter, lower letter or chinese, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].\".": "The name should start with upper letter, lower letter or chinese, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].\".",
|
"The name should start with upper letter, lower letter or chinese, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].\".": "The name should start with upper letter, lower letter or chinese, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].\".",
|
||||||
|
@ -2352,7 +2352,7 @@
|
|||||||
"The name of the physical network to which a port is connected": "端口连接到的物理网络的名称",
|
"The name of the physical network to which a port is connected": "端口连接到的物理网络的名称",
|
||||||
"The name should contain letter or number, the length is 1 to 16, characters can only contain \"0-9, a-z, A-Z, -, _.\"": "名称应包含字母或数字,长度为 1 到 16,且字符只能包含“0-9、a-z、A-Z、-、_”。",
|
"The name should contain letter or number, the length is 1 to 16, characters can only contain \"0-9, a-z, A-Z, -, _.\"": "名称应包含字母或数字,长度为 1 到 16,且字符只能包含“0-9、a-z、A-Z、-、_”。",
|
||||||
"The name should contain letter or number, the length is 2 to 64, characters can only contain \"0-9, a-z, A-Z, -, _.\"": "名称应包含字母或数字,长度为 2 到 64,且字符只能包含“0-9、a-z、A-Z、-、_”。",
|
"The name should contain letter or number, the length is 2 to 64, characters can only contain \"0-9, a-z, A-Z, -, _.\"": "名称应包含字母或数字,长度为 2 到 64,且字符只能包含“0-9、a-z、A-Z、-、_”。",
|
||||||
"The name should start with letter or number, characters can only contain \"0-9, a-z, A-Z, -, _, .\"": "名称应以字母或数字开头,且只包含“0-9, a-z, A-Z, -, _, .”。",
|
"The name should start with letter or number, and be a string of 2 to 255, characters can only contain \"0-9, a-z, A-Z, -, _, .\"": "名称应以字母或数字开头,长度为 2 到 255,且只包含“0-9, a-z, A-Z, -, _, .”。",
|
||||||
"The name should start with upper letter or lower letter, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].:^\".": "名称应以大写字母或小写字母开头,最长为128字符,且只包含“0-9, a-z, A-Z, \"'-_()[].:^”。",
|
"The name should start with upper letter or lower letter, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].:^\".": "名称应以大写字母或小写字母开头,最长为128字符,且只包含“0-9, a-z, A-Z, \"'-_()[].:^”。",
|
||||||
"The name should start with upper letter or lower letter, characters can only contain \"0-9, a-z, A-Z, -, _, .\"": "名称应以大写字母或小写字母开头,且字符只能包含“0-9、a-z、A-Z、-、_、.”。",
|
"The name should start with upper letter or lower letter, characters can only contain \"0-9, a-z, A-Z, -, _, .\"": "名称应以大写字母或小写字母开头,且字符只能包含“0-9、a-z、A-Z、-、_、.”。",
|
||||||
"The name should start with upper letter, lower letter or chinese, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].\".": "名称应以大写字母,小写字母或中文开头,最长为128字符,且只包含“0-9, a-z, A-Z, \"'-_()[].”。",
|
"The name should start with upper letter, lower letter or chinese, and be a string of 1 to 128, characters can only contain \"0-9, a-z, A-Z, \"-'_()[].\".": "名称应以大写字母,小写字母或中文开头,最长为128字符,且只包含“0-9, a-z, A-Z, \"'-_()[].”。",
|
||||||
|
@ -16,6 +16,7 @@ import Base from 'containers/List';
|
|||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import globalCapsulesStore from 'stores/zun/capsules';
|
import globalCapsulesStore from 'stores/zun/capsules';
|
||||||
import { capsuleStatus } from 'resources/zun/capsule';
|
import { capsuleStatus } from 'resources/zun/capsule';
|
||||||
|
import { getOptions } from 'utils';
|
||||||
import actionConfigs from './actions';
|
import actionConfigs from './actions';
|
||||||
|
|
||||||
export class Capsules extends Base {
|
export class Capsules extends Base {
|
||||||
@ -63,6 +64,20 @@ export class Capsules extends Base {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get searchFilters() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: t('Name'),
|
||||||
|
name: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Status'),
|
||||||
|
name: 'status',
|
||||||
|
options: getOptions(capsuleStatus),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default inject('rootStore')(observer(Capsules));
|
export default inject('rootStore')(observer(Capsules));
|
||||||
|
@ -15,7 +15,11 @@
|
|||||||
import Base from 'containers/BaseDetail';
|
import Base from 'containers/BaseDetail';
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import { containerStatus } from 'resources/zun/container';
|
import {
|
||||||
|
containerStatus,
|
||||||
|
imageDrivers,
|
||||||
|
exitPolicies,
|
||||||
|
} from 'resources/zun/container';
|
||||||
import { stringifyContent } from 'utils/content';
|
import { stringifyContent } from 'utils/content';
|
||||||
import { isEmpty } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
|
|
||||||
@ -34,14 +38,22 @@ export class BaseDetail extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
get baseInfoCard() {
|
get baseInfoCard() {
|
||||||
|
const { image, imageInfo } = this.detailData || {};
|
||||||
|
const imageUrl = imageInfo
|
||||||
|
? this.getLinkRender('imageDetail', imageInfo.name, {
|
||||||
|
id: imageInfo.id,
|
||||||
|
})
|
||||||
|
: image;
|
||||||
|
|
||||||
const options = [
|
const options = [
|
||||||
{
|
{
|
||||||
label: t('Image'),
|
label: t('Image'),
|
||||||
dataIndex: 'image',
|
content: imageUrl,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('Image Driver'),
|
label: t('Image Driver'),
|
||||||
dataIndex: 'image_driver',
|
dataIndex: 'image_driver',
|
||||||
|
valueMap: imageDrivers,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
label: t('Status Detail'),
|
label: t('Status Detail'),
|
||||||
@ -135,7 +147,7 @@ export class BaseDetail extends Base {
|
|||||||
return (
|
return (
|
||||||
<div>
|
<div>
|
||||||
<p>
|
<p>
|
||||||
{t('Name')}: {Name}
|
{t('Name')}: {exitPolicies[Name]}
|
||||||
</p>
|
</p>
|
||||||
<p>
|
<p>
|
||||||
{t('Max Retry')}: {MaximumRetryCount}
|
{t('Max Retry')}: {MaximumRetryCount}
|
||||||
|
@ -12,13 +12,13 @@
|
|||||||
|
|
||||||
import Base from 'components/Form';
|
import Base from 'components/Form';
|
||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import globalImageStore from 'src/stores/glance/image';
|
import { ImageStore } from 'stores/glance/image';
|
||||||
import { getImageColumns } from 'resources/glance/image';
|
import { getImageColumns } from 'resources/glance/image';
|
||||||
import { toJS } from 'mobx';
|
import { imageDrivers } from 'resources/zun/container';
|
||||||
|
|
||||||
export class StepInfo extends Base {
|
export class StepInfo extends Base {
|
||||||
init() {
|
init() {
|
||||||
this.getImageList();
|
this.imageStore = new ImageStore();
|
||||||
}
|
}
|
||||||
|
|
||||||
get title() {
|
get title() {
|
||||||
@ -29,24 +29,21 @@ export class StepInfo extends Base {
|
|||||||
return t('Info');
|
return t('Info');
|
||||||
}
|
}
|
||||||
|
|
||||||
async getImageList() {
|
|
||||||
await globalImageStore.fetchList();
|
|
||||||
}
|
|
||||||
|
|
||||||
get imageList() {
|
|
||||||
return toJS(globalImageStore.list.data || []).filter(
|
|
||||||
(it) => it.container_format === 'docker'
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
get imageColumns() {
|
get imageColumns() {
|
||||||
return getImageColumns(this).filter(
|
return getImageColumns(this).filter(
|
||||||
(it) => !['project_name', 'owner'].includes(it.dataIndex)
|
(it) => !['project_name', 'owner'].includes(it.dataIndex)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get imageDriverOptions() {
|
||||||
|
return Object.entries(imageDrivers).map(([k, v]) => ({
|
||||||
|
label: v,
|
||||||
|
value: k,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
get formItems() {
|
get formItems() {
|
||||||
const { imageDriver } = this.state;
|
const { context: { image_driver } = {} } = this.props;
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -61,7 +58,7 @@ export class StepInfo extends Base {
|
|||||||
return Promise.reject(
|
return Promise.reject(
|
||||||
value
|
value
|
||||||
? t(
|
? t(
|
||||||
'The name should start with letter or number, characters can only contain "0-9, a-z, A-Z, -, _, ."'
|
'The name should start with letter or number, and be a string of 2 to 255, characters can only contain "0-9, a-z, A-Z, -, _, ."'
|
||||||
)
|
)
|
||||||
: ''
|
: ''
|
||||||
);
|
);
|
||||||
@ -74,38 +71,29 @@ export class StepInfo extends Base {
|
|||||||
label: t('Image Driver'),
|
label: t('Image Driver'),
|
||||||
placeholder: t('Please select image driver'),
|
placeholder: t('Please select image driver'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
options: [
|
options: this.imageDriverOptions,
|
||||||
{
|
onChange: (value) =>
|
||||||
label: t('Docker Hub'),
|
this.updateContext({
|
||||||
value: 'docker',
|
image_driver: value,
|
||||||
},
|
}),
|
||||||
{
|
|
||||||
label: t('Glance Image'),
|
|
||||||
value: 'glance',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
onChange: (value) => {
|
|
||||||
this.setState({
|
|
||||||
imageDriver: value,
|
|
||||||
});
|
|
||||||
},
|
|
||||||
required: true,
|
required: true,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'image',
|
name: 'imageDocker',
|
||||||
label: t('Image'),
|
label: t('Image'),
|
||||||
type: 'input',
|
type: 'input',
|
||||||
placeholder: t('Please input image'),
|
placeholder: t('Please input image'),
|
||||||
required: true,
|
required: true,
|
||||||
display: imageDriver === 'docker',
|
display: image_driver === 'docker',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'image',
|
name: 'imageGlance',
|
||||||
label: t('Image'),
|
label: t('Image'),
|
||||||
type: 'select-table',
|
type: 'select-table',
|
||||||
data: this.imageList,
|
|
||||||
required: true,
|
required: true,
|
||||||
isLoading: globalImageStore.list.isLoading,
|
backendPageStore: this.imageStore,
|
||||||
|
extraParams: { container_format: 'docker' },
|
||||||
|
isLoading: this.imageStore.list.isLoading,
|
||||||
filterParams: [
|
filterParams: [
|
||||||
{
|
{
|
||||||
label: t('Name'),
|
label: t('Name'),
|
||||||
@ -113,7 +101,7 @@ export class StepInfo extends Base {
|
|||||||
},
|
},
|
||||||
],
|
],
|
||||||
columns: this.imageColumns,
|
columns: this.imageColumns,
|
||||||
display: imageDriver === 'glance',
|
display: image_driver === 'glance',
|
||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
import Base from 'components/Form';
|
import Base from 'components/Form';
|
||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import globalAvailabilityZoneStore from 'stores/nova/zone';
|
import globalAvailabilityZoneStore from 'stores/nova/zone';
|
||||||
|
import { exitPolicies } from 'resources/zun/container';
|
||||||
import ExposedPorts from '../../../components/ExposedPorts';
|
import ExposedPorts from '../../../components/ExposedPorts';
|
||||||
|
|
||||||
export class StepSpec extends Base {
|
export class StepSpec extends Base {
|
||||||
@ -42,6 +43,13 @@ export class StepSpec extends Base {
|
|||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get exitPoliciesOptions() {
|
||||||
|
return Object.entries(exitPolicies).map(([k, v]) => ({
|
||||||
|
label: v,
|
||||||
|
value: k,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
exposedPortValidator = (rule, value) => {
|
exposedPortValidator = (rule, value) => {
|
||||||
const ifHaveEmpty = (value || []).some((it) => {
|
const ifHaveEmpty = (value || []).some((it) => {
|
||||||
const { value: innerValue } = it;
|
const { value: innerValue } = it;
|
||||||
@ -57,7 +65,8 @@ export class StepSpec extends Base {
|
|||||||
};
|
};
|
||||||
|
|
||||||
get formItems() {
|
get formItems() {
|
||||||
const { disableRetry, healthcheck } = this.state;
|
const { context: { exitPolicy, healthcheck } = {} } = this.props;
|
||||||
|
const disableRetry = exitPolicy !== 'on-failure';
|
||||||
|
|
||||||
return [
|
return [
|
||||||
{
|
{
|
||||||
@ -103,27 +112,10 @@ export class StepSpec extends Base {
|
|||||||
name: 'exitPolicy',
|
name: 'exitPolicy',
|
||||||
label: t('Exit Policy'),
|
label: t('Exit Policy'),
|
||||||
type: 'select',
|
type: 'select',
|
||||||
options: [
|
options: this.exitPoliciesOptions,
|
||||||
{
|
|
||||||
label: t('No'),
|
|
||||||
value: 'no',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('On failure'),
|
|
||||||
value: 'on-failure',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('Always'),
|
|
||||||
value: 'always',
|
|
||||||
},
|
|
||||||
{
|
|
||||||
label: t('Unless Stopped'),
|
|
||||||
value: 'unless-stopped',
|
|
||||||
},
|
|
||||||
],
|
|
||||||
onChange: (value) =>
|
onChange: (value) =>
|
||||||
this.setState({
|
this.updateContext({
|
||||||
disableRetry: value !== 'on-failure',
|
exitPolicy: value,
|
||||||
}),
|
}),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -153,11 +145,10 @@ export class StepSpec extends Base {
|
|||||||
name: 'healthcheck',
|
name: 'healthcheck',
|
||||||
label: t('Enable Health Check'),
|
label: t('Enable Health Check'),
|
||||||
type: 'check',
|
type: 'check',
|
||||||
onChange: (value) => {
|
onChange: (value) =>
|
||||||
this.setState({
|
this.updateContext({
|
||||||
healthcheck: value,
|
healthcheck: value,
|
||||||
});
|
}),
|
||||||
},
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: 'healthcheck_cmd',
|
name: 'healthcheck_cmd',
|
||||||
|
@ -15,7 +15,7 @@ import { message as $message } from 'antd';
|
|||||||
import { StepAction } from 'src/containers/Action';
|
import { StepAction } from 'src/containers/Action';
|
||||||
import globalContainersStore from 'stores/zun/containers';
|
import globalContainersStore from 'stores/zun/containers';
|
||||||
import globalProjectStore from 'stores/keystone/project';
|
import globalProjectStore from 'stores/keystone/project';
|
||||||
import { isEmpty, isObject } from 'lodash';
|
import { isEmpty } from 'lodash';
|
||||||
import StepInfo from './StepInfo';
|
import StepInfo from './StepInfo';
|
||||||
import StepSpec from './StepSpec';
|
import StepSpec from './StepSpec';
|
||||||
import StepVolumes from './StepVolumes';
|
import StepVolumes from './StepVolumes';
|
||||||
@ -227,7 +227,9 @@ export class StepCreate extends StepAction {
|
|||||||
environmentVariables,
|
environmentVariables,
|
||||||
labels,
|
labels,
|
||||||
mounts,
|
mounts,
|
||||||
image,
|
image_driver,
|
||||||
|
imageDocker,
|
||||||
|
imageGlance,
|
||||||
exitPolicy,
|
exitPolicy,
|
||||||
maxRetry,
|
maxRetry,
|
||||||
networks,
|
networks,
|
||||||
@ -245,6 +247,7 @@ export class StepCreate extends StepAction {
|
|||||||
} = values;
|
} = values;
|
||||||
|
|
||||||
const body = {
|
const body = {
|
||||||
|
image_driver,
|
||||||
...rest,
|
...rest,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -359,8 +362,12 @@ export class StepCreate extends StepAction {
|
|||||||
body.entrypoint = [entrypoint];
|
body.entrypoint = [entrypoint];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (image) {
|
if (imageDocker && image_driver === 'docker') {
|
||||||
body.image = isObject(image) ? (image.selectedRows[0] || {}).name : image;
|
body.image = imageDocker;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (imageGlance && image_driver === 'glance') {
|
||||||
|
body.image = imageGlance.selectedRowKeys[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exitPolicy) {
|
if (exitPolicy) {
|
||||||
|
@ -15,7 +15,12 @@
|
|||||||
import Base from 'containers/List';
|
import Base from 'containers/List';
|
||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import globalContainersStore from 'src/stores/zun/containers';
|
import globalContainersStore from 'src/stores/zun/containers';
|
||||||
import { containerStatus, containerTaskStatus } from 'resources/zun/container';
|
import {
|
||||||
|
containerStatus,
|
||||||
|
containerTaskStatus,
|
||||||
|
imageDrivers,
|
||||||
|
} from 'resources/zun/container';
|
||||||
|
import { getOptions } from 'utils';
|
||||||
import actionConfigs from './actions';
|
import actionConfigs from './actions';
|
||||||
|
|
||||||
export class Containers extends Base {
|
export class Containers extends Base {
|
||||||
@ -48,17 +53,18 @@ export class Containers extends Base {
|
|||||||
routeName: this.getRouteName('zunContainerDetail'),
|
routeName: this.getRouteName('zunContainerDetail'),
|
||||||
idKey: 'uuid',
|
idKey: 'uuid',
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
title: t('Image Driver'),
|
||||||
|
isHideable: true,
|
||||||
|
dataIndex: 'image_driver',
|
||||||
|
valueMap: imageDrivers,
|
||||||
|
},
|
||||||
{
|
{
|
||||||
title: t('Status'),
|
title: t('Status'),
|
||||||
isHideable: true,
|
isHideable: true,
|
||||||
dataIndex: 'status',
|
dataIndex: 'status',
|
||||||
valueMap: containerStatus,
|
valueMap: containerStatus,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
title: t('Image'),
|
|
||||||
isHideable: true,
|
|
||||||
dataIndex: 'image',
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
title: t('Task State'),
|
title: t('Task State'),
|
||||||
isHideable: true,
|
isHideable: true,
|
||||||
@ -67,6 +73,25 @@ export class Containers extends Base {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get searchFilters() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: t('Name'),
|
||||||
|
name: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Status'),
|
||||||
|
name: 'status',
|
||||||
|
options: getOptions(containerStatus),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Task State'),
|
||||||
|
name: 'task_state',
|
||||||
|
options: getOptions(containerTaskStatus),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default inject('rootStore')(observer(Containers));
|
export default inject('rootStore')(observer(Containers));
|
||||||
|
@ -96,6 +96,15 @@ export class Hosts extends Base {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get searchFilters() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: t('Name'),
|
||||||
|
name: 'name',
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default inject('rootStore')(observer(Hosts));
|
export default inject('rootStore')(observer(Hosts));
|
||||||
|
@ -17,6 +17,7 @@ import Base from 'containers/List';
|
|||||||
import { inject, observer } from 'mobx-react';
|
import { inject, observer } from 'mobx-react';
|
||||||
import globalServicesStore from 'src/stores/zun/services';
|
import globalServicesStore from 'src/stores/zun/services';
|
||||||
import { serviceState } from 'resources/nova/service';
|
import { serviceState } from 'resources/nova/service';
|
||||||
|
import { getOptions } from 'utils';
|
||||||
|
|
||||||
export class Services extends Base {
|
export class Services extends Base {
|
||||||
init() {
|
init() {
|
||||||
@ -78,6 +79,20 @@ export class Services extends Base {
|
|||||||
},
|
},
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get searchFilters() {
|
||||||
|
return [
|
||||||
|
{
|
||||||
|
label: t('Name'),
|
||||||
|
name: 'name',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
label: t('Service State'),
|
||||||
|
name: 'state',
|
||||||
|
options: getOptions(serviceState),
|
||||||
|
},
|
||||||
|
];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export default inject('rootStore')(observer(Services));
|
export default inject('rootStore')(observer(Services));
|
||||||
|
@ -26,7 +26,7 @@ export const containerStatus = {
|
|||||||
};
|
};
|
||||||
|
|
||||||
export const containerTaskStatus = {
|
export const containerTaskStatus = {
|
||||||
null: t('No Task'),
|
free: t('No Task'),
|
||||||
container_creating: t('Container Creating'),
|
container_creating: t('Container Creating'),
|
||||||
container_starting: t('Container Starting'),
|
container_starting: t('Container Starting'),
|
||||||
container_stopping: t('Container Stopping'),
|
container_stopping: t('Container Stopping'),
|
||||||
@ -102,3 +102,15 @@ export const checkItemAction = (item, actionName) => {
|
|||||||
const { status } = item;
|
const { status } = item;
|
||||||
return validStates[actionName].includes(status);
|
return validStates[actionName].includes(status);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
export const imageDrivers = {
|
||||||
|
docker: t('Docker Hub'),
|
||||||
|
glance: t('Glance Image'),
|
||||||
|
};
|
||||||
|
|
||||||
|
export const exitPolicies = {
|
||||||
|
no: t('No'),
|
||||||
|
'on-failure': t('On failure'),
|
||||||
|
always: t('Always'),
|
||||||
|
'unless-stopped': t('Unless Stopped'),
|
||||||
|
};
|
||||||
|
@ -22,10 +22,15 @@ export class ContainersStore extends Base {
|
|||||||
return client.zun.containers;
|
return client.zun.containers;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get imageClient() {
|
||||||
|
return client.glance.images;
|
||||||
|
}
|
||||||
|
|
||||||
get mapper() {
|
get mapper() {
|
||||||
return (data) => ({
|
return (data) => ({
|
||||||
...data,
|
...data,
|
||||||
id: data.uuid,
|
id: data.uuid,
|
||||||
|
task_state: data.task_state === null ? 'free' : data.task_state,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -85,7 +90,7 @@ export class ContainersStore extends Base {
|
|||||||
}
|
}
|
||||||
|
|
||||||
async detailDidFetch(item) {
|
async detailDidFetch(item) {
|
||||||
const { uuid, status, addresses = {} } = item;
|
const { uuid, status, addresses = {}, image_driver, image } = item;
|
||||||
let stats = {};
|
let stats = {};
|
||||||
if (status === 'Running') {
|
if (status === 'Running') {
|
||||||
stats = (await this.client.stats.list(uuid)) || {};
|
stats = (await this.client.stats.list(uuid)) || {};
|
||||||
@ -100,6 +105,10 @@ export class ContainersStore extends Base {
|
|||||||
}, [])
|
}, [])
|
||||||
.map((it) => it.port);
|
.map((it) => it.port);
|
||||||
}
|
}
|
||||||
|
if (image_driver === 'glance') {
|
||||||
|
const info = await this.imageClient.show(image);
|
||||||
|
item.imageInfo = info;
|
||||||
|
}
|
||||||
return { ...item, stats, networks, ports };
|
return { ...item, stats, networks, ports };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user