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

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

parent 55c0e343
......@@ -201,7 +201,7 @@ Parameters:
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
* readable_name : the human-friendly name of the parameter
* description : an helpful description
......@@ -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
* 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.
* 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.
......
......@@ -37,37 +37,37 @@
{% endfor %}
</ul>
<h4>Start-up parameters:</h4>
<form action="{{ reverse_url("zappshop_start", "") }}{{ zapp.id }}-{{ zapp.manifest_index }}" method="post" id="zapp_start_form">
<input type="hidden" name="zapp-id" value="{{ zapp.id }}-{{ zapp.manifest_index }}">
<label>Execution name:&nbsp;<input type="text" name="exec_name" value="{{ zapp.zoe_description.name }}" maxlength="16" size="18" required/></label><br/>
{% for param in zapp.parameters %}
<label>{{ param.readable_name }}
{% if resources_are_customizable %}
<h4>Start-up parameters:</h4>
<form action="{{ reverse_url("zappshop_start", "") }}{{ zapp.id }}-{{ zapp.manifest_index }}" method="post" id="zapp_start_form">
<input type="hidden" name="zapp-id" value="{{ zapp.id }}-{{ zapp.manifest_index }}">
<label>Execution name:&nbsp;<input type="text" name="exec_name" value="{{ zapp.zoe_description.name }}" maxlength="16" size="18" required/></label><br/>
{% for param in zapp.parameters %}
<label>{{ param.readable_name }}
{% 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" %}
<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 %}
<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 %}
</label><br/>
{% endfor %}
{% if resources_are_customizable %}
</label><br/>
{% endfor %}
{% for service in zapp.zoe_description.services %}
<div class="resource-form">
<h5>{{ service.name }}</h5>
<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>
<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>
</div>
<div class="resource-form">
<h5>{{ service.name }}</h5>
<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>
<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>
</div>
{% endfor %}
{% endif %}
<hr>
{% 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>
<br><br>
{% endif %}
<hr>
{% 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>
<br><br>
{% endif %}
<button id="submit" type="submit">Start</button>
<button type="reset">Reset</button>
</form>
......
......@@ -95,7 +95,11 @@ class ZAppStartWeb(ZoeWebRequestHandler):
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:
for service in app_descr['services']:
if 'labels' in service:
......@@ -132,34 +136,38 @@ class ZAppStartWeb(ZoeWebRequestHandler):
if service['name'] == param.name:
service['command'] = self.get_argument(argument_name)
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:
log.warning('Unknown parameter kind: {}, ignoring...'.format(param.kind))
if role.can_customize_resources:
for service in app_descr['services']:
argument_name = service['name'] + '-resource_memory_min'
try:
self.get_argument(argument_name)
except MissingArgumentError:
pass
for service in app_descr['services']:
argument_name = service['name'] + '-resource_memory_min'
try:
self.get_argument(argument_name)
except MissingArgumentError:
pass
else:
if float(self.get_argument(argument_name)) >= get_conf().max_memory_limit:
val = int(get_conf().max_memory_limit * (1024 ** 3))
else:
if float(self.get_argument(argument_name)) >= get_conf().max_memory_limit:
val = int(get_conf().max_memory_limit * (1024 ** 3))
else:
val = int(float(self.get_argument(argument_name)) * (1024 ** 3))
service["resources"]["memory"]["min"] = val
argument_name = service['name'] + '-resource_cores_min'
try:
self.get_argument(argument_name)
except MissingArgumentError:
pass
val = int(float(self.get_argument(argument_name)) * (1024 ** 3))
service["resources"]["memory"]["min"] = val
argument_name = service['name'] + '-resource_cores_min'
try:
self.get_argument(argument_name)
except MissingArgumentError:
pass
else:
if float(self.get_argument(argument_name)) >= get_conf().max_core_limit:
val = get_conf().max_core_limit
else:
if float(self.get_argument(argument_name)) >= get_conf().max_core_limit:
val = get_conf().max_core_limit
else:
val = float(self.get_argument(argument_name))
service["resources"]["cores"]["min"] = val
break
val = float(self.get_argument(argument_name))
service["resources"]["cores"]["min"] = val
break
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