Commit 128337ee authored by Daniele Venzano's avatar Daniele Venzano
Browse files

Implement platform status page

Delete old files no longer of use
parent 2815cf62
......@@ -43,7 +43,7 @@ class SwarmClient:
ns.cores_total = int(info["DriverStatus"][idx + node + 2][1].split(' / ')[1])
ns.memory_reserved = info["DriverStatus"][idx + node + 3][1].split(' / ')[0]
ns.memory_total = info["DriverStatus"][idx + node + 3][1].split(' / ')[1]
ns.labels = ns.cores_reserved = info["DriverStatus"][idx + node + 4][1:]
ns.labels = info["DriverStatus"][idx + node + 4][1:]
pl_status.nodes.append(ns)
idx += 4
......
......@@ -97,8 +97,20 @@ def execution_new():
return jsonify(status="error")
@api_bp.route('/executions/terminate/<exec_id>')
def execution_terminate(exec_id):
@api_bp.route('/executions/logs/container/<int:container_id>')
def execution_logs(container_id: int):
client = get_zoe_client()
_api_check_user(client)
log = client.log_get(container_id)
if log is None:
return jsonify(status="error", msg="no log found")
else:
return jsonify(status="ok", log=log)
@api_bp.route('/executions/terminate/<int:exec_id>')
def execution_terminate(exec_id: int):
client = get_zoe_client()
_api_check_user(client)
......@@ -107,8 +119,8 @@ def execution_terminate(exec_id):
return jsonify(status="ok")
@api_bp.route('/history/logs/<execution_id>')
def history_logs_get(execution_id):
@api_bp.route('/history/logs/<int:execution_id>')
def history_logs_get(execution_id: int):
client = get_zoe_client()
_api_check_user(client)
......
from flask import jsonify, request, send_file, abort, Blueprint
from zipfile import is_zipfile
@app.route("/api/<int:user_id>/cluster/<int:cluster_id>/terminate")
def api_terminate_cluster(user_id, cluster_id):
db = CAaaState()
ret = {}
if not db.check_user_id(user_id):
ret["status"] = "unauthorized"
return jsonify(**ret)
cluster_id = str(cluster_id)
cluster_list = db.get_clusters(user_id)
if cluster_id not in cluster_list:
return abort(404)
if cluster_list[cluster_id]["user_id"] != user_id:
ret["status"] = "unauthorized"
return jsonify(**ret)
if sm.terminate_cluster(cluster_id):
ret["status"] = "ok"
else:
ret["status"] = "error"
return jsonify(**ret)
@app.route("/api/<int:user_id>/container/<int:container_id>/logs")
def api_container_logs(user_id, container_id):
db = CAaaState()
ret = {}
if not db.check_user_id(user_id):
ret["status"] = "unauthorized"
return jsonify(**ret)
logs = sm.get_log(container_id)
if logs is None:
ret["status"] = "no such container"
ret["logs"] = ''
else:
logs = logs.decode("ascii").split("\n")
ret["status"] = "ok"
ret["logs"] = logs
return jsonify(**ret)
@app.route("/api/<int:user_id>/history/<app_id>/logs")
def api_history_log_archive(user_id, app_id):
state = CAaaState()
if not state.check_user_id(user_id):
return jsonify(status="unauthorized")
ah = AppHistory(user_id)
path = ah.get_log_archive_path(app_id)
return send_file(path, mimetype="application/zip")
......@@ -5,62 +5,6 @@ from zoe_client import ZoeClient
from common.configuration import conf
@app.route("/web/status")
def web_status():
client = ZoeClient()
status = client.platform_status()
return render_template('status.html', status=status)
@app.route("/web/login/<email>")
def web_login(email):
client = ZoeClient()
user_id = client.user_get(email)
if user_id is None:
user_id = client.user_new(email)
return redirect(url_for("web_index", user_id=user_id))
@app.route("/web/<int:user_id>")
def web_index(user_id):
client = ZoeClient()
if not client.user_check(user_id):
return redirect(url_for('index'))
template_vars = {
"user_id": user_id,
"email": client.user_get(user_id).email
}
return render_template('home.html', **template_vars)
@app.route("/web/<int:user_id>/apps")
def web_user_apps(user_id):
client = ZoeClient()
if not client.user_check(user_id):
return redirect(url_for('index'))
apps = client.application_list(user_id)
template_vars = {
"user_id": user_id,
"apps": apps
}
return render_template('apps.html', **template_vars)
@app.route("/web/<int:user_id>/spark-notebook")
def web_notebook(user_id):
client = ZoeClient()
if not client.user_check(user_id):
return redirect(url_for('index'))
template_vars = {
"user_id": user_id,
"max_age": conf['notebook_max_age_no_activity'],
"wrn_time": conf['notebook_max_age_no_activity'] - conf['notebook_warning_age_no_activity']
}
return render_template('notebook.html', **template_vars)
@app.route("/web/<int:user_id>/cluster/<int:app_id>/inspect")
def web_inspect(user_id, app_id):
client = ZoeClient()
......@@ -78,24 +22,6 @@ def web_inspect(user_id, app_id):
return render_template('inspect.html', **template_vars)
@app.route("/web/<int:user_id>/execution/<int:execution_id>/terminate")
def web_terminate(user_id, execution_id):
client = ZoeClient()
if not client.user_check(user_id):
return redirect(url_for('index'))
execution = client.execution_get(execution_id)
application = client.application_get(execution.application_id)
if application.user_id != user_id:
abort(404)
template_vars = {
"execution_name": execution.name,
"execution_id": execution_id,
"user_id": user_id
}
return render_template('execution_terminate.html', **template_vars)
@app.route("/web/<int:user_id>/container/<int:container_id>/logs")
def web_logs(user_id, container_id):
client = ZoeClient()
......@@ -116,15 +42,3 @@ def web_logs(user_id, container_id):
"cont_logs": logs
}
return render_template('logs.html', **ret)
@app.route("/web/<int:user_id>/submit-spark-app")
def web_spark_submit(user_id):
client = ZoeClient()
if not client.user_check(user_id):
return redirect(url_for('index'))
template_vars = {
'user_id': user_id,
}
return render_template('submit.html', **template_vars)
......@@ -9,8 +9,10 @@ import zoe_web.utils as web_utils
def status_platform():
client = get_zoe_client()
user = web_utils.check_user(client)
platform_report = client.platform_status().report
template_vars = {
"user_id": user.id,
"email": user.email
"platform": platform_report
}
return render_template('status.html', **template_vars)
return render_template('platform_status.html', **template_vars)
{% extends "base_user.html" %}
{% block title %}Spark notebook{% endblock %}
{% block content %}
<h2>Spark Notebook</h2>
<p>You notebook is available at: <a href="{{ notebook_address }}">{{ notebook_address }}</a></p>
<p>Please note that notebooks are <b>automatically terminated {{ max_age }} hours after the last access</b>.
A warning email will be sent {{ wrn_time }} hours before this happens.</p>
{% endblock %}
\ No newline at end of file
{% extends "base_user.html" %}
{% block title %}Status{% endblock %}
{% block content %}
<h2>System status overview</h2>
<ul>
<li>Running containers: {{ platform.swarm.container_count }}</li>
<li>Images: {{ platform.swarm.image_count }}</li>
<li>Total memory: {{ platform.swarm.memory_total|filesizeformat }}</li>
<li>Number of cores: {{ platform.swarm.cores_total }}</li>
<li>Swarm placement strategy: {{ platform.swarm.placement_strategy }}</li>
</ul>
<h3>Node status:</h3>
{% for node in platform.swarm.nodes %}
<h4>{{ node.name }}</h4>
<ul>
<li>Running containers: {{ node.container_count }}</li>
<li>Cores: {{ node.cores_total }}</li>
<li>Cores reserved: {{ node.cores_reserved }}</li>
<li>Memory: {{ node.memory_total }}</li>
<li>Memory reserved: {{ node.memory_reserved }}</li>
<li>Labels: {{ node.labels }}</li>
</ul>
{% endfor %}
{% endblock %}
\ No newline at end of file
{% extends "base_user.html" %}
{% block title %}Status{% endblock %}
{% block content %}
<h2>System status overview</h2>
<ul>
<li>Containers: {{ Containers }}</li>
<li>Images: {{ Images }}</li>
<li>MemTotal: {{ MemTotal }}</li>
<li>Memory limit: {{ MemoryLimit }}</li>
<li>NCPU: {{ NCPU }}</li>
<li>Driver status:</li>
<li><ul>
{% for entry in DriverStatus %}
<li>{{ entry[0] }}: {{ entry[1] }}</li>
{% endfor %}
</ul></li>
</ul>
{% endblock %}
\ No newline at end of file
{% extends "base_user.html" %}
{% block title %}Submit Spark application{% endblock %}
{% block content %}
<h2>Submit Spark application</h2>
<p>Use the form below to submit a Spark application.<br>
The application should be packaged in a zip archive containing all the files needed by the application.</p>
<form enctype="multipart/form-data" id="app_upload">
<label for="exec_name">Execution name:</label>
<input type="text" autofocus autocomplete="on" required pattern="[a-z0-9_\-]+" name="exec_name" id="exec_name" placeholder="myapp-run-25"><br/>
<label for="cmd_line">Command line:</label>
<input type="text" autocomplete="on" required name="cmd_line" id="cmd_line" size="150" placeholder="wordcount.py hdfs://192.168.45.157/datasets/gutenberg_big_2x.txt hdfs://192.168.45.157/tmp/cntwdc1"><br/>
<label for="spark_options">Spark options:</label>
<input type="text" autocomplete="on" name="spark_options" id="spark_options" size="100"><br/>
<label for="upload">Spark application package:</label>
<input type="file" name="file" id="upload" accept="application/zip"><br/>
<input type="button" value="Submit" id="submit">
</form>
<progress style="display: none" id="progress"></progress>
<script type="application/javascript">
function progressHandlingFunction(e){
if(e.lengthComputable){
$('progress').attr({value:e.loaded,max:e.total});
}
}
function completeHandler(e) {
location.href = "http://" + window.location.hostname + "/web/{{ user_id }}/apps";
return false;
}
function errorHandler(e) {
$("#progress").hide();
}
$('#submit').on('click', function(){
var formData = new FormData($('#app_upload')[0]);
$("#progress").show();
$.ajax({
url: '{{ url_for("api_spark_submit", user_id=user_id) }}', //Server script to process data
type: 'POST',
xhr: function() { // Custom XMLHttpRequest
var myXhr = $.ajaxSettings.xhr();
if(myXhr.upload){ // Check if upload property exists
myXhr.upload.addEventListener('progress', progressHandlingFunction, false); // For handling the progress of the upload
}
return myXhr;
},
//Ajax events
//beforeSend: beforeSendHandler,
success: completeHandler,
error: errorHandler,
// Form data
data: formData,
//Options to tell jQuery not to process data or worry about content-type.
cache: false,
contentType: false,
processData: false
});
});
</script>
{% endblock %}
\ No newline at end of file
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