Commit 7939fc12 authored by Daniele Venzano's avatar Daniele Venzano
Browse files

Add a parameter in the zapp shop to set a service count

parent 55c0e343
...@@ -201,7 +201,7 @@ Parameters: ...@@ -201,7 +201,7 @@ Parameters:
Parameters are values of the JSON description that are modified at run time. Parameters are values of the JSON description that are modified at run time.
* kind : the kind of parameter, it can be ``command`` or ``environment`` * kind : the kind of parameter, it can be ``service_count``, ``command`` or ``environment``
* name : the machine-friendly name of the parameter * name : the machine-friendly name of the parameter
* readable_name : the human-friendly name of the parameter * readable_name : the human-friendly name of the parameter
* description : an helpful description * description : an helpful description
...@@ -211,12 +211,13 @@ Parameters are values of the JSON description that are modified at run time. ...@@ -211,12 +211,13 @@ Parameters are values of the JSON description that are modified at run time.
* min : if ``type`` is integer, this is required and is the minimum value the user can set * min : if ``type`` is integer, this is required and is the minimum value the user can set
* step : if ``type`` is integer, this is required and is the step for moving between values * step : if ``type`` is integer, this is required and is the step for moving between values
Parameters can be of two kinds: Parameters can be of the following kinds:
* environment : the parameter is passed as an environment variable. The name of the environment variable is stored in the ``name`` field. The JSON description is modified by setting the user-defined value in the environment variable with the corresponding name. All services that have the variable defined are modified. * environment : the parameter is passed as an environment variable. The name of the environment variable is stored in the ``name`` field. The JSON description is modified by setting the user-defined value in the environment variable with the corresponding name. All services that have the variable defined are modified.
* command : the service named ``name`` has its start-up command changed to the user-defined value * command : the service named ``name`` has its start-up command changed to the user-defined value
* service_count : the service named ``name`` has its total_count and essential_count changed to the user-defined value
By default users with the ``user`` and ``admin`` roles have access also to resource parameters via the web interface. They can set the amount of memory and cores to reserve before starting their execution. The configuration option ``no-user-edit-limits-web`` can be used to disable access to this feature. By default users with the ``user`` and ``admin`` roles have also access to parameters via the web interface. They can set the amount of memory and cores to reserve before starting their execution. The configuration option ``no-user-edit-limits-web`` can be used to disable access to this feature.
To get started, in the ``contrib/zapp-shop-sample/`` directory there is a sample of the structure needed for a working zapp-shop, including some data science related ZApps. Copy it as-is in your ZApp shop directory to have some Zapps to play with. To get started, in the ``contrib/zapp-shop-sample/`` directory there is a sample of the structure needed for a working zapp-shop, including some data science related ZApps. Copy it as-is in your ZApp shop directory to have some Zapps to play with.
......
...@@ -37,37 +37,37 @@ ...@@ -37,37 +37,37 @@
{% endfor %} {% endfor %}
</ul> </ul>
<h4>Start-up parameters:</h4> {% if resources_are_customizable %}
<form action="{{ reverse_url("zappshop_start", "") }}{{ zapp.id }}-{{ zapp.manifest_index }}" method="post" id="zapp_start_form"> <h4>Start-up parameters:</h4>
<input type="hidden" name="zapp-id" value="{{ zapp.id }}-{{ zapp.manifest_index }}"> <form action="{{ reverse_url("zappshop_start", "") }}{{ zapp.id }}-{{ zapp.manifest_index }}" method="post" id="zapp_start_form">
<label>Execution name:&nbsp;<input type="text" name="exec_name" value="{{ zapp.zoe_description.name }}" maxlength="16" size="18" required/></label><br/> <input type="hidden" name="zapp-id" value="{{ zapp.id }}-{{ zapp.manifest_index }}">
{% for param in zapp.parameters %} <label>Execution name:&nbsp;<input type="text" name="exec_name" value="{{ zapp.zoe_description.name }}" maxlength="16" size="18" required/></label><br/>
<label>{{ param.readable_name }} {% for param in zapp.parameters %}
<label>{{ param.readable_name }}
{% if param.type == "number" and "memory" in param.kind %} {% if param.type == "number" and "memory" in param.kind %}
(GiB) <input name="{{ param.name }}-{{ param.kind }}" value="{{ param.default }}" required size="5" title="{{ param.description }}" type="{{ param.type }}" min="{{ param.min }}" max="{{ param.max }}" step="{{ param.step }}"/> (GiB) <input name="{{ param.name }}-{{ param.kind }}" value="{{ param.default }}" required size="5" title="{{ param.description }}" type="{{ param.type }}" min="{{ param.min }}" max="{{ param.max }}" step="{{ param.step }}"/>
{% elif param.type == "number" %} {% elif param.type == "number" %}
<input name="{{ param.name }}-{{ param.kind }}" value="{{ param.default }}" required size="5" title="{{ param.description }}" type="{{ param.type }}" min="{{ param.min }}" max="{{ param.max }}" step="{{ param.step }}"/> <input name="{{ param.name }}-{{ param.kind }}" value="{{ param.default }}" required size="5" title="{{ param.description }}" type="{{ param.type }}" min="{{ param.min }}" max="{{ param.max }}" step="{{ param.step }}"/>
{% else %} {% else %}
<input name="{{ param.name }}-{{ param.kind }}" value="{{ param.default if param.default != None }}" required title="{{ param.description }}" size="128" type="{{ param.type }}" /> <input name="{{ param.name }}-{{ param.kind }}" value="{{ param.default if param.default != None }}" required title="{{ param.description }}" size="128" type="{{ param.type }}" />
{% endif %} {% endif %}
</label><br/> </label><br/>
{% endfor %} {% endfor %}
{% if resources_are_customizable %}
{% for service in zapp.zoe_description.services %} {% for service in zapp.zoe_description.services %}
<div class="resource-form"> <div class="resource-form">
<h5>{{ service.name }}</h5> <h5>{{ service.name }}</h5>
<label>Memory allocation (GiB) <label>Memory allocation (GiB)
<input name="{{ service.name }}-resource_memory_min" value="{{ service["resources"]["memory"]["min"] / (1024 ** 3) }}" required title="Memory soft limit, service can use more memory if there is no contention" type="number" min="0.5" max="{{ max_memory_limit }}" step="0.5"/></label> <input name="{{ service.name }}-resource_memory_min" value="{{ service["resources"]["memory"]["min"] / (1024 ** 3) }}" required title="Memory soft limit, service can use more memory if there is no contention" type="number" min="0.5" max="{{ max_memory_limit }}" step="0.5"/></label>
<label>Minimum core allocation: <label>Minimum core allocation:
<input name="{{ service.name }}-resource_cores_min" value="{{ service["resources"]["cores"]["min"] }}" required title="No less than this amount of cores will be allocated to this service" type="number" min="0.1" max="{{ max_core_limit }}" step="0.1"/></label> <input name="{{ service.name }}-resource_cores_min" value="{{ service["resources"]["cores"]["min"] }}" required title="No less than this amount of cores will be allocated to this service" type="number" min="0.1" max="{{ max_core_limit }}" step="0.1"/></label>
</div> </div>
{% endfor %} {% endfor %}
{% endif %} {% endif %}
<hr> <hr>
{% if user.role.can_access_api %} {% if user.role.can_access_api %}
<label class="label-inline"><input type="checkbox" onchange="set_submit_text(this)" name="download_json"> Download JSON with these parameters for command-line execution</label> <label class="label-inline"><input type="checkbox" onchange="set_submit_text(this)" name="download_json"> Download JSON with these parameters for command-line execution</label>
<br><br> <br><br>
{% endif %} {% endif %}
<button id="submit" type="submit">Start</button> <button id="submit" type="submit">Start</button>
<button type="reset">Reset</button> <button type="reset">Reset</button>
</form> </form>
......
...@@ -95,7 +95,11 @@ class ZAppStartWeb(ZoeWebRequestHandler): ...@@ -95,7 +95,11 @@ class ZAppStartWeb(ZoeWebRequestHandler):
exec_name = self.get_argument('exec_name') exec_name = self.get_argument('exec_name')
app_descr = self._set_parameters(zapp.zoe_description, zapp.parameters, self.current_user.role) if self.current_user.role.can_customize_resources:
app_descr = self._set_parameters(zapp.zoe_description, zapp.parameters, self.current_user.role)
else:
app_descr = zapp.zoe_description
if len(zapp.labels) > 0: if len(zapp.labels) > 0:
for service in app_descr['services']: for service in app_descr['services']:
if 'labels' in service: if 'labels' in service:
...@@ -132,34 +136,38 @@ class ZAppStartWeb(ZoeWebRequestHandler): ...@@ -132,34 +136,38 @@ class ZAppStartWeb(ZoeWebRequestHandler):
if service['name'] == param.name: if service['name'] == param.name:
service['command'] = self.get_argument(argument_name) service['command'] = self.get_argument(argument_name)
break break
elif param.kind == 'service_count':
for service in app_descr['services']:
if service['name'] == param.name:
service['total_count'] = int(self.get_argument(argument_name))
service['essential_count'] = int(self.get_argument(argument_name))
else: else:
log.warning('Unknown parameter kind: {}, ignoring...'.format(param.kind)) log.warning('Unknown parameter kind: {}, ignoring...'.format(param.kind))
if role.can_customize_resources: for service in app_descr['services']:
for service in app_descr['services']: argument_name = service['name'] + '-resource_memory_min'
argument_name = service['name'] + '-resource_memory_min' try:
try: self.get_argument(argument_name)
self.get_argument(argument_name) except MissingArgumentError:
except MissingArgumentError: pass
pass else:
if float(self.get_argument(argument_name)) >= get_conf().max_memory_limit:
val = int(get_conf().max_memory_limit * (1024 ** 3))
else: else:
if float(self.get_argument(argument_name)) >= get_conf().max_memory_limit: val = int(float(self.get_argument(argument_name)) * (1024 ** 3))
val = int(get_conf().max_memory_limit * (1024 ** 3)) service["resources"]["memory"]["min"] = val
else:
val = int(float(self.get_argument(argument_name)) * (1024 ** 3)) argument_name = service['name'] + '-resource_cores_min'
service["resources"]["memory"]["min"] = val try:
self.get_argument(argument_name)
argument_name = service['name'] + '-resource_cores_min' except MissingArgumentError:
try: pass
self.get_argument(argument_name) else:
except MissingArgumentError: if float(self.get_argument(argument_name)) >= get_conf().max_core_limit:
pass val = get_conf().max_core_limit
else: else:
if float(self.get_argument(argument_name)) >= get_conf().max_core_limit: val = float(self.get_argument(argument_name))
val = get_conf().max_core_limit service["resources"]["cores"]["min"] = val
else: break
val = float(self.get_argument(argument_name))
service["resources"]["cores"]["min"] = val
break
return app_descr return app_descr
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment