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
|
||||
|
||||
|
||||
def container_create(request, **kwargs):
|
||||
def _cleanup_params(attrs, check, **params):
|
||||
args = {}
|
||||
run = False
|
||||
for (key, value) in kwargs.items():
|
||||
|
||||
for (key, value) in params.items():
|
||||
if key == "run":
|
||||
run = value
|
||||
continue
|
||||
elif key == "interactive":
|
||||
args["interactive"] = value
|
||||
continue
|
||||
elif key == "restart_policy":
|
||||
args[key] = utils.check_restart_policy(value)
|
||||
continue
|
||||
|
||||
if key in CONTAINER_CREATE_ATTRS:
|
||||
elif key == "environment" or key == "labels":
|
||||
values = {}
|
||||
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)
|
||||
else:
|
||||
elif check:
|
||||
raise exceptions.BadRequest(
|
||||
"Key must be in %s" % ",".join(CONTAINER_CREATE_ATTRS))
|
||||
if key == "environment":
|
||||
envs = {}
|
||||
vals = value.split(",")
|
||||
for v in vals:
|
||||
kv = v.split("=", 1)
|
||||
envs[kv[0]] = kv[1]
|
||||
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
|
||||
"Key must be in %s" % ",".join(attrs))
|
||||
|
||||
return args, run
|
||||
|
||||
|
||||
def container_create(request, **kwargs):
|
||||
args, run = _cleanup_params(CONTAINER_CREATE_ATTRS, True, **kwargs)
|
||||
response = None
|
||||
if run:
|
||||
response = zunclient(request).containers.run(**args)
|
||||
@ -84,6 +82,11 @@ def container_create(request, **kwargs):
|
||||
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):
|
||||
# TODO(shu-mutou): force option should be provided by user.
|
||||
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):
|
||||
args = {}
|
||||
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))
|
||||
|
||||
args = _cleanup_params(IMAGE_PULL_ATTRS, True, **kwargs)
|
||||
return zunclient(request).images.create(**args)
|
||||
|
@ -46,6 +46,17 @@ class Container(generic.View):
|
||||
"""
|
||||
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
|
||||
class ContainerActions(generic.View):
|
||||
|
@ -33,6 +33,7 @@
|
||||
'horizon.framework.conf.resource-type-registry.service',
|
||||
'horizon.framework.util.i18n.gettext',
|
||||
'horizon.dashboard.container.containers.create.service',
|
||||
'horizon.dashboard.container.containers.update.service',
|
||||
'horizon.dashboard.container.containers.delete.service',
|
||||
'horizon.dashboard.container.containers.delete-force.service',
|
||||
'horizon.dashboard.container.containers.start.service',
|
||||
@ -50,6 +51,7 @@
|
||||
registry,
|
||||
gettext,
|
||||
createContainerService,
|
||||
updateContainerService,
|
||||
deleteContainerService,
|
||||
deleteContainerForceService,
|
||||
startContainerService,
|
||||
@ -92,6 +94,13 @@
|
||||
text: gettext('Refresh')
|
||||
}
|
||||
})
|
||||
.append({
|
||||
id: 'updateContainerAction',
|
||||
service: updateContainerService,
|
||||
template: {
|
||||
text: gettext('Update Container')
|
||||
}
|
||||
})
|
||||
.append({
|
||||
id: 'startContainerAction',
|
||||
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: {
|
||||
title: gettext("CPU"),
|
||||
type: "number",
|
||||
minimum: 0,
|
||||
step: 0.1
|
||||
minimum: 0
|
||||
},
|
||||
memory: {
|
||||
title: gettext("Memory"),
|
||||
@ -182,7 +181,8 @@
|
||||
},
|
||||
{
|
||||
key: "run",
|
||||
readonly: action === "update"
|
||||
readonly: action === "update",
|
||||
condition: action === "update"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -200,6 +200,7 @@
|
||||
items: [
|
||||
{
|
||||
key: "cpu",
|
||||
step: 0.1,
|
||||
placeholder: gettext("The number of virtual cpu for this container.")
|
||||
},
|
||||
{
|
||||
@ -292,8 +293,6 @@
|
||||
];
|
||||
// model
|
||||
model = {
|
||||
//id: "",
|
||||
//uuid: "",
|
||||
// info
|
||||
name: "",
|
||||
image: "",
|
||||
|
@ -29,6 +29,7 @@
|
||||
var imagesPath = '/api/zun/images/';
|
||||
var service = {
|
||||
createContainer: createContainer,
|
||||
updateContainer: updateContainer,
|
||||
getContainer: getContainer,
|
||||
getContainers: getContainers,
|
||||
deleteContainer: deleteContainer,
|
||||
@ -57,6 +58,11 @@
|
||||
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) {
|
||||
var msg = gettext('Unable to retrieve the Container.');
|
||||
return apiService.get(containersPath + id).error(error(msg));
|
||||
|
Loading…
x
Reference in New Issue
Block a user