476 lines
25 KiB
HTML
Executable File
476 lines
25 KiB
HTML
Executable File
{% extends "base_AdminLTE.html"%}
|
|
|
|
<!--
|
|
Config Page :
|
|
1. images
|
|
2. workspace templates
|
|
|
|
-->
|
|
|
|
{% block title %}Docklet | Config{% endblock %}
|
|
|
|
{% block panel_title %}Config{% endblock %}
|
|
|
|
{% block panel_list %}
|
|
<ol class="breadcrumb">
|
|
<li>
|
|
<a href="/dashboard/"><i class="fa fa-dashboard"></i>Home</a>
|
|
</li>
|
|
<li class="active">
|
|
<strong>Config</strong>
|
|
</li>
|
|
</ol>
|
|
{% endblock %}
|
|
|
|
{% block css_src %}
|
|
<link href="//cdn.bootcss.com/datatables/1.10.11/css/dataTables.bootstrap.min.css" rel="stylesheet">
|
|
<link href="//cdn.bootcss.com/datatables/1.10.11/css/jquery.dataTables_themeroller.css" rel="stylesheet">
|
|
<link href="/static/dist/css/modalconfig.css" rel="stylesheet">
|
|
{% endblock %}
|
|
|
|
|
|
{% block content %}
|
|
{% for master in allclusters %}
|
|
{% for clustername, clusterinfo in allclusters[master].items() %}
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="box box-info collapsed-box">
|
|
<div class="box-header with-border">
|
|
<h3 class="box-title">WorkSpace Name: {{ clustername }} <strong>@ {{master.split("@")[1]}}</strong></h3>
|
|
|
|
<div class="box-tools pull-right">
|
|
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
|
|
</div>
|
|
</div>
|
|
<div class="box-body" style="display:none">
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="box box-info">
|
|
<div class="box-header with-border">
|
|
<h4 class="box-title">VCLUSTER</h4>
|
|
<h5>create_time:{{clusterinfo['create_time']}}      start_time:{{clusterinfo['start_time']}}</h5>
|
|
|
|
<div class="box-tools pull-right">
|
|
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
|
|
</div>
|
|
</div>
|
|
<div class="box-body">
|
|
<p>
|
|
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#Scaleout_{{ clustername }}_{{master.split("@")[1]}}"><i class="fa fa-plus"></i>Add Node</button>
|
|
</p>
|
|
<div class="modal inmodal" id="Scaleout_{{ clustername }}_{{master.split("@")[1]}}" tabindex="-1" role="dialog" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content animated fadeIn">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
|
<i class="fa fa-plus modal-icon"></i>
|
|
<h4 class="modal-title">Choose Image</h4>
|
|
<small class="font-bold">Choose an image to add node</small>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="form-group">
|
|
<form action="/workspace/{{master.split("@")[0]}}/scaleout/{{ clustername }}/" method="POST" >
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
<table class="table table-striped table-bordered table-hover table-image">
|
|
<thead>
|
|
<tr>
|
|
<th>ImageName</th>
|
|
<th>Type</th>
|
|
<th>Owner</th>
|
|
<th>Size</th>
|
|
<th>Choose</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>base</td>
|
|
<td>public</td>
|
|
<td>docklet</td>
|
|
<td>--</td>
|
|
<td><input type="radio" name="image" value="base_base_base" checked="checked"></td>
|
|
</tr>
|
|
{% for image in allimages[master]['private'] %}
|
|
<tr>
|
|
<td>{{image['name']}}</td>
|
|
<td>private</td>
|
|
<td>{{mysession['username']}}</td>
|
|
<td>{{image['size_format']}}</td>
|
|
<td><input type="radio" name="image" value="{{image['name']}}_{{mysession['username']}}_private"></td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% for p_user, p_images in allimages[master]['public'].items() %}
|
|
{% for image in p_images %}
|
|
<tr>
|
|
<td>{{image['name']}}</td>
|
|
<td>public</td>
|
|
<td>{{p_user}}</td>
|
|
<td>{{image['size_format']}}</td>
|
|
<td><input type="radio" name="image" value="{{image['name']}}_{{p_user}}_public"></td>
|
|
</tr>
|
|
{% endfor %}
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
<div class="hr-line-dashed"></div>
|
|
<div class="panel-group" id="accordion_{{clustername}}_{{master.split("@")[1]}}">
|
|
<div class="panel panel-default">
|
|
<div class="panel-heading">
|
|
<h4 class="panel-title">
|
|
<a data-toggle="collapse" data-panel="#accordion_{{clustername}}_{{master.split("@")[1]}}" href="#collapseOne_{{clustername}}_{{master.split("@")[1]}}">
|
|
show advanced options
|
|
</a>
|
|
</h4>
|
|
</div>
|
|
<div id="collapseOne_{{clustername}}_{{master.split("@")[1]}}" class="panel-collapse collapse">
|
|
<div class="panel-body">
|
|
<div class="form-group">
|
|
<label class="control-label">CPU</label>
|
|
<div ><input type="number" class="form-control" name="cpuSetting" id="cpuSetting" value = {{defaultsetting['cpu']}} /> {{usage['cpu']}}CORE/{{quota['cpu']}}CORE
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">MEMORY</label>
|
|
<div ><input type="number" class="form-control" name="memorySetting" id="memorySetting" value = {{defaultsetting['memory']}} /> {{usage['memory']}}MB/{{quota['memory']}}MB
|
|
</div>
|
|
</div>
|
|
<div class="form-group">
|
|
<label class="control-label">DISK</label>
|
|
<div><input type="number" class="form-control" name="diskSetting" id="diskSetting" value= {{defaultsetting['disk']}} /> {{usage['disk']}} MB/{{quota['disk']}}MB (min value is the size of image + 100)
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
|
|
<button type="submit" class="btn btn-success">Add</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Node ID</th>
|
|
<th>Node Name</th>
|
|
<th>IP Address</th>
|
|
<th>Status</th>
|
|
<th>Image</th>
|
|
<th>Save</th>
|
|
<th>Delete</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for container in clusterinfo['containers'] %}
|
|
<tr>
|
|
<td>{{ loop.index }}</td>
|
|
<td>{{ container['containername'] }}</td>
|
|
<td>{{ container['ip'] }}</td>
|
|
|
|
{% if clusterinfo['status'] == 'stopped' %}
|
|
<td><div class="text-warning"><i class="fa fa-stop"></i> Stopped</div></td>
|
|
{% else %}
|
|
<td><div class="text-success"><i class="fa fa-play"></i> Running</div></td>
|
|
{% endif %}
|
|
|
|
<td>{{ container['image'] }}</td>
|
|
<td><button type="button" class="btn btn-success btn-xs" data-toggle="modal" data-target="#DelModal_{{ container['containername'] }}_{{master.split("@")[1]}}">Save</button></td>
|
|
{% if container['containername'][-2:] == '-0' %}
|
|
<td><button class="btn btn-xs btn-default">Delete</button></td>
|
|
{% else %}
|
|
<td><a class="btn btn-xs btn-danger" href="/workspace/{{master.split("@")[0]}}/scalein/{{ clustername }}/{{ container['containername'] }}/">Delete</a></td>
|
|
{% endif %}
|
|
<div class="modal inmodal" id="DelModal_{{ container['containername'] }}_{{master.split("@")[1]}}" tabindex="-1" role="dialog" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content animated fadeIn">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
|
<i class="fa fa-save modal-icon"></i>
|
|
<h4 class="modal-title">Save Image</h4>
|
|
<small class="font-bold">Save Your Environment As a Image</small>
|
|
</div>
|
|
<div class="modal-body">
|
|
<div class="form-group">
|
|
<form action="/workspace/{{master.split("@")[0]}}/save/{{ clustername }}/{{ container['containername'] }}/" method="POST" id="saveImage">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
<label>Image Name</label>
|
|
<input type="text" placeholder="Enter Image Name" class="form-control" name="ImageName" id="ImageName"/>
|
|
<br/>
|
|
<label>Description</label>
|
|
<textarea rows="5" cols="60" name="description" id="description">please input your description</textarea>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
|
|
<button type="submit" class="btn btn-success">Save</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
</tr>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div class="row">
|
|
<div class="col-md-12">
|
|
<div class="box box-info">
|
|
<div class="box-header with-border">
|
|
<h4 class="box-title">TCP Ports Mapping</h4>
|
|
<div class="box-tools pull-right">
|
|
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-minus"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
|
|
</div>
|
|
</div>
|
|
<div class="box-body">
|
|
<p>
|
|
<button type="button" class="btn btn-primary btn-sm" data-toggle="modal" data-target="#Addportsmapping_{{ clustername }}_{{master.split("@")[1]}}"><i class="fa fa-plus"></i>Apply</button>
|
|
</p>
|
|
<div class="modal inmodal" id="Addportsmapping_{{ clustername }}_{{master.split("@")[1]}}" tabindex="-1" role="dialog" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content animated fadeIn">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
|
<i class="fa fa-plus modal-icon"></i>
|
|
<h4 class="modal-title">Apply for TCP Ports Mapping</h4>
|
|
<small class="font-bold">Add a TCP port mapping for a node</small>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form action="/port_mapping/add/{{master.split("@")[0]}}/" method="POST" id="AddportsmappingForm">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
<div class="form-group">
|
|
<label>Cluster Name</label>
|
|
<input type = "text" value="{{ clustername }}" class="form-control" name="clustername" readonly="readonly">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Node Name</label>
|
|
<select class="form-control" name="node_name" onchange="chnodeip(this.value,node_ip)">
|
|
{% for container in clusterinfo['containers'] %}
|
|
<option value="{{ container['containername'] }}">{{ container['containername'] }}</option>
|
|
{% endfor %}
|
|
</select>
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Node IP</label>
|
|
<input type = "text" value="{{ clusterinfo["containers"][0]["ip"][:clusterinfo["containers"][0]["ip"].index("/")] }}" class="form-control" name="node_ip" readonly="readonly">
|
|
</div>
|
|
<div class="form-group">
|
|
<label>Node Port</label><small class="font-bold"> The port that the host port is mapping to(1-65535).</small>
|
|
<input type="number" class="form-control" placeholder="1-65535" value="80" name="node_port" id="node_port" min="1" max="65535"/>
|
|
</div>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
|
|
<button type="submit" class="btn btn-primary">Submit</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<table class="table table-bordered">
|
|
<thead>
|
|
<tr>
|
|
<th>Node Name</th>
|
|
<th>Node IP</th>
|
|
<th>Node Port</th>
|
|
<th>Host Public IP</th>
|
|
<th>Host Port</th>
|
|
<th>Delete</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for record in clusterinfo['port_mapping'] %}
|
|
<tr>
|
|
<td>{{ record['node_name'] }}</td>
|
|
<td>{{ record['node_ip'] }}</td>
|
|
<td>{{ record['node_port'] }}</td>
|
|
<td>{{ clusterinfo['proxy_public_ip'] }}</td>
|
|
<td>{{ record['host_port'] }}</td>
|
|
<td><a class="btn btn-xs btn-danger" href="/port_mapping/delete/{{master.split("@")[0]}}/{{ clustername }}/{{ record['node_name'] }}/{{ record['node_port'] }}/">Delete</a></td>
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
{% endfor %}
|
|
{% endfor %}
|
|
<div class="row">
|
|
<div class="col-lg-12">
|
|
<div class="box box-info collapsed-box">
|
|
<div class="box-header with-border">
|
|
<h3 class="box-title">Image Info</h3>
|
|
<div class="box-tools pull-right">
|
|
<button type="button" class="btn btn-box-tool" data-widget="collapse"><i class="fa fa-plus"></i>
|
|
</button>
|
|
<button type="button" class="btn btn-box-tool" data-widget="remove"><i class="fa fa-times"></i></button>
|
|
</div>
|
|
</div>
|
|
<div class="box-body" style="display:none">
|
|
|
|
<table class="table table-striped table-bordered table-hover table-image" >
|
|
<thead>
|
|
<tr>
|
|
<th>ImageName</th>
|
|
<th>Type</th>
|
|
<th>Owner</th>
|
|
<th>CreateTime</th>
|
|
<th>Size</th>
|
|
<th>Description</th>
|
|
<th>Location</th>
|
|
<th>Status</th>
|
|
<th>Operation</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
<tr>
|
|
<td>base</td>
|
|
<td>public</td>
|
|
<td>docklet</td>
|
|
<td>2015-01-01 00:00:00</td>
|
|
<td>--</td>
|
|
<td>A Base Image For You</td>
|
|
<td>--</td>
|
|
<td></td>
|
|
<td></td>
|
|
</tr>
|
|
{% for master in allimages %}
|
|
{% for image in allimages[master]['private'] %}
|
|
<tr>
|
|
<td>{{image['name']}}</td>
|
|
<td>private</td>
|
|
<td>{{mysession['username']}}</td>
|
|
<td>{{image['time']}}</td>
|
|
<td>{{image['size_format']}}</td>
|
|
<td><a href="/image/{{master.split("@")[0]}}/description/{{image['name']}}_{{mysession['username']}}_private/" target="_blank">{{image['description']}}</a></td>
|
|
<td>{{master.split("@")[1]}}</td>
|
|
{% if image['isshared'] == 'false' %}
|
|
<td>unshared</td>
|
|
<td>
|
|
<a href="/image/{{master.split("@")[0]}}/share/{{ image['name'] }}/"><button type="button" class="btn btn-xs btn-success">share</button></a>
|
|
<a href="/image/{{master.split("@")[0]}}/delete/{{ image['name'] }}/"><button type="button" class="btn btn-xs btn-danger">delete</button></a>
|
|
<button type="button" class="btn btn-xs btn-primary" data-toggle="modal" data-target="#Copyimage_{{ image['name'] }}_{{master.split("@")[1]}}">copy</button>
|
|
<div class="modal inmodal" id="Copyimage_{{ image['name'] }}_{{master.split("@")[1]}}" tabindex="-1" role="dialog" aria-hidden="true">
|
|
<div class="modal-dialog">
|
|
<div class="modal-content animated fadeIn">
|
|
<div class="modal-header">
|
|
<button type="button" class="close" data-dismiss="modal"><span aria-hidden="true">×</span><span class="sr-only">Close</span></button>
|
|
<i class="fa fa-plus modal-icon"></i>
|
|
<h4 class="modal-title">Copy image to other location</h4>
|
|
</div>
|
|
<div class="modal-body">
|
|
<form action="/image/{{master.split("@")[0]}}/copy/{{image['name']}}/" method="POST" id="CopyImageForm">
|
|
<input type="hidden" name="csrf_token" value="{{ csrf_token() }}">
|
|
<table class="table table-striped table-bordered table-hover table-image">
|
|
<thead>
|
|
<tr>
|
|
<th>Location</th>
|
|
<th>choose</th>
|
|
</tr>
|
|
</thead>
|
|
<tbody>
|
|
{% for targetmaster in masterips %}
|
|
{% if not master==targetmaster %}
|
|
<tr>
|
|
<td>{{ targetmaster.split("@")[1]}}</td>
|
|
<td><input type="radio" name="target" value="{{targetmaster.split("@")[0]}}"></td>
|
|
</tr>
|
|
{% endif %}
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
<div class="modal-footer">
|
|
<button type="button" class="btn btn-white" data-dismiss="modal">Close</button>
|
|
<button type="submit" class="btn btn-primary">Submit</button>
|
|
</div>
|
|
</form>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</td>
|
|
{% else %}
|
|
<td>shared</td>
|
|
<td>
|
|
<a href="/image/{{master.split("@")[0]}}/unshare/{{ image['name'] }}/"><button type="button" class="btn btn-xs btn-warning">unshare</button></a>
|
|
<a href="/image/{{master.split("@")[0]}}/delete/{{ image['name'] }}/"><button type="button" class="btn btn-xs btn-danger">delete</button></a>
|
|
<button type="button" class="btn btn-xs btn-primary" data-toggle="modal" data-target="#Copyimage_{{ image['name'] }}_{{master.split("@")[1]}}">Copy</button>
|
|
</td>
|
|
{% endif %}
|
|
</tr>
|
|
{% endfor %}
|
|
{% for p_user,p_images in allimages[master]['public'].items() %}
|
|
{% for image in p_images %}
|
|
<tr>
|
|
<td>{{image['name']}}</td>
|
|
<td>public</td>
|
|
<td>{{p_user}}</td>
|
|
<td>{{image['time']}}</td>
|
|
<td>{{image['size_format']}}</td>
|
|
<td><a href="/image/{{master.split("@")[0]}}/description/{{image['name']}}_{{p_user}}_public/" target="_blank">{{image['description']}}</a></td>
|
|
<td>{{master.split("@")[1]}}</td>
|
|
<td></td>
|
|
{% if p_user == mysession['username'] %}
|
|
<td><a href="/image/{{master.split("@")[0]}}/unshare/{{ image['name'] }}/"><button type="button" class="btn btn-xs btn-warning">unshare</button></a></td>
|
|
{% else %}
|
|
<td></td>
|
|
{% endif %}
|
|
</tr>
|
|
{% endfor %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
</tbody>
|
|
</table>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% endblock %}
|
|
|
|
{% block script_src %}
|
|
|
|
<script src="//cdn.bootcss.com/datatables/1.10.11/js/jquery.dataTables.js"></script>
|
|
<script src="//cdn.bootcss.com/datatables/1.10.11/js/dataTables.bootstrap.min.js"></script>
|
|
<script src="//cdn.bootcss.com/datatables-tabletools/2.1.5/js/TableTools.min.js"></script>
|
|
|
|
<script>
|
|
$(document).ready(function() {
|
|
$(".table-image").DataTable();
|
|
$(".table-image").attr("style","");
|
|
});
|
|
var map_node_ip = [];
|
|
{% for master in allclusters %}
|
|
{% for clustername, clusterinfo in allclusters[master].items() %}
|
|
{% for container in clusterinfo['containers'] %}
|
|
map_node_ip["{{ container['containername'] }}"] = "{{ container["ip"][:container["ip"].index("/")] }}";
|
|
{% endfor %}
|
|
{% endfor %}
|
|
{% endfor %}
|
|
function chnodeip(node_name,field)
|
|
{
|
|
field.value = map_node_ip[node_name];
|
|
}
|
|
</script>
|
|
|
|
{% endblock %}
|