Add update action for container
This patch adds update action for container as item action. Change-Id: Ie80a1f447e218213adaff2253a1ec1afd7fe5672
This commit is contained in:
parent
2fe0d61529
commit
6ab8f75e59
@ -43,39 +43,37 @@ def zunclient(request):
|
|||||||
return c
|
return c
|
||||||
|
|
||||||
|
|
||||||
def container_create(request, **kwargs):
|
def _cleanup_params(attrs, check, **params):
|
||||||
args = {}
|
args = {}
|
||||||
run = False
|
run = False
|
||||||
for (key, value) in kwargs.items():
|
|
||||||
|
for (key, value) in params.items():
|
||||||
if key == "run":
|
if key == "run":
|
||||||
run = value
|
run = value
|
||||||
continue
|
|
||||||
elif key == "interactive":
|
elif key == "interactive":
|
||||||
args["interactive"] = value
|
args["interactive"] = value
|
||||||
continue
|
|
||||||
elif key == "restart_policy":
|
elif key == "restart_policy":
|
||||||
args[key] = utils.check_restart_policy(value)
|
args[key] = utils.check_restart_policy(value)
|
||||||
continue
|
elif key == "environment" or key == "labels":
|
||||||
|
values = {}
|
||||||
if key in CONTAINER_CREATE_ATTRS:
|
vals = value.split(",")
|
||||||
|
for v in vals:
|
||||||
|
kv = v.split("=", 1)
|
||||||
|
values[kv[0]] = kv[1]
|
||||||
|
args[str(key)] = values
|
||||||
|
elif key in attrs:
|
||||||
|
if value is None:
|
||||||
|
value = ''
|
||||||
args[str(key)] = str(value)
|
args[str(key)] = str(value)
|
||||||
else:
|
elif check:
|
||||||
raise exceptions.BadRequest(
|
raise exceptions.BadRequest(
|
||||||
"Key must be in %s" % ",".join(CONTAINER_CREATE_ATTRS))
|
"Key must be in %s" % ",".join(attrs))
|
||||||
if key == "environment":
|
|
||||||
envs = {}
|
return args, run
|
||||||
vals = value.split(",")
|
|
||||||
for v in vals:
|
|
||||||
kv = v.split("=", 1)
|
def container_create(request, **kwargs):
|
||||||
envs[kv[0]] = kv[1]
|
args, run = _cleanup_params(CONTAINER_CREATE_ATTRS, True, **kwargs)
|
||||||
args["environment"] = envs
|
|
||||||
elif key == "labels":
|
|
||||||
labels = {}
|
|
||||||
vals = value.split(",")
|
|
||||||
for v in vals:
|
|
||||||
kv = v.split("=", 1)
|
|
||||||
labels[kv[0]] = kv[1]
|
|
||||||
args["labels"] = labels
|
|
||||||
response = None
|
response = None
|
||||||
if run:
|
if run:
|
||||||
response = zunclient(request).containers.run(**args)
|
response = zunclient(request).containers.run(**args)
|
||||||
@ -84,6 +82,11 @@ def container_create(request, **kwargs):
|
|||||||
return response
|
return response
|
||||||
|
|
||||||
|
|
||||||
|
def container_update(request, id, **kwargs):
|
||||||
|
args, run = _cleanup_params(CONTAINER_CREATE_ATTRS, True, **kwargs)
|
||||||
|
return zunclient(request).containers.update(id, **args)
|
||||||
|
|
||||||
|
|
||||||
def container_delete(request, id, force=False):
|
def container_delete(request, id, force=False):
|
||||||
# TODO(shu-mutou): force option should be provided by user.
|
# TODO(shu-mutou): force option should be provided by user.
|
||||||
return zunclient(request).containers.delete(id, force)
|
return zunclient(request).containers.delete(id, force)
|
||||||
@ -147,13 +150,5 @@ def image_list(request, limit=None, marker=None, sort_key=None,
|
|||||||
|
|
||||||
|
|
||||||
def image_create(request, **kwargs):
|
def image_create(request, **kwargs):
|
||||||
args = {}
|
args = _cleanup_params(IMAGE_PULL_ATTRS, True, **kwargs)
|
||||||
for (key, value) in kwargs.items():
|
|
||||||
|
|
||||||
if key in IMAGE_PULL_ATTRS:
|
|
||||||
args[str(key)] = str(value)
|
|
||||||
else:
|
|
||||||
raise exceptions.BadRequest(
|
|
||||||
"Key must be in %s" % ",".join(IMAGE_PULL_ATTRS))
|
|
||||||
|
|
||||||
return zunclient(request).images.create(**args)
|
return zunclient(request).images.create(**args)
|
||||||
|
@ -46,6 +46,17 @@ class Container(generic.View):
|
|||||||
"""
|
"""
|
||||||
return client.container_delete(request, id, force=True)
|
return client.container_delete(request, id, force=True)
|
||||||
|
|
||||||
|
@rest_utils.ajax(data_required=True)
|
||||||
|
def patch(self, request, id):
|
||||||
|
"""Update a Container.
|
||||||
|
|
||||||
|
Returns the Container object on success.
|
||||||
|
"""
|
||||||
|
container = client.container_update(request, id, **request.DATA)
|
||||||
|
return rest_utils.CreatedResponse(
|
||||||
|
'/api/zun/containers/%s' % id,
|
||||||
|
container.to_dict())
|
||||||
|
|
||||||
|
|
||||||
@urls.register
|
@urls.register
|
||||||
class ContainerActions(generic.View):
|
class ContainerActions(generic.View):
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
'horizon.framework.conf.resource-type-registry.service',
|
'horizon.framework.conf.resource-type-registry.service',
|
||||||
'horizon.framework.util.i18n.gettext',
|
'horizon.framework.util.i18n.gettext',
|
||||||
'horizon.dashboard.container.containers.create.service',
|
'horizon.dashboard.container.containers.create.service',
|
||||||
|
'horizon.dashboard.container.containers.update.service',
|
||||||
'horizon.dashboard.container.containers.delete.service',
|
'horizon.dashboard.container.containers.delete.service',
|
||||||
'horizon.dashboard.container.containers.delete-force.service',
|
'horizon.dashboard.container.containers.delete-force.service',
|
||||||
'horizon.dashboard.container.containers.start.service',
|
'horizon.dashboard.container.containers.start.service',
|
||||||
@ -50,6 +51,7 @@
|
|||||||
registry,
|
registry,
|
||||||
gettext,
|
gettext,
|
||||||
createContainerService,
|
createContainerService,
|
||||||
|
updateContainerService,
|
||||||
deleteContainerService,
|
deleteContainerService,
|
||||||
deleteContainerForceService,
|
deleteContainerForceService,
|
||||||
startContainerService,
|
startContainerService,
|
||||||
@ -92,6 +94,13 @@
|
|||||||
text: gettext('Refresh')
|
text: gettext('Refresh')
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
.append({
|
||||||
|
id: 'updateContainerAction',
|
||||||
|
service: updateContainerService,
|
||||||
|
template: {
|
||||||
|
text: gettext('Update Container')
|
||||||
|
}
|
||||||
|
})
|
||||||
.append({
|
.append({
|
||||||
id: 'startContainerAction',
|
id: 'startContainerAction',
|
||||||
service: startContainerService,
|
service: startContainerService,
|
||||||
|
@ -0,0 +1,144 @@
|
|||||||
|
/**
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); you may
|
||||||
|
* not use this 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';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @ngdoc overview
|
||||||
|
* @name horizon.dashboard.container.containers.update.service
|
||||||
|
* @description Service for the container update modal
|
||||||
|
*/
|
||||||
|
angular
|
||||||
|
.module('horizon.dashboard.container.containers')
|
||||||
|
.factory('horizon.dashboard.container.containers.update.service', updateService);
|
||||||
|
|
||||||
|
updateService.$inject = [
|
||||||
|
'horizon.app.core.openstack-service-api.policy',
|
||||||
|
'horizon.app.core.openstack-service-api.zun',
|
||||||
|
'horizon.dashboard.container.containers.resourceType',
|
||||||
|
'horizon.dashboard.container.containers.workflow',
|
||||||
|
'horizon.framework.util.actions.action-result.service',
|
||||||
|
'horizon.framework.util.i18n.gettext',
|
||||||
|
'horizon.framework.util.q.extensions',
|
||||||
|
'horizon.framework.widgets.form.ModalFormService',
|
||||||
|
'horizon.framework.widgets.toast.service'
|
||||||
|
];
|
||||||
|
|
||||||
|
function updateService(
|
||||||
|
policy, zun, resourceType, workflow,
|
||||||
|
actionResult, gettext, $qExtensions, modal, toast
|
||||||
|
) {
|
||||||
|
var message = {
|
||||||
|
success: gettext('Container %s was successfully updated.')
|
||||||
|
};
|
||||||
|
|
||||||
|
var service = {
|
||||||
|
initAction: initAction,
|
||||||
|
perform: perform,
|
||||||
|
allowed: allowed
|
||||||
|
};
|
||||||
|
|
||||||
|
return service;
|
||||||
|
|
||||||
|
//////////////
|
||||||
|
|
||||||
|
function initAction() {
|
||||||
|
}
|
||||||
|
|
||||||
|
function perform(selected) {
|
||||||
|
var title, submitText;
|
||||||
|
title = gettext('Update Container');
|
||||||
|
submitText = gettext('Update');
|
||||||
|
var config = workflow.init('update', title, submitText);
|
||||||
|
config.model.id = selected.id;
|
||||||
|
|
||||||
|
// load current data
|
||||||
|
zun.getContainer(selected.id).then(onLoad);
|
||||||
|
function onLoad(response) {
|
||||||
|
config.model.name = response.data.name
|
||||||
|
? response.data.name : "";
|
||||||
|
config.model.image = response.data.image
|
||||||
|
? response.data.image : "";
|
||||||
|
config.model.image_driver = response.data.image_driver
|
||||||
|
? response.data.image_driver : "docker";
|
||||||
|
config.model.image_pull_policy = response.data.image_pull_policy
|
||||||
|
? response.data.image_pull_policy : "";
|
||||||
|
config.model.command = response.data.command
|
||||||
|
? response.data.command : "";
|
||||||
|
config.model.cpu = response.data.cpu
|
||||||
|
? response.data.cpu : "";
|
||||||
|
config.model.memory = response.data.memory
|
||||||
|
? parseInt(response.data.memory, 10) : "";
|
||||||
|
config.model.restart_policy = response.data.restart_policy.Name
|
||||||
|
? response.data.restart_policy.Name : "";
|
||||||
|
config.model.restart_policy_max_retry = response.data.restart_policy.MaximumRetryCount
|
||||||
|
? parseInt(response.data.restart_policy.MaximumRetryCount, 10) : null;
|
||||||
|
config.model.workdir = response.data.workdir
|
||||||
|
? response.data.workdir : "";
|
||||||
|
config.model.environment = response.data.environment
|
||||||
|
? hashToString(response.data.environment) : "";
|
||||||
|
config.model.interactive = response.data.interactive
|
||||||
|
? response.data.interactive : false;
|
||||||
|
config.model.labels = response.data.labels
|
||||||
|
? hashToString(response.data.labels) : "";
|
||||||
|
}
|
||||||
|
|
||||||
|
return modal.open(config).then(submit);
|
||||||
|
}
|
||||||
|
|
||||||
|
function allowed() {
|
||||||
|
return policy.ifAllowed({ rules: [['container', 'edit_container']] });
|
||||||
|
}
|
||||||
|
|
||||||
|
function submit(context) {
|
||||||
|
var id = context.model.id;
|
||||||
|
context.model = cleanUpdateProperties(context.model);
|
||||||
|
return zun.updateContainer(id, context.model).then(success);
|
||||||
|
}
|
||||||
|
|
||||||
|
function success(response) {
|
||||||
|
response.data.id = response.data.uuid;
|
||||||
|
toast.add('success', interpolate(message.success, [response.data.name]));
|
||||||
|
var result = actionResult.getActionResult().updated(resourceType, response.data.name);
|
||||||
|
return result.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanUpdateProperties(model) {
|
||||||
|
// Initially clean fields that don't have any value.
|
||||||
|
// Not only "null", blank too.
|
||||||
|
// only "cpu" and "memory" fields are editable.
|
||||||
|
for (var key in model) {
|
||||||
|
if (model.hasOwnProperty(key) && model[key] === null || model[key] === "" ||
|
||||||
|
(key !== "cpu" && key !== "memory")) {
|
||||||
|
delete model[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return model;
|
||||||
|
}
|
||||||
|
|
||||||
|
function hashToString(hash) {
|
||||||
|
var str = "";
|
||||||
|
for (var key in hash) {
|
||||||
|
if (hash.hasOwnProperty(key)) {
|
||||||
|
if (str.length > 0) {
|
||||||
|
str += ",";
|
||||||
|
}
|
||||||
|
str += key + "=" + hash[key];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return str;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})();
|
@ -82,8 +82,7 @@
|
|||||||
cpu: {
|
cpu: {
|
||||||
title: gettext("CPU"),
|
title: gettext("CPU"),
|
||||||
type: "number",
|
type: "number",
|
||||||
minimum: 0,
|
minimum: 0
|
||||||
step: 0.1
|
|
||||||
},
|
},
|
||||||
memory: {
|
memory: {
|
||||||
title: gettext("Memory"),
|
title: gettext("Memory"),
|
||||||
@ -182,7 +181,8 @@
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
key: "run",
|
key: "run",
|
||||||
readonly: action === "update"
|
readonly: action === "update",
|
||||||
|
condition: action === "update"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -200,6 +200,7 @@
|
|||||||
items: [
|
items: [
|
||||||
{
|
{
|
||||||
key: "cpu",
|
key: "cpu",
|
||||||
|
step: 0.1,
|
||||||
placeholder: gettext("The number of virtual cpu for this container.")
|
placeholder: gettext("The number of virtual cpu for this container.")
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -292,8 +293,6 @@
|
|||||||
];
|
];
|
||||||
// model
|
// model
|
||||||
model = {
|
model = {
|
||||||
//id: "",
|
|
||||||
//uuid: "",
|
|
||||||
// info
|
// info
|
||||||
name: "",
|
name: "",
|
||||||
image: "",
|
image: "",
|
||||||
|
@ -29,6 +29,7 @@
|
|||||||
var imagesPath = '/api/zun/images/';
|
var imagesPath = '/api/zun/images/';
|
||||||
var service = {
|
var service = {
|
||||||
createContainer: createContainer,
|
createContainer: createContainer,
|
||||||
|
updateContainer: updateContainer,
|
||||||
getContainer: getContainer,
|
getContainer: getContainer,
|
||||||
getContainers: getContainers,
|
getContainers: getContainers,
|
||||||
deleteContainer: deleteContainer,
|
deleteContainer: deleteContainer,
|
||||||
@ -57,6 +58,11 @@
|
|||||||
return apiService.post(containersPath, params).error(error(msg));
|
return apiService.post(containersPath, params).error(error(msg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function updateContainer(id, params) {
|
||||||
|
var msg = gettext('Unable to update Container.');
|
||||||
|
return apiService.patch(containersPath + id, params).error(error(msg));
|
||||||
|
}
|
||||||
|
|
||||||
function getContainer(id) {
|
function getContainer(id) {
|
||||||
var msg = gettext('Unable to retrieve the Container.');
|
var msg = gettext('Unable to retrieve the Container.');
|
||||||
return apiService.get(containersPath + id).error(error(msg));
|
return apiService.get(containersPath + id).error(error(msg));
|
||||||
|
Loading…
Reference in New Issue
Block a user