summaryrefslogblamecommitdiffstats
path: root/modules-available/dnbd3/templates/page-serverlist.html
blob: bcb0d76629d077fd46a5e688feb430a52a2db386 (plain) (tree)
1
2
3
4
5
6
7
8
9


                                     
       

                                                                                       
                                                                                     

        








                                                                                                               
                                                                                                             



                                                                                    
                                                                                                                                                      

                                                                                              




                                                                
                                                      
                                                                                                                                                

                                                                                                



                                                                                                                                                         
                                                                                                                                                 








                                                                                                                            
                                                            
                                                           

                                   
                                                                                                                                        
                                                                         
                                              
                         

             
 



                                                             


                                         


                                                                                
                                                                                     











                                                                              
                                                                           





                                                                                                                 







                                                                                                                    
                                                                
                                                                                                                                                

                                                                                                                  
                                                                
                                                                                
                                                                                                           
                                                                                

                                                                                               
                                                                                
                                                    
                                                                                
                                                                                     

                                                                                                                     
                                                                                                                                                            
                                                                                             


                                                                                                    




                                                                                                                       
                                             
                                                                                                                                                  
                                                               
                                             
                                                                                                                    
                                                                                                                         
                                             



















                                                                                                                                                        
                                                                                                                                                                        



                                                                                                                    
                                                                           
                                                                

                                                                                                                                                      
                                                                                                                                                                
                                                                                                          


                                                                                                                        
                                                                                                                                            
                                                                                                                                                        
                                                                                                  



                                                                                                             

                                                                                                                                                                       






                                                                                                               
                
       
                                                                   
 

                                    
                                                                                                                                                 







                                                                                                               
                                                                                                                                                          






                                                                                                                

      
                                                         
                                  















                                                                                                              
 

                                                          


                                                                                                         
                                                                                          

                                                










                                                                                                              

                                                             
                                           
















                                                                                                                 



                      







                                                                                                         
                                                               












                                                                                                                          










                                                                                                         
                                                                                            
                                                                                                        




                                                                                                                                           


                                                                                                               
                                                                                                                                                    



                                                                                                             

                                      



                      
                            

                                  



                                                           
                     






                                             
                                                               
          
                                                                                    

                                       

                                                    
                                                    
                                        




                                              


                                             



















                                                                                                          
                                      












                                                                                                                                                         



                                                                                             




                                                                                                        















                                                                                          

                                   
                                        

                                                                                   
                                
                                             
                                                 
                                                   

                                                  






                                                                                                                  
                                                                


                                                                                                                               
                                 
                                                             
                                             
                                                  




                                   











                                                                                                     




                                                                                                

                                                   
                                                                                







                                                                                                                                          

                              
                                      
                                                         
                                                  

                                       
                                                  


                                                 
                 
                                                                       
                                         







                                                                                                                                
                                                              


                                                                      
                                                                                   
                         

                                                                     





                                                                                                 
                                              
                                      



                                       




































                                                                                       
                                        








                                                                              
                                                                 








                                                                                             


             
<h1>{{lang_dnbd3Management}}</h1>
<p><i>{{lang_dnbd3IntroText}}</i></p>

