update batch on web to support multi datacenters

This commit is contained in:
Firmlyzhu 2019-03-23 19:22:15 +08:00
parent a3c6a9b867
commit b058412584
4 changed files with 158 additions and 61 deletions

View File

@ -43,6 +43,14 @@
<div class="form-group"><label class="col-sm-2 control-label">Job Name</label> <div class="form-group"><label class="col-sm-2 control-label">Job Name</label>
<div class="col-sm-10"><input type="text" class="form-control" name="jobName" id="job_name" required></div> <div class="col-sm-10"><input type="text" class="form-control" name="jobName" id="job_name" required></div>
</div> </div>
<br/>
<div class="form-group"><label class="col-sm-2 control-label">Location</label>
<div class="col-sm-10"><select id="masterselector" class="form-control">
{% for master in masterips %}
<option value="{{master.split("@")[0]}}">{{master.split("@")[1]}}</option>
{% endfor %}
</select></div>
</div>
<div class="hr-line-dashed"></div> <div class="hr-line-dashed"></div>
<br/> <br/>
<div class="form-group"><label class="col-sm-2 control-label">Priority</label> <div class="form-group"><label class="col-sm-2 control-label">Priority</label>
@ -64,7 +72,7 @@
<div class="form-group"> <div class="form-group">
<div class="col-sm-4 col-sm-offset-2"> <div class="col-sm-4 col-sm-offset-2">
<button class="btn btn-primary" type="button" id="add_task" class="btn btn-box-tool" title="add a task">Add Task <i class="fa fa-plus"></i></button> <button class="btn btn-primary" type="button" id="add_task" class="btn btn-box-tool" title="add a task">Add Task <i class="fa fa-plus"></i></button>
<button class="btn btn-primary" type="submit">Create</button> <button class="btn btn-primary" type="submit">Create Job</button>
</div> </div>
</div> </div>
</div> </div>
@ -96,6 +104,11 @@
<script type="text/javascript"> <script type="text/javascript">
var task_number = 0; var task_number = 0;
var mapping_number = 0; var mapping_number = 0;
var images_text = "{{ images }}";
images_text = images_text.replace(/&#39;/g,"\"");
console.log(images_text);
var images_info = JSON.parse(images_text);
console.log(images_info);
$().ready(function() { $().ready(function() {
$("#form").validate(); $("#form").validate();
}); });
@ -132,8 +145,68 @@
+'Remove</button></div>'; +'Remove</button></div>';
} }
$("select#masterselector").change(function() {
var masterip=$(this).children('option:selected').val();
var mastername=$(this).children('option:selected').html();
console.log(masterip);
var host = window.location.host;
var images = images_info;
for(var tnum = 1; tnum<=task_number; ++tnum)
{
var imagehtml =
"<thead>"
+"<tr>"
+"<th>ImageName</th>"
+"<th>Type</th>"
+"<th>Owner</th>"
+"<th>Size</th>"
+"<th>Description</th>"
+"<th>Choose</th>"
+"</tr>"
+"</thead>"
+"<tbody>"
+"<tr>"
+"<td>base</td>"
+"<td>public</td>"
+"<td>docklet</td>"
+"<td>--</td>"
+"<td>A base image for you</td>"
+'<td><div class="i-checks"><label><input type="radio" name="image_' + tnum + '" value="base_base_base" checked="checked"></label></div></td>'
+"</tr>";
for(var index in images[masterip].private) {
var image = images[masterip].private[index];
imagehtml +=
"<tr>"
+"<td>"+image.name+"</td>"
+"<td>private</td>"
+"<td>{{user}}</td>"
+"<td>"+image.size_format+"</td>"
+'<td><a href="/image/' + masterip + '/description/' + image.name + '_' + '{{user}}' + '_private/" target="_blank">' + image.description + '</a></td>'
+'<td><div class="i-checks"><label><input type="radio" name="image_' + tnum + '" value="'+image.name+'_{{user}}_private"><label></div></td>'
+"</tr>";
}
for(var p_user in images[masterip].public) {
for(var index in images[masterip].public[p_user]) {
image=images[masterip].public[p_user][index];
imagehtml +=
"<tr>"
+"<td>"+image.name+"</td>"
+"<td>public</td>"
+"<td>" + p_user + "</td>"
+"<td>"+image.size_format+"</td>"
+'<td><a href="/image/' + masterip + '/description/' + image.name + "_" + p_user + '_public/" target="_blank">' + image.description + '</a></td>'
+'<td><div class="i-checks"><label><input type="radio" name="image_' + tnum + '" value="'+image.name+'_{{p_user}}_public"><label></div></td>'
+"</tr>";
}
}
imagehtml += "</tbody>";
$("#imagetable"+tnum).html(imagehtml);
}
});
function addTask() { function addTask() {
task_number += 1; task_number += 1;
var masterip=$("select#masterselector").children('option:selected').val();
mapping_number = 0; mapping_number = 0;
var task_html = ''; var task_html = '';
task_html += task_html +=
@ -195,50 +268,60 @@
+'<label class="col-sm-2 control-label">Start at the Same Time</label>' +'<label class="col-sm-2 control-label">Start at the Same Time</label>'
+'<div class="col-sm-3"><input type="checkbox" name="atSameTime_' + task_number + '" checked="checked"/>' +'<div class="col-sm-3"><input type="checkbox" name="atSameTime_' + task_number + '" checked="checked"/>'
+'</div></div>' +'</div></div>'
+'<div class="form-group"><label class="col-sm-2 control-label">Image Choose</label>' var images = images_info
+'<div class="col-sm-10">' task_html +=
+'<table id="imagetable" class="table table-striped table-bordered table-hover table-image" >' '<div class="form-group"><label class="col-sm-2 control-label">Image Choose</label>'
+'<thead>' +'<div class="col-sm-10">'
+'<tr>' +'<table id="imagetable' + task_number +'" class="table table-striped table-bordered table-hover table-image" >'
+'<th>ImageName</th>' +"<thead>"
+'<th>Type</th>' +"<tr>"
+'<th>Owner</th>' +"<th>ImageName</th>"
+'<th>Description</th>' +"<th>Type</th>"
+'<th>Choose</th>' +"<th>Owner</th>"
+'</tr>' +"<th>Size</th>"
+'</thead>' +"<th>Description</th>"
+'<tbody>' +"<th>Choose</th>"
+'<tr>' +"</tr>"
+'<td>base</td>' +"</thead>"
+'<td>public</td>' +"<tbody>"
+'<td>docklet</td>' +"<tr>"
+'<td>A base image for you</td>' +"<td>base</td>"
+'<td><div class="i-checks"><label><input type="radio" name="image_' + task_number + '" value="base_base_base" checked="checked"></label></div></td>' +"<td>public</td>"
+'</tr>' +"<td>docklet</td>"
+'{% for image in images['private'] %}' +"<td>--</td>"
+'<tr>' +"<td>A base image for you</td>"
+'<td>{{image['name']}}</td>' +'<td><div class="i-checks"><label><input type="radio" name="image_' + task_number + '" value="base_base_base" checked="checked"></label></div></td>'
+'<td>private</td>' +"</tr>";
+'<td>{{user}}</td>' for(var index in images[masterip].private) {
+'<td><a href="/image/{{masterips[0].split("@")[1]}}/description/{{image['name']}}_{{user}}_private/" target="_blank">{{image['description']}}</a></td>' var image = images[masterip].private[index];
+'<td><div class="i-checks"><label><input type="radio" name="image_' + task_number + '" value="{{image['name']}}_{{user}}_private"></label></div></td>' task_html +=
+'</tr>' "<tr>"
+'{% endfor %}' +"<td>"+image.name+"</td>"
+'{% for p_user,p_images in images['public'].items() %}' +"<td>private</td>"
+'{% for image in p_images %}' +"<td>{{user}}</td>"
+'<tr>' +"<td>"+image.size_format+"</td>"
+'<td>{{image['name']}}</td>' +'<td><a href="/image/' + masterip + '/description/' + image.name + '_' + '{{user}}' + '_private/" target="_blank">' + image.description + '</a></td>'
+'<td>public</td>' +'<td><div class="i-checks"><label><input type="radio" name="image_' + task_number + '" value="'+image.name+'_{{user}}_private"><label></div></td>'
+'<td>{{p_user}}</td>' +"</tr>";
+'<td><a href="/image/{{masterips[0].split("@")[1]}}/description/{{image['name']}}_{{p_user}}_public/" target="_blank">{{image['description']}}</a></td>' }
+'<td><div class="i-checks"><label><input type="radio" name="image_' + task_number + '" value="{{image['name']}}_{{p_user}}_public"></label></div></td>' for(var p_user in images[masterip].public) {
+'</tr>' for(var index in images[masterip].public[p_user]) {
+'{% endfor %}' image=images[masterip].public[p_user][index];
+'{% endfor %}' task_html +=
+'</tbody>' "<tr>"
+'</table>' +"<td>"+image.name+"</td>"
+'</div>' +"<td>public</td>"
+'</div>' +"<td>" + p_user + "</td>"
+"<td>"+image.size_format+"</td>"
+'<td><a href="/image/' + masterip + '/description/' + image.name + "_" + p_user + '_public/" target="_blank">' + image.description + '</a></td>'
+'<td><div class="i-checks"><label><input type="radio" name="image_' + task_number + '" value="'+image.name+'_{{p_user}}_public"><label></div></td>'
+"</tr>";
}
}
task_html +=
'</tbody></table>'
+'</div>'
+'</div>'
+'<div class="form-group">' +'<div class="form-group">'
+'<span>' +'<span>'
+'<label class="col-sm-2 contril-label">Exteranl Storage Mapping</label>' +'<label class="col-sm-2 contril-label">Exteranl Storage Mapping</label>'

View File

@ -31,8 +31,9 @@
<p> <p>
<a href="/batch_job/create/"><button type="button" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> Create Batch Job</button></a> <a href="/batch_job/create/"><button type="button" class="btn btn-primary btn-sm"><i class="fa fa-plus"></i> Create Batch Job</button></a>
</p> </p>
{% for job_info in job_list %} {% for master in masterips %}
<div class="modal inmodal" id='OutputModal_{{ job_info['job_id'] }}' tabindex="-1" role="dialog" aria-hidden="true"> {% for job_info in job_list[master.split('@')[0]] %}
<div class="modal inmodal" id='OutputModal_{{ master }}_{{ job_info['job_id'] }}' tabindex="-1" role="dialog" aria-hidden="true">
<div class="modal-dialog"> <div class="modal-dialog">
<div class="modal-content animated fadeIn"> <div class="modal-content animated fadeIn">
<div class="modal-header"> <div class="modal-header">
@ -55,8 +56,8 @@
<tr> <tr>
<td>{{ taskid }}</td> <td>{{ taskid }}</td>
<td>{{ vnodeid }}</td> <td>{{ vnodeid }}</td>
<td><a class="btn btn-info btn-xs" href='/batch_job/output/{{ job_info["job_id"] }}/{{ taskid }}/{{ vnodeid }}/stdout/' target="_blank">Stdout</a></td> <td><a class="btn btn-info btn-xs" href='/batch_job/output/{{ master.split('@')[0] }}/{{ job_info["job_id"] }}/{{ taskid }}/{{ vnodeid }}/stdout/' target="_blank">Stdout</a></td>
<td><a class="btn btn-info btn-xs" href='/batch_job/output/{{ job_info["job_id"] }}/{{ taskid }}/{{ vnodeid }}/stderr/' target="_blank">Stderr</a></td> <td><a class="btn btn-info btn-xs" href='/batch_job/output/{{ master.split('@')[0] }}/{{ job_info["job_id"] }}/{{ taskid }}/{{ vnodeid }}/stderr/' target="_blank">Stderr</a></td>
</tr> </tr>
{% endfor %} {% endfor %}
{% endfor %} {% endfor %}
@ -70,10 +71,12 @@
</div> </div>
</div> </div>
{% endfor %} {% endfor %}
{% endfor %}
<div class="table"> <div class="table">
<table width="100%" cellspacing="0" style="margin: 0 auto;" class="table table-striped table-bordered table-hover table-batch"> <table width="100%" cellspacing="0" style="margin: 0 auto;" class="table table-striped table-bordered table-hover table-batch">
<thead> <thead>
<tr> <tr>
<th>Location</th>
<th>ID</th> <th>ID</th>
<th>Name</th> <th>Name</th>
<th>Status</th> <th>Status</th>
@ -84,19 +87,22 @@
</tr> </tr>
<thead> <thead>
<tbody> <tbody>
{% for job_info in job_list %} {% for master in masterips %}
{% for job_info in job_list[master.split('@')[0]] %}
<tr> <tr>
<td>{{ master.split('@')[1] }}</td>
<td>{{ job_info['job_id'] }}</td> <td>{{ job_info['job_id'] }}</td>
<td>{{ job_info['job_name'] }}</td> <td>{{ job_info['job_name'] }}</td>
<td> <td>
{{ job_info['status'] }} {{ job_info['status'] }}
</td> </td>
<td>Tasks</td> <td>Tasks</td>
<td><a href="/batch_job/{{masterips[0].split("@")[0]}}/stop/{{ job_info['job_id'] }}/"><button type="button" class="btn btn-xs btn-warning"> &nbsp;Stop&nbsp;&nbsp; </button></a></td> <td><a href="/batch_job/{{master.split("@")[0]}}/stop/{{ job_info['job_id'] }}/"><button type="button" class="btn btn-xs btn-warning"> &nbsp;Stop&nbsp;&nbsp; </button></a></td>
<td>{{ job_info['create_time'] }}</td> <td>{{ job_info['create_time'] }}</td>
<td><a role="button" class="btn btn-info btn-xs" id='{{ job_info['job_id'] }}_output' data-toggle="modal" data-target='#OutputModal_{{ job_info['job_id'] }}'>Get Output</a></td> <td><a role="button" class="btn btn-info btn-xs" id='{{ master }}_{{ job_info['job_id'] }}_output' data-toggle="modal" data-target='#OutputModal_{{ master }}_{{ job_info['job_id'] }}'>Get Output</a></td>
</tr> </tr>
{% endfor %} {% endfor %}
{% endfor %}
</tbody> </tbody>
</table> </table>
</div> </div>

View File

@ -157,9 +157,10 @@ def stop_batch_job(masterip,jobid):
def state_batch_job(): def state_batch_job():
return stateBatchJobView().as_view() return stateBatchJobView().as_view()
@app.route("/batch_job/output/<jobid>/<taskid>/<vnodeid>/<issue>/", methods=['GET']) @app.route("/batch_job/output/<masterip>/<jobid>/<taskid>/<vnodeid>/<issue>/", methods=['GET'])
@login_required @login_required
def output_batch_job(jobid, taskid, vnodeid, issue): def output_batch_job(masterip, jobid, taskid, vnodeid, issue):
outputBatchJobView.masterip = masterip
outputBatchJobView.jobid = jobid outputBatchJobView.jobid = jobid
outputBatchJobView.taskid = taskid outputBatchJobView.taskid = taskid
outputBatchJobView.vnodeid = vnodeid outputBatchJobView.vnodeid = vnodeid

View File

@ -3,6 +3,7 @@ from webViews.view import normalView
from webViews.log import logger from webViews.log import logger
from webViews.checkname import checkname from webViews.checkname import checkname
from webViews.dockletrequest import dockletRequest from webViews.dockletrequest import dockletRequest
import json
class batchJobListView(normalView): class batchJobListView(normalView):
template_path = "batch/batch_list.html" template_path = "batch/batch_list.html"
@ -10,9 +11,12 @@ class batchJobListView(normalView):
@classmethod @classmethod
def get(self): def get(self):
masterips = dockletRequest.post_to_all() masterips = dockletRequest.post_to_all()
result = dockletRequest.post("/batch/job/list/",{},masterips[0].split("@")[0]) job_list = {}
job_list = result.get("data") for ipname in masterips:
logger.debug("job_list: %s" % job_list) ip = ipname.split("@")[0]
result = dockletRequest.post("/batch/job/list/",{},ip)
job_list[ip] = result.get("data")
logger.debug("job_list[%s]: %s" % (ip,job_list[ip]))
if True: if True:
return self.render(self.template_path, masterips=masterips, job_list=job_list) return self.render(self.template_path, masterips=masterips, job_list=job_list)
else: else:
@ -24,7 +28,10 @@ class createBatchJobView(normalView):
@classmethod @classmethod
def get(self): def get(self):
masterips = dockletRequest.post_to_all() masterips = dockletRequest.post_to_all()
images = dockletRequest.post("/image/list/",{},masterips[0].split("@")[0]).get("images") images = {}
for master in masterips:
images[master.split("@")[0]] = dockletRequest.post("/image/list/",{},master.split("@")[0]).get("images")
logger.info(images)
if True: if True:
return self.render(self.template_path, masterips=masterips, images=images) return self.render(self.template_path, masterips=masterips, images=images)
else: else:
@ -67,6 +74,7 @@ class stopBatchJobView(normalView):
class outputBatchJobView(normalView): class outputBatchJobView(normalView):
template_path = "batch/batch_output.html" template_path = "batch/batch_output.html"
masterip = ""
jobid = "" jobid = ""
taskid = "" taskid = ""
vnodeid = "" vnodeid = ""
@ -74,18 +82,17 @@ class outputBatchJobView(normalView):
@classmethod @classmethod
def get(self): def get(self):
masterips = dockletRequest.post_to_all()
data = { data = {
'jobid':self.jobid, 'jobid':self.jobid,
'taskid':self.taskid, 'taskid':self.taskid,
'vnodeid':self.vnodeid, 'vnodeid':self.vnodeid,
'issue':self.issue 'issue':self.issue
} }
result = dockletRequest.post("/batch/job/output/",data,masterips[0].split("@")[0]) result = dockletRequest.post("/batch/job/output/",data,self.masterip)
output = result.get("data") output = result.get("data")
#logger.debug("job_list: %s" % job_list) #logger.debug("job_list: %s" % job_list)
if result.get('success',"") == "true": if result.get('success',"") == "true":
return self.render(self.template_path, masterip=masterips[0].split("@")[0], jobid=self.jobid, return self.render(self.template_path, masterip=self.masterip, jobid=self.jobid,
taskid=self.taskid, vnodeid=self.vnodeid, issue=self.issue, output=output) taskid=self.taskid, vnodeid=self.vnodeid, issue=self.issue, output=output)
else: else:
return self.error() return self.error()