Merge "Add exec/kill action"
This commit is contained in:
commit
503c16e050
@ -22,7 +22,7 @@ LOG = logging.getLogger(__name__)
|
|||||||
|
|
||||||
CONTAINER_CREATE_ATTRS = ['name', 'image', 'command', 'cpu', 'memory',
|
CONTAINER_CREATE_ATTRS = ['name', 'image', 'command', 'cpu', 'memory',
|
||||||
'environment', 'workdir', 'ports', 'hostname',
|
'environment', 'workdir', 'ports', 'hostname',
|
||||||
'labels']
|
'labels', 'image_pull_policy']
|
||||||
|
|
||||||
|
|
||||||
@memoized
|
@memoized
|
||||||
@ -109,3 +109,11 @@ def container_pause(request, id):
|
|||||||
|
|
||||||
def container_unpause(request, id):
|
def container_unpause(request, id):
|
||||||
return zunclient(request).containers.unpause(id)
|
return zunclient(request).containers.unpause(id)
|
||||||
|
|
||||||
|
|
||||||
|
def container_execute(request, id, command):
|
||||||
|
return zunclient(request).containers.execute(id, command)
|
||||||
|
|
||||||
|
|
||||||
|
def container_kill(request, id, signal=None):
|
||||||
|
return zunclient(request).containers.kill(id, signal)
|
||||||
|
@ -63,6 +63,12 @@ class ContainerActions(generic.View):
|
|||||||
return client.container_pause(request, id)
|
return client.container_pause(request, id)
|
||||||
elif action == 'unpause':
|
elif action == 'unpause':
|
||||||
return client.container_unpause(request, id)
|
return client.container_unpause(request, id)
|
||||||
|
elif action == 'execute':
|
||||||
|
command = request.DATA.get("command")
|
||||||
|
return client.container_execute(request, id, command)
|
||||||
|
elif action == 'kill':
|
||||||
|
signal = request.DATA.get("signal")
|
||||||
|
return client.container_kill(request, id, signal)
|
||||||
|
|
||||||
|
|
||||||
@urls.register
|
@urls.register
|
||||||
|
@ -35,6 +35,8 @@
|
|||||||
'horizon.dashboard.container.containers.reboot.service',
|
'horizon.dashboard.container.containers.reboot.service',
|
||||||
'horizon.dashboard.container.containers.pause.service',
|
'horizon.dashboard.container.containers.pause.service',
|
||||||
'horizon.dashboard.container.containers.unpause.service',
|
'horizon.dashboard.container.containers.unpause.service',
|
||||||
|
'horizon.dashboard.container.containers.execute.service',
|
||||||
|
'horizon.dashboard.container.containers.kill.service',
|
||||||
'horizon.dashboard.container.containers.resourceType',
|
'horizon.dashboard.container.containers.resourceType',
|
||||||
];
|
];
|
||||||
|
|
||||||
@ -48,9 +50,32 @@
|
|||||||
rebootContainerService,
|
rebootContainerService,
|
||||||
pauseContainerService,
|
pauseContainerService,
|
||||||
unpauseContainerService,
|
unpauseContainerService,
|
||||||
|
executeContainerService,
|
||||||
|
killContainerService,
|
||||||
resourceType)
|
resourceType)
|
||||||
{
|
{
|
||||||
var containersResourceType = registry.getResourceType(resourceType);
|
var containersResourceType = registry.getResourceType(resourceType);
|
||||||
|
|
||||||
|
containersResourceType.globalActions
|
||||||
|
.append({
|
||||||
|
id: 'createContainerAction',
|
||||||
|
service: createContainerService,
|
||||||
|
template: {
|
||||||
|
type: 'create',
|
||||||
|
text: gettext('Create Container')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
containersResourceType.batchActions
|
||||||
|
.append({
|
||||||
|
id: 'batchDeleteContainerAction',
|
||||||
|
service: deleteContainerService,
|
||||||
|
template: {
|
||||||
|
type: 'delete-selected',
|
||||||
|
text: gettext('Delete Containers')
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
containersResourceType.itemActions
|
containersResourceType.itemActions
|
||||||
.append({
|
.append({
|
||||||
id: 'startContainerAction',
|
id: 'startContainerAction',
|
||||||
@ -87,6 +112,20 @@
|
|||||||
text: gettext('Unpause Container')
|
text: gettext('Unpause Container')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.append({
|
||||||
|
id: 'executeContainerAction',
|
||||||
|
service: executeContainerService,
|
||||||
|
template: {
|
||||||
|
text: gettext('Execute Command')
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.append({
|
||||||
|
id: 'killContainerAction',
|
||||||
|
service: killContainerService,
|
||||||
|
template: {
|
||||||
|
text: gettext('Send Kill Signal')
|
||||||
|
}
|
||||||
|
})
|
||||||
.append({
|
.append({
|
||||||
id: 'deleteContainerAction',
|
id: 'deleteContainerAction',
|
||||||
service: deleteContainerService,
|
service: deleteContainerService,
|
||||||
@ -95,24 +134,6 @@
|
|||||||
text: gettext('Delete Container')
|
text: gettext('Delete Container')
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
containersResourceType.batchActions
|
|
||||||
.append({
|
|
||||||
id: 'createContainerAction',
|
|
||||||
service: createContainerService,
|
|
||||||
template: {
|
|
||||||
type: 'create',
|
|
||||||
text: gettext('Create Container')
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.append({
|
|
||||||
id: 'batchDeleteContainerAction',
|
|
||||||
service: deleteContainerService,
|
|
||||||
template: {
|
|
||||||
type: 'delete-selected',
|
|
||||||
text: gettext('Delete Containers')
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
})();
|
})();
|
||||||
|
@ -0,0 +1,118 @@
|
|||||||
|
/**
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self file except in compliance with the License. You may obtain
|
||||||
|
* a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('horizon.dashboard.container.containers')
|
||||||
|
.factory(
|
||||||
|
'horizon.dashboard.container.containers.execute.service',
|
||||||
|
executeContainerService);
|
||||||
|
|
||||||
|
executeContainerService.$inject = [
|
||||||
|
'horizon.app.core.openstack-service-api.zun',
|
||||||
|
'horizon.framework.util.i18n.gettext',
|
||||||
|
'horizon.framework.util.q.extensions',
|
||||||
|
'horizon.framework.widgets.form.ModalFormService',
|
||||||
|
'horizon.framework.widgets.toast.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc factory
|
||||||
|
* @name horizon.dashboard.container.containers.execute.service
|
||||||
|
* @description
|
||||||
|
* Service for the command execution in the container
|
||||||
|
*/
|
||||||
|
function executeContainerService(
|
||||||
|
zun, gettext, $qExtensions, modal, toast
|
||||||
|
) {
|
||||||
|
// schema
|
||||||
|
var schema = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
command: {
|
||||||
|
title: gettext("Command"),
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// form
|
||||||
|
var form = [
|
||||||
|
{
|
||||||
|
type: "section",
|
||||||
|
htmlClass: "col-sm-12",
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
key: "command",
|
||||||
|
placeholder: gettext("The command to execute."),
|
||||||
|
required: true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// model
|
||||||
|
var model;
|
||||||
|
|
||||||
|
var message = {
|
||||||
|
success: gettext("Command was successfully executed at container %s.")
|
||||||
|
};
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initAction: initAction,
|
||||||
|
perform: perform,
|
||||||
|
allowed: allowed
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
function initAction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed() {
|
||||||
|
return $qExtensions.booleanAsPromise(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(selected) {
|
||||||
|
model = {
|
||||||
|
id: selected.id,
|
||||||
|
name: selected.name,
|
||||||
|
command: ''
|
||||||
|
};
|
||||||
|
// modal config
|
||||||
|
var config = {
|
||||||
|
title: gettext("Execute Command"),
|
||||||
|
submitText: gettext("Execute"),
|
||||||
|
schema: schema,
|
||||||
|
form: form,
|
||||||
|
model: model
|
||||||
|
};
|
||||||
|
return modal.open(config).then(submit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit(context) {
|
||||||
|
var id = context.model.id;
|
||||||
|
var name = context.model.name;
|
||||||
|
delete context.model.id;
|
||||||
|
delete context.model.name;
|
||||||
|
return zun.executeContainer(id, context.model).then(function(response) {
|
||||||
|
toast.add('success', interpolate(message.success, [name]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -0,0 +1,6 @@
|
|||||||
|
<p translate>
|
||||||
|
Signal to send to the container: integer or string like SIGINT.
|
||||||
|
When not set, SIGKILL is set as default value and the container will exit.
|
||||||
|
The supported signals varies between platform.
|
||||||
|
Besides, you can omit 'SIG' prefix.
|
||||||
|
</p>
|
@ -0,0 +1,128 @@
|
|||||||
|
/**
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use self file except in compliance with the License. You may obtain
|
||||||
|
* a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
|
||||||
|
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
|
||||||
|
* License for the specific language governing permissions and limitations
|
||||||
|
* under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
(function() {
|
||||||
|
'use strict';
|
||||||
|
|
||||||
|
angular
|
||||||
|
.module('horizon.dashboard.container.containers')
|
||||||
|
.factory(
|
||||||
|
'horizon.dashboard.container.containers.kill.service',
|
||||||
|
killContainerService);
|
||||||
|
|
||||||
|
killContainerService.$inject = [
|
||||||
|
'horizon.app.core.openstack-service-api.zun',
|
||||||
|
'horizon.dashboard.container.containers.basePath',
|
||||||
|
'horizon.framework.util.i18n.gettext',
|
||||||
|
'horizon.framework.util.q.extensions',
|
||||||
|
'horizon.framework.widgets.form.ModalFormService',
|
||||||
|
'horizon.framework.widgets.toast.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc factory
|
||||||
|
* @name horizon.dashboard.container.containers.kill.service
|
||||||
|
* @description
|
||||||
|
* Service to send kill signals to the container
|
||||||
|
*/
|
||||||
|
function killContainerService(
|
||||||
|
zun, basePath, gettext, $qExtensions, modal, toast
|
||||||
|
) {
|
||||||
|
// schema
|
||||||
|
var schema = {
|
||||||
|
type: "object",
|
||||||
|
properties: {
|
||||||
|
signal: {
|
||||||
|
title: gettext("Kill Signal"),
|
||||||
|
type: "string"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// form
|
||||||
|
var form = [
|
||||||
|
{
|
||||||
|
type: 'section',
|
||||||
|
htmlClass: 'row',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
type: 'section',
|
||||||
|
htmlClass: 'col-sm-6',
|
||||||
|
items: [
|
||||||
|
{
|
||||||
|
"key": "signal",
|
||||||
|
"placeholder": gettext("The kill signal to send.")
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
type: 'template',
|
||||||
|
templateUrl: basePath + 'operations/kill.help.html'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
];
|
||||||
|
|
||||||
|
// model
|
||||||
|
var model;
|
||||||
|
|
||||||
|
var message = {
|
||||||
|
success: gettext('Kill signal was successfully sent to container %s.')
|
||||||
|
};
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initAction: initAction,
|
||||||
|
perform: perform,
|
||||||
|
allowed: allowed
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
function initAction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed() {
|
||||||
|
return $qExtensions.booleanAsPromise(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(selected) {
|
||||||
|
model = {
|
||||||
|
id: selected.id,
|
||||||
|
name: selected.name,
|
||||||
|
signal: ''
|
||||||
|
};
|
||||||
|
// modal config
|
||||||
|
var config = {
|
||||||
|
"title": gettext('Send Kill Signal'),
|
||||||
|
"submitText": gettext('Send'),
|
||||||
|
"schema": schema,
|
||||||
|
"form": form,
|
||||||
|
"model": model
|
||||||
|
};
|
||||||
|
return modal.open(config).then(submit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit(context) {
|
||||||
|
var id = context.model.id;
|
||||||
|
var name = context.model.name;
|
||||||
|
delete context.model.id;
|
||||||
|
delete context.model.name;
|
||||||
|
return zun.killContainer(id, context.model).then(function(response) {
|
||||||
|
toast.add('success', interpolate(message.success, [name]));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -36,7 +36,9 @@
|
|||||||
logsContainer: logsContainer,
|
logsContainer: logsContainer,
|
||||||
rebootContainer: rebootContainer,
|
rebootContainer: rebootContainer,
|
||||||
pauseContainer: pauseContainer,
|
pauseContainer: pauseContainer,
|
||||||
unpauseContainer: unpauseContainer
|
unpauseContainer: unpauseContainer,
|
||||||
|
executeContainer: executeContainer,
|
||||||
|
killContainer: killContainer
|
||||||
};
|
};
|
||||||
|
|
||||||
return service;
|
return service;
|
||||||
@ -140,17 +142,31 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
function pauseContainer(id) {
|
function pauseContainer(id) {
|
||||||
return apiService.post('/api/zun/containers/' + id + '/pause')
|
return apiService.post('/api/zun/containers/' + id + '/pause')
|
||||||
.error(function() {
|
.error(function() {
|
||||||
toastService.add('error', gettext('Unable to pause Container'));
|
toastService.add('error', gettext('Unable to pause Container'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
function unpauseContainer(id) {
|
function unpauseContainer(id) {
|
||||||
return apiService.post('/api/zun/containers/' + id + '/unpause')
|
return apiService.post('/api/zun/containers/' + id + '/unpause')
|
||||||
.error(function() {
|
.error(function() {
|
||||||
toastService.add('error', gettext('Unable to unpause of Container'));
|
toastService.add('error', gettext('Unable to unpause of Container'));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function executeContainer(id, params) {
|
||||||
|
return apiService.post('/api/zun/containers/' + id + '/execute', params)
|
||||||
|
.error(function() {
|
||||||
|
toastService.add('error', gettext('Unable to execute the command'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
function killContainer(id, params) {
|
||||||
|
return apiService.post('/api/zun/containers/' + id + '/kill', params)
|
||||||
|
.error(function() {
|
||||||
|
toastService.add('error', gettext('Unable to send kill signal'));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}());
|
}());
|
||||||
|
Loading…
Reference in New Issue
Block a user