<style>
	.shd { text-shadow: #fff 1px 1px 2px; border:1px solid #ddd; min-width:100px; }
	.shd:empty { display: none; }
	#speed-graph { width: 100%; height: 100px; margin: 3px; border-radius: 3px; }
</style>

<div class="panel panel-default">
	<div class="panel-heading">
		{{lang_dnbd3Status}}:
		<b>
			{{#enabled}}{{lang_enabled}}{{/enabled}}
			{{^enabled}}{{lang_disabled}} (NFS/CIFS){{/enabled}}
		</b><a href="#" data-toggle="collapse" data-target="#toggle-div">{{lang_changeDnbd3Status}}</a>
	</div>
	<div class="panel-collapse {{^show_enable_warning}}collapse{{/show_enable_warning}}" id="toggle-div">
		<div class="panel-body">
			<form method="post" action="?do=dnbd3">
				<input type="hidden" name="token" value="{{token}}">
				<div class="checkbox">
					<input id="enable-dnbd3" type="checkbox" name="enabled" {{enabled_checked_s}} {{perms.toggle-usage.disabled}}>
					<label for="enable-dnbd3">{{lang_enableDnbd3}}</label>
				</div>
			{{#show_enable_warning}}
				<div class="text-warning">
					{{lang_enableDnbd3Hint}}
				</div>
			{{/show_enable_warning}}
				<div class="checkbox">
					<input id="allow-nfs" type="checkbox" name="with-nfs" {{nfs_checked_s}} {{perms.toggle-usage.disabled}}>
					<label for="allow-nfs">{{lang_allowNfsFallback}}</label>
				</div>
				<div class="checkbox">
					<input id="prefer-local" type="checkbox" name="prefer-local" {{local_checked_s}} {{perms.toggle-usage.disabled}}>
					<label for="prefer-local">{{lang_preferSatDnbd3}}</label>
				</div>
				<button type="submit" name="action" value="toggle-usage" class="btn btn-success" {{perms.toggle-usage.disabled}}>
					<span class="glyphicon glyphicon-floppy-disk"></span>
					{{lang_save}}
				</button>
			</form>
		</div>
	</div>
</div>

<form method="post" onsubmit="$('#refbtn').prop('disabled', true).find('span').addClass('slx-rotation')" action="?do=dnbd3">
	<input type="hidden" name="token" value="{{token}}">
	<input type="hidden" name="action" value="refresh">
	<h2>
		{{lang_serverList}}
		<button id="refbtn" type="submit" class="btn btn-default" {{perms.refresh.disabled}} title="{{lang_manualRefreshInfo}}">
			<span class="glyphicon glyphicon-refresh"></span>
			{{lang_manualRefresh}}
		</button>
	</h2>
</form>

<form method="post" action="?do=dnbd3">
	<input type="hidden" name="token" value="{{token}}">
	<input type="hidden" name="action" value="delserver">
	<table class="table">
		<thead>
			<tr>
				<th></th>
				<th>{{lang_proxyServerTHead}}</th>
				<th class="text-right">{{lang_storageSize}}</th>
				<th class="text-right">{{lang_clientCount}}</th>
				<th style="min-width:116px">{{lang_uploadSpeed}}</th>
				<th class="text-right">{{lang_lastSeen}}</th>
				<th class="text-right">{{lang_uptime}}</th>
				<th class="text-right">{{lang_txTotal}}</th>
				<th class="text-right">{{lang_rxTotal}}</th>
				<th class="text-right">{{lang_locations}}</th>
				<th></th>
			</tr>
		</thead>

		<tbody>
			{{#list}}
				<tr>
					<td class="text-right text-nowrap">
						{{#slxOk}}
							<span class="glyphicon glyphicon-ok text-success"></span>
						{{/slxOk}}
						{{#slxDown}}
							<span class="glyphicon glyphicon-off"></span>
						{{/slxDown}}
						{{#uptime}}
							<span class="glyphicon glyphicon-ok text-success"></span>
						{{/uptime}}
						{{^uptime}}
							<span class="glyphicon glyphicon-remove text-danger"></span>
						{{/uptime}}
					</td>
					<td class="{{#self}}slx-bold{{/self}}">
						{{#machineuuid}}
							<a class="pull-right btn btn-default btn-xs" href="?do=statistics&uuid={{machineuuid}}">
								<span class="glyphicon glyphicon-eye-open"></span>
							</a>
						{{/machineuuid}}
						{{^perms.view.details.disabled}}
						<a href="?do=dnbd3&amp;show=proxy&amp;server={{serverid}}">
						{{/perms.view.details.disabled}}
							{{fixedip}}
							<span class="small">{{clientip}}</span>
						{{^perms.view.details.disabled}}
						</a>
						{{/perms.view.details.disabled}}
						<div class="small">{{hostname}}</div>
					</td>
					<td data-sort="int" data-sort-default="desc" data-sort-value="{{disktotal}}">
						<div style="background:linear-gradient(to right, #f85 {{diskUsePercent}}%, transparent {{diskUsePercent}}%)"
							  class="text-center text-nowrap shd"
							  title="{{lang_diskFree}}: {{diskfree_s}}">
							{{disktotal_s}}
						</div>
						{{#errormsg}}
						<div class="small text-nowrap text-danger" style="margin-right:-500px">
							{{errormsg}}
						</div>
						{{/errormsg}}
					</td>
					<td data-sort="int" data-sort-default="desc" class="text-right text-nowrap" id="clientcount-{{serverid}}">
						{{clientcount}}
					</td>
					<td data-sort="int" data-sort-default="desc" class="text-right text-nowrap">
						<div id="upspeed-{{serverid}}" class="text-center text-nowrap shd"></div>
					</td>
					<td data-sort="int" data-sort-default="desc" data-sort-value="{{dnbd3lastseen}}" class="text-right text-nowrap">
						{{dnbd3lastseen_s}}
					</td>
					<td data-sort="int" data-sort-default="desc" data-sort-value="{{uptime}}" class="text-right text-nowrap">
						{{uptime_s}}
					</td>
					<td data-sort="int" data-sort-default="desc" data-sort-value="{{totalup}}" class="text-right text-nowrap">
						{{totalup_s}}
					</td>
					<td data-sort="int" data-sort-default="desc" data-sort-value="{{totaldown}}" class="text-right text-nowrap">
						{{totaldown_s}}
					</td>
					<td class="text-right text-nowrap">
						{{^self}}
							{{^locations}}
								<i>{{lang_global}}</i>
							{{/locations}}
							{{#locations}}
								{{locations}}
							{{/locations}}
							<a href="?do=dnbd3&amp;show=locations&amp;server={{serverid}}" class="btn btn-default btn-xs {{edit_disabled}}">
								<span class="glyphicon glyphicon-map-marker"></span>
							</a>
						{{/self}}
					</td>
					<td class="text-right text-nowrap">
						{{#machineuuid}}
							{{#rebootcontrol}}
								<button class="btn btn-warning btn-xs reboot-btn" type="button" data-id="{{serverid}}"
										  data-toggle="modal" data-target="#server-reboot-modal" title="{{lang_reboot}}"
											{{edit_disabled}}>
									<span class="glyphicon glyphicon-repeat"></span>
								</button>
							{{/rebootcontrol}}
							<button class="btn btn-default btn-xs edit-btn" type="button" data-id="{{serverid}}"
									  data-toggle="modal" data-target="#server-edit-modal" title="{{lang_settings}}"
										{{edit_disabled}}>
								<span class="glyphicon glyphicon-cog"></span>
							</button>
						{{/machineuuid}}
						{{^self}}
							<button type="submit" class="btn btn-danger btn-xs" name="server" value="{{serverid}}" {{edit_disabled}}
									  data-confirm="#confirm-delete" data-title="{{fixedip}} {{clientip}}" title="{{lang_delete}}">
								<span class="glyphicon glyphicon-trash"></span>
							</button>
						{{/self}}
					</td>
				</tr>
			{{/list}}
		</tbody>
	</table>
</form>
<div class="hidden" id="confirm-delete">{{lang_wantToDelete}}</div>

<div class="btn-toolbar pull-right">
	<div class="btn-group">
		<button type="button" class="btn btn-success" data-toggle="modal" data-target="#add-modal" {{perms.configure.external.disabled}}>
			<span class="glyphicon glyphicon-plus"></span>
			{{lang_externalServerAdd}}
		</button>
		<button type="button" class="btn btn-default" data-toggle="modal" data-target="#help-external">
			<span class="glyphicon glyphicon-question-sign"></span>
		</button>
	</div>
	<div class="btn-group">
		<a class="btn btn-success {{perms.configure.proxy.disabled}}" href="?do=runmode&amp;module=dnbd3&amp;modeid=proxy&amp;redirect=?do=dnbd3">
			<span class="glyphicon glyphicon-plus"></span>
			{{lang_managedServerAdd}}
		</a>
		<button type="button" class="btn btn-default" data-toggle="modal" data-target="#help-automatic">
			<span class="glyphicon glyphicon-question-sign"></span>
		</button>
	</div>
</div>

<div id="help-external" class="modal fade" role="dialog">
	<div class="modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal">&times;</button>
				<h4 class="modal-title"><b>{{lang_externalServer}}</b></h4>
			</div>
			<div class="modal-body">
				{{lang_externalServerHelp}}
			</div>
			<div class="modal-footer">
				<button type="button" class="btn btn-primary pull-right" data-dismiss="modal">
					{{lang_close}}
				</button>
			</div>
		</div>
	</div>
</div>

<div id="help-automatic" class="modal fade" role="dialog">
	<div class="modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal">&times;</button>
				<h4 class="modal-title"><b>{{lang_managedServer}}</b></h4>
			</div>
			<div class="modal-body">
				{{lang_managedServerHelp}}
			</div>
			<div class="modal-footer">
				<button type="button" class="btn btn-primary pull-right" data-dismiss="modal">
					{{lang_close}}
				</button>
			</div>
		</div>
	</div>
</div>

<div id="server-edit-modal" class="fade modal" role="dialog">
	<div class="modal-dialog modal-lg">
		<div class="modal-content">
			<form method="post" action="?do=dnbd3">
				<input type="hidden" name="token" value="{{token}}">
				<input type="hidden" name="action" value="editserver">
				<div class="modal-header">
					<button type="button" class="close" data-dismiss="modal">&times;</button>
					<h4 class="modal-title"><b>{{lang_editProxyHeading}}</b></h4>
				</div>
				<div class="modal-body" id="server-edit-body">
					.
				</div>
				<div class="modal-footer">
					<button type="submit" class="btn btn-primary pull-right">
						<span class="glyphicon glyphicon-floppy-disk"></span>
						{{lang_save}}
					</button>
				</div>
			</form>
		</div>
	</div>
</div>

<div id="server-reboot-modal" class="modal fade" role="dialog">
	<div class="modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal">&times;</button>
				<h4 class="modal-title"><b>{{lang_rebootProxyHeading}}</b></h4>
			</div>
			<div class="modal-body">
				<p>{{lang_rebootProxyText}}</p>
				<p id="reboot-status"></p>
			</div>
			<div class="modal-footer text-right">
				<button type="button" class="btn btn-default" data-dismiss="modal">{{lang_close}}</button>
				<button id="btn-exec-reboot" type="button" class="btn btn-primary">
					<span class="glyphicon glyphicon-repeat"></span>
					{{lang_reboot}}
				</button>
			</div>
		</div>
	</div>
</div>

<div id="add-modal" class="modal fade" role="dialog">
	<div class="modal-dialog">
		<div class="modal-content">
			<div class="modal-header">
				<button type="button" class="close" data-dismiss="modal">&times;</button>
				<h4 class="modal-title"><b>{{lang_addServer}}</b></h4>
			</div>
			<form id="addform" method="post" action="?do=dnbd3">
				<div class="modal-body">
					<p>{{lang_enterIpOfServer}}</p>

					<input type="hidden" name="token" value="{{token}}">
					<input type="text" class="form-control" name="newip" id="newip">
					<div id="addtest" class="text-danger"></div>
				</div>
				<div class="modal-footer">
					<div class="btn-toolbar pull-right">
						<button id="testbtn" type="submit" class="btn btn-warning" name="action" value="addserver">
							<span class="glyphicon glyphicon-question-sign"></span>
							{{lang_test}}
						</button>
						<button id="savebtn" type="submit" class="btn btn-primary" name="action" value="addserver" disabled>
							<span class="glyphicon glyphicon-floppy-disk"></span>
							{{lang_save}}
						</button>
					</div>
				</div>
			</form>
		</div>
	</div>
</div>

<div class="clearfix"></div>
<div class="slx-space"></div>
<canvas id="speed-graph"></canvas>

<script type="application/javascript"><!--
document.addEventListener('DOMContentLoaded', function () {
	var slxWorking = false;
	var testedIp;
	const $form = $('#addform');
	const $inputs = $form.find(':input');
	const $result =$('#addtest');
	const $ip = $('#newip');
	const $save = $('#savebtn');

	const changeFunc = function() {
		$save.prop('disabled', $ip.val() !== testedIp);
	};
	$ip.change(changeFunc).keypress(function () { setTimeout(changeFunc, 1); });

	$form.submit(function (event) {
		console.log('pre-sub');
		console.log($save.prop('disabled'));
		if (!$save.prop('disabled')) return;
		console.log('post-sub');
		event.preventDefault();
		runTest();
	});

	$('#testbtn').click(function (event) {
		console.log('pre-focus');
		if ($ip.is(':focus')) return;
		console.log('post-focus');
		event.preventDefault();
		runTest();
	});

	function runTest() {
		if (slxWorking === false) {
			var ip = $ip.val();
			var form = $('#addform');
			slxWorking = Math.random();
			var workCopy = slxWorking;
			$inputs.prop('disabled', true);
			$result.empty().removeClass('text-danger').text('...working...');
			var resetFunc = function(ok) {
				if (slxWorking === workCopy) {
					slxWorking = false;
					$inputs.prop('disabled', false);
					if (!ok) $result.empty().addClass('text-danger').text('Timeout.');
				}
			};
			setTimeout(resetFunc, 3000);
			testedIp = ip;
			$.post('?do=dnbd3', {action:'servertest', ip:ip, token:TOKEN}, function (data) {
				if (workCopy !== slxWorking) return;
				resetFunc(true);
				if (!data || data.fatal) {
					$save.prop('disabled', true);
				}
				if (data && data.error) {
					$result.empty().addClass('text-danger').text(data.error);
				} else {
					$result.empty().removeClass('text-danger').text('OK, Uptime: ' + data.uptime + ', Clients: ' + data.clientCount);
				}
			}, 'json').fail(function(oh, what) {
				resetFunc(true);
				$result.empty().addClass('text-danger').text('Fail ' + what);
			});
		}
	}

	$('.edit-btn').click(function() {
		var id = $(this).data('id');
		$('#server-edit-body').text('loading').load('?do=dnbd3&action=editserver&server=' + id);
	});

	var rebootServerId = 0;
	$('.reboot-btn').click(function() {
		rebootServerId = $(this).data('id');
		$('#btn-exec-reboot').prop('disabled', false);
		$('#reboot-status').empty();
	});
	$('#btn-exec-reboot').click(function() {
		$(this).prop('disabled', true);
		var $t = $('#reboot-status');
		if (rebootServerId === 0) {
			$t.text('No ID!?');
			return;
		}
		$t.html('<span class="glyphicon glyphicon-refresh slx-rotation"></span>');
		var sid = rebootServerId;
		var taskId = false;
		var lastText;
		var query = function() {
			data = {"token": TOKEN, "action": "reboot", "server": sid};
			if (taskId !== false) data['taskid'] = taskId;
			$.ajax({
				"data": data,
				"method": "POST",
				"dataType": "json",
				"url": "?do=dnbd3"
			}).done(function (data) {
				if (!data || !data.taskId) return;
				if (taskId === false) taskId = data.taskId;
				if (data.error) data.rebootStatus += ' (' + data.error + ')';
				if (data.rebootStatus !== lastText) {
					$t.empty().text(data.rebootStatus);
				}
				if (data.taskStatus === 'TASK_PROCESSING' || data.taskStatus === 'TASK_WAITING') {
					setTimeout(query, 5000);
					if (data.rebootStatus !== lastText) {
						$t.append($('<span class="glyphicon glyphicon-refresh slx-rotation"></span>'));
					}
				}
				lastText = data.rebootStatus;
			}).fail(function () {
				$t.text('Failed');
			});
		};
		query();
		rebootServerId = 0;
	});
	// live speed
	var hiddenProp;
	if (typeof document.hidden !== "undefined") { // Opera 12.10 and Firefox 18 and later support
		hiddenProp = "hidden";
	} else if (typeof document.msHidden !== "undefined") {
		hiddenProp = "msHidden";
	} else if (typeof document.webkitHidden !== "undefined") {
		hiddenProp = "webkitHidden";
	} else {
		hiddenProp = null;
	}
	var formatBytes = function(bytes) {
		if (bytes < 1024) return bytes.toFixed(0) + '\u2009B';
		if (bytes < 1048576) return (bytes / 1024).toFixed(0) + '\u2009KiB';
		if (bytes < 1073741824) return (bytes / 1048576).toFixed(1) + '\u2009MiB';
		if (bytes < 1099511627776) return (bytes / 1073741824).toFixed(2) + '\u2009GiB';
		return (bytes / 1099511627776).toFixed(2) + '\u2009TiB';
	};
	var calcBackgroundStyle = function(speed) {
		const colors = ['#eee', '#cfc', '#6f6', '#bc3', '#f00', '#f88'];
		const limits = [1048576, 10485760, 104857600, 1073741824, 10737418240];
		for (var i = 0; i < 4; ++i) {
			if (speed < limits[i]) break;
		}
		const percent = Math.round(Math.max(0, Math.min(100, speed / limits[i] * 100)));
		return { background: 'linear-gradient(90deg, ' + colors[i+1] + ' ' + percent + '%, ' + colors[i] + ' ' + percent + '%)' };
	};
	var lastSpeedList = {};
	var history = [];
	var inactiveCount = 0;
	var updateSpeed = function() {
		if (hiddenProp && document[hiddenProp]) {
			if (++inactiveCount > 300)
				return;
		} else {
			if (inactiveCount > 300) {
				history.push(-1);
			}
			inactiveCount = 0;
		}
		$.ajax('?do=dnbd3&action=stats').done(function(elist) {
			var speedSum = 0;
			for (var k in elist) {
				var e = elist[k];
				if (lastSpeedList[k]) {
					var lastSpeed = lastSpeedList[k];
					if (lastSpeed['ts'] < e['ts']) {
						var $speed = $('#upspeed-' + k);
						var s = (e['bytesSent'] - lastSpeed['bytesSent']) / (e['ts'] - lastSpeed['ts']);
						$speed.text(formatBytes(s) + "/s").css(calcBackgroundStyle(s));
						speedSum += s;
					}
				}
				var $clients = $('#clientcount-' + k);
				$clients.text(e['clientCount'] + e['serverCount']);
			}
			history.push(speedSum);
			while (history.length > 500) history.shift();
			for (k in lastSpeedList) {
				if (!elist[k]) {
					$('#upspeed-' + k).text('???').css('background', '#aaa');
					$('#clientcount-' + k).text('-');
				}
			}
			lastSpeedList = elist;
			updateGraph();
		});
	};
	updateSpeed();
	setInterval(updateSpeed, 2500);
	var graph = document.getElementById('speed-graph');
	var updateGraph = function() {
		var i;
		var gctx = graph.getContext('2d');
		graph.width = Math.floor(graph.clientWidth / graph.clientHeight * 100);
		graph.height = 100;
		gctx.fillStyle = '#eee';
		gctx.fillRect(0, 0, graph.width, graph.height);
		var part = history.slice(-Math.floor(graph.width / 10));
		var max = 1;
		var peakIdx = -1;
		var peakCount = 0;
		var peakList = {};
		for (i = 0; i < part.length; ++i) {
			if (part[i] > max) max = part[i];
		}
		for (i = 0; i < part.length; ++i) {
			if (peakIdx === -1 || part[i] > part[peakIdx]) {
				peakIdx = i;
				peakCount = 0;
			} else if ((part[peakIdx] - part[i]) / max > 0.1) {
				if (peakCount > 3) {
					peakList[part.length - peakIdx - 1] = 1;
					peakIdx = -1;
				} else {
					peakCount++;
				}
			} else {
				peakIdx = i;
			}
		}
		if (peakCount > 1) {
			peakList[part.length - peakIdx - 1] = 1;
		}
		const BAR_COLOR = '#999';
		part.reverse();
		gctx.fillStyle = BAR_COLOR;
		gctx.font = "9pt Arial";
		gctx.textBaseline = 'top';
		for (i = 0; i < part.length; ++i) {
			var x = graph.width - i*10;
			if (part[i] === -1) {
				gctx.fillStyle = '#bbb';
				gctx.fillRect(x - 5, 0, 1, 100);
				gctx.fillStyle = BAR_COLOR;
			} else {
				var v = Math.round((1 - part[i] / max) * 100);
				gctx.fillRect(x - 10, v, 9, 100);
				if (peakList[i]) {
					gctx.fillStyle = '#333';
					gctx.fillText(formatBytes(part[i]) + "/s", x + 1, v);
					gctx.fillStyle = BAR_COLOR;
				}
			}
		}
		gctx.stroke();
	};
});

//--></script>