diff --git a/lower-constraints.txt b/lower-constraints.txt index 2046b34..e608508 100644 --- a/lower-constraints.txt +++ b/lower-constraints.txt @@ -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 diff --git a/requirements.txt b/requirements.txt index 06b66c1..ca79d11 100644 --- a/requirements.txt +++ b/requirements.txt @@ -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 diff --git a/zun_ui/api/client.py b/zun_ui/api/client.py index 538aa9f..3f7aa01 100644 --- a/zun_ui/api/client.py +++ b/zun_ui/api/client.py @@ -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, diff --git a/zun_ui/api/rest_api.py b/zun_ui/api/rest_api.py index 98564f9..1796451 100644 --- a/zun_ui/api/rest_api.py +++ b/zun_ui/api/rest_api.py @@ -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""" diff --git a/zun_ui/static/dashboard/container/containers/actions/workflow/spec.help.html b/zun_ui/static/dashboard/container/containers/actions/workflow/spec.help.html index 33c1ace..3c2ef05 100644 --- a/zun_ui/static/dashboard/container/containers/actions/workflow/spec.help.html +++ b/zun_ui/static/dashboard/container/containers/actions/workflow/spec.help.html @@ -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> diff --git a/zun_ui/static/dashboard/container/containers/actions/workflow/workflow.service.js b/zun_ui/static/dashboard/container/containers/actions/workflow/workflow.service.js index 35795df..0c73afa 100644 --- a/zun_ui/static/dashboard/container/containers/actions/workflow/workflow.service.js +++ b/zun_ui/static/dashboard/container/containers/actions/workflow/workflow.service.js @@ -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, diff --git a/zun_ui/static/dashboard/container/containers/containers.module.js b/zun_ui/static/dashboard/container/containers/containers.module.js index e49c8ee..81792ac 100644 --- a/zun_ui/static/dashboard/container/containers/containers.module.js +++ b/zun_ui/static/dashboard/container/containers/containers.module.js @@ -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'] }, diff --git a/zun_ui/static/dashboard/container/containers/details/overview.html b/zun_ui/static/dashboard/container/containers/details/overview.html index 38753de..1cff23a 100644 --- a/zun_ui/static/dashboard/container/containers/details/overview.html +++ b/zun_ui/static/dashboard/container/containers/details/overview.html @@ -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> diff --git a/zun_ui/static/dashboard/container/zun.service.js b/zun_ui/static/dashboard/container/zun.service.js index 51e5647..fe01f7a 100644 --- a/zun_ui/static/dashboard/container/zun.service.js +++ b/zun_ui/static/dashboard/container/zun.service.js @@ -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 // ////////////