Add new options for container creation

This patch adds following options for container creation.
* auto_heal
* disk
* availablity_zones

Also, add these parameters into details views to show.
And change layouts to add these options.

This change requires python-zunclient 1.4.0 or later.

Change-Id: Ibb9e774ea379a9999c703d6919f14dd0a6e56857
Implements: blueprint add-params-rocky-1
Depends-On: I6c0512816277a63bbf444d0775121bb5d964a36a
This commit is contained in:
Shu Muto 2018-04-06 15:12:32 +09:00
parent 41fb73489a
commit 2f01345c76
9 changed files with 112 additions and 10 deletions

View File

@ -84,7 +84,7 @@ python-neutronclient==6.7.0
python-novaclient==10.1.0
python-openstackclient==3.14.0
python-swiftclient==3.5.0
python-zunclient==1.3.0
python-zunclient==1.4.0
pytz==2018.3
PyYAML==3.12
rcssmin==1.0.6

View File

@ -8,6 +8,6 @@
#
# PBR should always appear first
pbr!=2.1.0,>=2.0.0 # Apache-2.0
python-zunclient>=1.3.0 # Apache-2.0
python-zunclient>=1.4.0 # Apache-2.0
horizon>=14.0.0.0b1 # Apache-2.0

View File

@ -104,11 +104,11 @@ def _cleanup_params(attrs, check, **params):
run = value
elif key == "cpu":
args[key] = float(value)
elif key == "memory":
elif key == "memory" or key == "disk":
args[key] = int(value)
elif key == "interactive" or key == "mounts" or key == "nets" \
or key == "security_groups" or key == "hints"\
or key == "auto_remove":
or key == "auto_remove" or key == "auto_heal":
args[key] = value
elif key == "restart_policy":
args[key] = utils.check_restart_policy(value)
@ -267,6 +267,11 @@ def port_update_security_groups(request):
return {"port": port, "security_group": security_groups}
def availability_zone_list(request):
list = zunclient(request).availability_zones.list()
return list
def image_list(request, limit=None, marker=None, sort_key=None,
sort_dir=None, detail=True):
return zunclient(request).images.list(limit, marker, sort_key,

View File

@ -145,6 +145,22 @@ class Containers(generic.View):
new_container.to_dict())
@urls.register
class AvailabilityZones(generic.View):
"""API for Zun AvailabilityZones"""
url_regex = r'zun/availability_zones/$'
@rest_utils.ajax()
def get(self, request):
"""Get a list of the Zun AvailabilityZones.
The returned result is an object with property 'items' and each
item under this is a Zun AvailabilityZones.
"""
result = client.availability_zone_list(request)
return {'items': [i.to_dict() for i in result]}
@urls.register
class Images(generic.View):
"""API for Zun Images"""

View File

@ -1,10 +1,16 @@
<dl>
<dt translate>CPU</dt>
<dd translate>The number of virtual cpus.</dd>
<dt translate>Memory</dt>
<dd translate>The container memory size in MiB.</dd>
<dt translate>Runtime</dt>
<dd translate>The runtime to use for this container. Default: "runc"</dd>
<dt translate>CPU</dt>
<dd translate>The number of virtual CPUs.</dd>
<dt translate>Memory</dt>
<dd translate>The container memory size in MiB.</dd>
<dt translate>Disk</dt>
<dd translate>The disk size in GiB for per container.</dd>
<dt translate>Availability Zone</dt>
<dd translate>The availability zone of the container.</dd>
<dt translate>Exit Policy</dt>
<dd translate>Policy to apply when a container exits.</dd>
<dt translate>Auto Heal</dt>
<dd translate>The flag of healing non-existent container in docker.</dd>
</dl>

View File

@ -59,6 +59,9 @@
{value: "unless-stopped", name: gettext("Restart if stopped")},
{value: "remove", name: gettext("Remove container")}
];
var availabilityZones = [
{value: "", name: gettext("Select availability zone.")}
];
// schema
schema = {
@ -108,6 +111,15 @@
type: "number",
minimum: 4
},
disk: {
title: gettext("Disk"),
type: "number",
minimum: 0
},
availability_zone: {
title: gettext("Availability Zone"),
type: "string"
},
exit_policy: {
title: gettext("Exit Policy"),
type: "string"
@ -117,6 +129,10 @@
type: "number",
minimum: 0
},
auto_heal: {
title: gettext("Enable auto heal"),
type: "boolean"
},
// misc
workdir: {
title: gettext("Working Directory"),
@ -255,6 +271,29 @@
}
]
},
{
type: "section",
htmlClass: "col-xs-6",
items: [
{
key: "disk",
step: 1,
placeholder: gettext("The disk size in GiB for per container.")
}
]
},
{
type: "section",
htmlClass: "col-xs-6",
items: [
{
key: "availability_zone",
readonly: action === "update",
type: "select",
titleMap: availabilityZones
}
]
},
{
type: "section",
htmlClass: "col-xs-6",
@ -269,7 +308,7 @@
if (notOnFailure) {
model.restart_policy_max_retry = "";
}
form[0].tabs[1].items[5].items[0].readonly = notOnFailure;
form[0].tabs[1].items[7].items[0].readonly = notOnFailure;
// set auto_remove whether exit_policy is "remove".
// if exit_policy is set as "remove", clear restart_policy.
// otherwise, set restart_policy as same value as exit_policy.
@ -293,6 +332,16 @@
readonly: true
}
]
},
{
type: "section",
htmlClass: "col-xs-12",
items: [
{
key: "auto_heal",
readonly: action === "update"
}
]
}
]
},
@ -462,10 +511,13 @@
runtime: "",
cpu: "",
memory: "",
disks: "",
availability_zone: "",
exit_policy: "",
restart_policy: "",
restart_policy_max_retry: "",
auto_remove: false,
auto_heal: false,
// mounts
mounts: [],
// networks
@ -510,6 +562,7 @@
getVolumes();
getNetworks();
securityGroup.query().then(onGetSecurityGroups);
zun.getZunAvailabilityZones().then(onGetZunServices);
});
// get container when action equals "update"
@ -681,6 +734,15 @@
return response;
}
// get availability zones from zun services
function onGetZunServices(response) {
var azs = [];
response.data.items.forEach(function (service) {
azs.push({value: service.availability_zone, name: service.availability_zone});
});
push.apply(availabilityZones, azs);
}
var config = {
title: title,
submitText: submitText,

View File

@ -144,9 +144,11 @@
function containerProperties() {
return {
'addresses': { label: gettext('Addresses'), filters: ['noValue', 'json'] },
'auto_heal': { label: gettext('Auto Heal'), filters: ['yesno'] },
'auto_remove': { label: gettext('Auto Remove'), filters: ['yesno'] },
'command': { label: gettext('Command'), filters: ['noValue'] },
'cpu': { label: gettext('CPU'), filters: ['noValue'] },
'disk': { label: gettext('Disk'), filters: ['gb', 'noValue'] },
'environment': { label: gettext('Environment'), filters: ['noValue', 'json'] },
'host': { label: gettext('Host'), filters: ['noValue'] },
'hostname': { label: gettext('Hostname'), filters: ['noValue'] },

View File

@ -19,7 +19,7 @@
cls="dl-horizontal"
item="ctrl.container"
property-groups="[['image', 'image_driver', 'image_pull_policy', 'hostname', 'runtime',
'cpu', 'memory', 'restart_policy', 'auto_remove',
'cpu', 'memory', 'disk', 'restart_policy', 'auto_remove', 'auto_heal',
'addresses', 'ports', 'security_groups']]">
</hz-resource-property-list>
</div>

View File

@ -26,6 +26,7 @@
function ZunAPI(apiService, toastService, gettext) {
var containersPath = '/api/zun/containers/';
var zunAvailabilityZonesPath = '/api/zun/availability_zones/';
var imagesPath = '/api/zun/images/';
var service = {
createContainer: createContainer,
@ -48,6 +49,7 @@
attachNetwork: attachNetwork,
detachNetwork: detachNetwork,
updatePortSecurityGroup: updatePortSecurityGroup,
getZunAvailabilityZones: getZunAvailabilityZones,
pullImage: pullImage,
getImages: getImages
};
@ -177,6 +179,15 @@
.error(error(msg));
}
//////////////////////////////
// Zun AvailabilityZones //
//////////////////////////////
function getZunAvailabilityZones() {
var msg = gettext('Unable to retrieve the Zun Availability Zones.');
return apiService.get(zunAvailabilityZonesPath).error(error(msg));
}
////////////
// Images //
////////////