mirror of
https://github.com/unraid/webgui.git
synced 2026-03-10 04:49:14 -05:00
@@ -5,9 +5,9 @@ Icon="icon-ups"
|
||||
Tag="battery-3"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015, Dan Landon.
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -107,7 +107,7 @@ UPS type:
|
||||
> + **ModBus** - serial device for use with newest SmartUPS models supporting the MODBUS protocol
|
||||
|
||||
Device:
|
||||
: <input type="text" name="DEVICE" maxlength="200" value="<?=htmlspecialchars($cfg['DEVICE']);?>">
|
||||
: <input type="text" name="DEVICE" maxlength="200" class="narrow" value="<?=htmlspecialchars($cfg['DEVICE']);?>">
|
||||
|
||||
> Enter the *device* which correspondes to your situation, only applicable when *UPS type* is not set to USB.
|
||||
>
|
||||
|
||||
@@ -5,9 +5,9 @@ Cond="is_file('/var/run/dockerd.pid')"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2014-2018, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2014-2020, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -41,7 +41,7 @@ table tbody td{line-height:normal}
|
||||
<span class="status" style="margin-top:<?=$width?>px"><span><input type="checkbox" class="advancedview"></span></span>
|
||||
<table id="docker_containers" class="tablesorter shift">
|
||||
<thead><tr><th><a href="#" style="cursor:hand;margin-left:12px;display:inline-block;width:32px" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-th-list"></i></a>Application</th><th>Version</th><th>Network</th><th>Port Mappings <small>(App to Host)</small></th><th>Volume Mappings <small>(App to Host)</small></th><th class="load advanced">CPU & Memory load</th><th class="nine">Autostart</th><th class="five">Log</th></tr></thead>
|
||||
<tbody id="docker_list"><tr><td class="advanced"></td><td colspan='7'><div class="spinner"></div></td><td class="advanced"></td></tr></tbody>
|
||||
<tbody id="docker_list"><tr><td colspan='9'></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" onclick="addContainer()" value="Add Container" style="display:none">
|
||||
<input type="button" onclick="startAll()" value="Start All" style="display:none">
|
||||
@@ -99,9 +99,10 @@ var sortableHelper = function(e,i){
|
||||
return i;
|
||||
};
|
||||
function loadlist() {
|
||||
timers.docker = setTimeout(function(){$('div.spinner.fixed').show('slow');},150);
|
||||
$.get('/plugins/dynamix.docker.manager/include/DockerContainers.php',function(d) {
|
||||
clearTimeout(timers.docker);
|
||||
var data = d.split(/\0/);
|
||||
$('div.spinner').hide('slow').remove();
|
||||
$('#docker_list').html(data[0]).sortable({helper:sortableHelper,items:'tr.sortable',cursor:'move',axis:'y',containment:'parent',cancel:'span.docker_readmore,input',delay:100,opacity:0.5,zIndex:9999,
|
||||
update:function(e,ui){
|
||||
var row = $('#docker_list').find('tr:first');
|
||||
@@ -131,11 +132,16 @@ function loadlist() {
|
||||
if ($.cookie('docker_listview_mode')=='advanced') {$('.advanced').show(); $('.basic').hide();}
|
||||
context.init({preventDoubleContext:false,left:true,above:false});
|
||||
$('input[type=button]').prop('disabled',false).show('slow');
|
||||
var update = false;
|
||||
for (var i=0,ct; ct=docker[i]; i++) if (ct.update=='false') {update = true; break;};
|
||||
if (!update) $('input#updateAll').prop('disabled',true);
|
||||
var update = false, rebuild = false;
|
||||
for (var i=0,ct; ct=docker[i]; i++) {
|
||||
if (ct.update==1) update = true;
|
||||
if (ct.update==2) rebuild = true;
|
||||
}
|
||||
listview();
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
if (data[2]==1) {$('#busy').show(); setTimeout(loadlist,5000);} else if ($('#busy').is(':visible')) {$('#busy').hide(); setTimeout(loadlist,3000);}
|
||||
if (!update) $('input#updateAll').prop('disabled',true);
|
||||
if (rebuild) rebuildAll();
|
||||
});
|
||||
}
|
||||
function sizes() {
|
||||
|
||||
@@ -177,6 +177,8 @@ Docker vDisk location:
|
||||
|
||||
> You must specify an image file for Docker. The system will automatically create this file when the Docker service is first started.
|
||||
>
|
||||
> The image file name must have the extension .img, e.g. If not the input is not accepted and marked red.
|
||||
>
|
||||
> It is recommended to create this image file outside the array, e.g. on the Cache pool. For best performance SSD devices are preferred.
|
||||
|
||||
Default appdata storage location:
|
||||
@@ -189,6 +191,8 @@ Default appdata storage location:
|
||||
|
||||
> You can specify a folder to automatically generate and store subfolders containing configuration files for each Docker app (via the /config mapped volume).
|
||||
>
|
||||
> The folder's path must end with a trailing slash (/) character. If not the input is not accepted and marked red.
|
||||
>
|
||||
> It is recommended to create this folder outside the array, e.g. on the Cache pool. For best performance SSD devices are preferred.
|
||||
>
|
||||
> Only used when adding new Docker apps. Editing existing Docker apps will not be affected by this setting.
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -28,7 +28,7 @@ require_once "$docroot/webGui/include/Helpers.php";
|
||||
</head>
|
||||
<style>
|
||||
div.button{width:100%;text-align:center;display:none}
|
||||
div.spinner{margin:0 auto;text-align:center}
|
||||
div.spinner{position:fixed;top:50%;left:50%;margin-top:-32px;margin-left:-64px}
|
||||
div.spinner .unraid_mark{height:64px}
|
||||
div.spinner .unraid_mark_2,div .unraid_mark_4{animation:mark_2 1.5s ease infinite}
|
||||
div.spinner .unraid_mark_3{animation:mark_3 1.5s ease infinite}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2019, Lime Technology
|
||||
* Copyright 2015-2019, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2019, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -15,7 +15,6 @@
|
||||
$docroot = $docroot ?? $_SERVER['DOCUMENT_ROOT'] ?: '/usr/local/emhttp';
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/DockerClient.php";
|
||||
require_once "$docroot/plugins/dynamix.docker.manager/include/Helpers.php";
|
||||
require_once "$docroot/webGui/include/Helpers.php";
|
||||
|
||||
libxml_use_internal_errors(false); # Enable xml errors
|
||||
|
||||
@@ -35,7 +34,7 @@ $DockerTemplates = new DockerTemplates();
|
||||
|
||||
$custom = DockerUtil::custom();
|
||||
$subnet = DockerUtil::network($custom);
|
||||
$cpus = cpu_list();
|
||||
$cpus = DockerUtil::cpus();
|
||||
|
||||
function cpu_pinning() {
|
||||
global $xml,$cpus;
|
||||
@@ -84,10 +83,10 @@ if (isset($_POST['contName'])) {
|
||||
if (!is_dir($userTmplDir)) mkdir($userTmplDir, 0777, true);
|
||||
if ($Name) {
|
||||
$filename = sprintf('%s/my-%s.xml', $userTmplDir, $Name);
|
||||
if ( is_file($filename) ) {
|
||||
if (is_file($filename)) {
|
||||
$oldXML = simplexml_load_file($filename);
|
||||
if ($oldXML->Icon != $_POST['contIcon']) {
|
||||
if (! strpos($Repository,":")) {
|
||||
if (!strpos($Repository,":")) {
|
||||
$Repository .= ":latest";
|
||||
}
|
||||
$iconPath = $DockerTemplates->getIcon($Repository);
|
||||
@@ -157,11 +156,14 @@ if (isset($_POST['contName'])) {
|
||||
##########################
|
||||
|
||||
if ($_GET['updateContainer']){
|
||||
readfile("$docroot/plugins/dynamix.docker.manager/log.htm");
|
||||
@flush();
|
||||
$echo = $_GET['mute'] ? false : true;
|
||||
if ($echo) {
|
||||
readfile("$docroot/plugins/dynamix.docker.manager/log.htm");
|
||||
@flush();
|
||||
}
|
||||
foreach ($_GET['ct'] as $value) {
|
||||
$tmpl = $DockerTemplates->getUserTemplate(urldecode($value));
|
||||
if (!$tmpl) {
|
||||
if ($echo && !$tmpl) {
|
||||
echo "<script>addLog('<p>Configuration not found. Was this container created using this plugin?</p>');</script>";
|
||||
@flush();
|
||||
continue;
|
||||
@@ -170,27 +172,23 @@ if ($_GET['updateContainer']){
|
||||
list($cmd, $Name, $Repository) = xmlToCommand($tmpl);
|
||||
$Registry = getXmlVal($xml, "Registry");
|
||||
$oldImageID = $DockerClient->getImageID($Repository);
|
||||
// Pull image
|
||||
if (!pullImage($Name, $Repository)) continue;
|
||||
// pull image
|
||||
if ($echo) if (!pullImage($Name, $Repository)) continue;
|
||||
$oldContainerInfo = $DockerClient->getContainerDetails($Name);
|
||||
// determine if the container is still running
|
||||
if (!empty($oldContainerInfo) && !empty($oldContainerInfo['State']) && !empty($oldContainerInfo['State']['Running'])) {
|
||||
// since container was already running, put it back it to a running state after update
|
||||
$cmd = str_replace('/plugins/dynamix.docker.manager/scripts/docker create ', '/plugins/dynamix.docker.manager/scripts/docker run -d ', $cmd);
|
||||
$cmd = str_replace('/docker create ', '/docker run -d ', $cmd);
|
||||
// attempt graceful stop of container first
|
||||
stopContainer($Name);
|
||||
stopContainer($Name, $echo);
|
||||
}
|
||||
// force kill container if still running after 10 seconds
|
||||
if ( ! $_GET['communityApplications'] ) {
|
||||
removeContainer($Name);
|
||||
}
|
||||
execCommand($cmd);
|
||||
if (!$_GET['communityApplications']) removeContainer($Name, $echo);
|
||||
execCommand($cmd, $echo);
|
||||
$DockerClient->flushCaches();
|
||||
$newImageID = $DockerClient->getImageID($Repository);
|
||||
if ($oldImageID && $oldImageID != $newImageID) {
|
||||
// remove old orphan image since it's no longer used by this container
|
||||
removeImage($oldImageID);
|
||||
}
|
||||
// remove old orphan image since it's no longer used by this container
|
||||
if ($oldImageID && $oldImageID != $newImageID) removeImage($oldImageID, $echo);
|
||||
}
|
||||
echo '<div style="text-align:center"><button type="button" onclick="window.parent.jQuery(\'#iframe-popup\').dialog(\'close\')">Done</button></div><br>';
|
||||
goto END;
|
||||
@@ -310,7 +308,7 @@ button[type=button]{margin:0 20px 0 0}
|
||||
for (var x=1; x<=last; x++) if(x != this_tab) $('#tab'+x).bind({click:function(){$('#'+elementId).hide();}});
|
||||
<?endif;?>
|
||||
$('.advanced-switch').switchButton({labels_placement: "left", on_label: 'Advanced View', off_label: 'Basic View'});
|
||||
$('.advanced-switch').change(function () {
|
||||
$('.advanced-switch').change(function() {
|
||||
var status = $(this).is(':checked');
|
||||
toggleRows('advanced', status, 'basic');
|
||||
load_contOverview();
|
||||
@@ -382,11 +380,11 @@ button[type=button]{margin:0 20px 0 0}
|
||||
}
|
||||
return newConfig.prop('outerHTML');
|
||||
}
|
||||
|
||||
|
||||
function escapeQuote(string) {
|
||||
return string.replace(new RegExp('"','g'),""");
|
||||
}
|
||||
|
||||
|
||||
function makeAllocations(container,current) {
|
||||
var html = [];
|
||||
for (var i=0,ct; ct=container[i]; i++) {
|
||||
@@ -399,7 +397,7 @@ button[type=button]{margin:0 20px 0 0}
|
||||
function getVal(el, name) {
|
||||
var el = $(el).find("*[name="+name+"]");
|
||||
if (el.length) {
|
||||
return ( $(el).attr('type') == 'checkbox' ) ? ($(el).is(':checked') ? "on" : "off") : $(el).val();
|
||||
return ($(el).attr('type') == 'checkbox') ? ($(el).is(':checked') ? "on" : "off") : $(el).val();
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
@@ -407,7 +405,7 @@ button[type=button]{margin:0 20px 0 0}
|
||||
|
||||
function addConfigPopup() {
|
||||
var title = 'Add Configuration';
|
||||
var popup = $( "#dialogAddConfig" );
|
||||
var popup = $("#dialogAddConfig");
|
||||
|
||||
// Load popup the popup with the template info
|
||||
popup.html($("#templatePopupConfig").html());
|
||||
@@ -436,10 +434,10 @@ button[type=button]{margin:0 20px 0 0}
|
||||
["Name","Target","Default","Mode","Description","Type","Display","Required","Mask","Value"].forEach(function(e){
|
||||
Opts[e] = getVal(Element, e);
|
||||
});
|
||||
if (! Opts.Name ){
|
||||
if (!Opts.Name){
|
||||
Opts.Name = makeName(Opts.Type);
|
||||
}
|
||||
if (! Opts.Description ) {
|
||||
if (!Opts.Description) {
|
||||
Opts.Description = "Container "+Opts.Type+": "+Opts.Target;
|
||||
}
|
||||
if (Opts.Required == "true") {
|
||||
@@ -461,7 +459,7 @@ button[type=button]{margin:0 20px 0 0}
|
||||
}
|
||||
});
|
||||
$(".ui-dialog .ui-dialog-titlebar").addClass('menu');
|
||||
$(".ui-dialog .ui-dialog-title").css('text-align','center').css( 'width', "100%");
|
||||
$(".ui-dialog .ui-dialog-title").css('text-align','center').css('width', "100%");
|
||||
$(".ui-dialog .ui-dialog-content").css('padding-top','15px').css('vertical-align','bottom');
|
||||
$(".ui-button-text").css('padding','0px 5px');
|
||||
}
|
||||
@@ -517,10 +515,10 @@ button[type=button]{margin:0 20px 0 0}
|
||||
Opts.Buttons = "<button type='button' onclick='editConfigPopup("+num+",<?=$disableEdit?>)'>Edit</button>";
|
||||
Opts.Buttons += "<button type='button' onclick='removeConfig("+num+")'>Remove</button>";
|
||||
}
|
||||
if (! Opts.Name ){
|
||||
if (!Opts.Name){
|
||||
Opts.Name = makeName(Opts.Type);
|
||||
}
|
||||
if (! Opts.Description ) {
|
||||
if (!Opts.Description) {
|
||||
Opts.Description = "Container "+Opts.Type+": "+Opts.Target;
|
||||
}
|
||||
Opts.Number = num;
|
||||
@@ -545,7 +543,7 @@ button[type=button]{margin:0 20px 0 0}
|
||||
}
|
||||
});
|
||||
$(".ui-dialog .ui-dialog-titlebar").addClass('menu');
|
||||
$(".ui-dialog .ui-dialog-title").css('text-align','center').css( 'width', "100%");
|
||||
$(".ui-dialog .ui-dialog-title").css('text-align','center').css('width', "100%");
|
||||
$(".ui-dialog .ui-dialog-content").css('padding-top','15px').css('vertical-align','bottom');
|
||||
$(".ui-button-text").css('padding','0px 5px');
|
||||
$('.desc_readmore').readmore({maxHeight:10});
|
||||
@@ -557,20 +555,19 @@ button[type=button]{margin:0 20px 0 0}
|
||||
}
|
||||
|
||||
function prepareConfig(form) {
|
||||
var types = [], values = [], targets = [];
|
||||
var types = [], values = [], targets = [], vcpu = [];
|
||||
if ($('select[name="contNetwork"]').val()=='host') {
|
||||
$(form).find('input[name="confType[]"]').each(function(){types.push($(this).val());});
|
||||
$(form).find('input[name="confValue[]"]').each(function(){values.push($(this));});
|
||||
$(form).find('input[name="confTarget[]"]').each(function(){targets.push($(this));});
|
||||
for (var i=0; i < types.length; i++) if (types[i]=='Port') $(targets[i]).val($(values[i]).val());
|
||||
}
|
||||
var vcpu = [];
|
||||
$(form).find('input[id^="box"]').each(function(){if ($(this).prop('checked')) vcpu.push($('#'+$(this).prop('id').replace('box','cpu')).text());});
|
||||
form.contCPUset.value = vcpu.join(',');
|
||||
}
|
||||
|
||||
function makeName(type) {
|
||||
i = $("#configLocation input[name^='confType'][value='"+type+"']").length+1;
|
||||
var i = $("#configLocation input[name^='confType'][value='"+type+"']").length+1;
|
||||
return "Host "+type.replace('Variable','Key')+" "+i;
|
||||
}
|
||||
|
||||
@@ -668,14 +665,13 @@ button[type=button]{margin:0 20px 0 0}
|
||||
allowBrowsing: true
|
||||
},
|
||||
function(file){if(on_files){p.val(file);p.trigger('change');if(close_on_select){ft.slideUp('fast',function(){ft.remove();});}}},
|
||||
function(folder){if(on_folders){p.val(folder);p.trigger('change');if(close_on_select){$(ft).slideUp('fast',function (){$(ft).remove();});}}}
|
||||
);
|
||||
function(folder){if(on_folders){p.val(folder);p.trigger('change');if(close_on_select){$(ft).slideUp('fast',function(){$(ft).remove();});}}});
|
||||
// Format fileTree according to parent position, height and width
|
||||
ft.css({'left':p.position().left,'top':(p.position().top+p.outerHeight()),'width':(p.width())});
|
||||
// close if click elsewhere
|
||||
$(document).mouseup(function(e){if(!ft.is(e.target) && ft.has(e.target).length === 0){ft.slideUp('fast',function (){$(ft).remove();});}});
|
||||
$(document).mouseup(function(e){if(!ft.is(e.target) && ft.has(e.target).length === 0){ft.slideUp('fast',function(){$(ft).remove();});}});
|
||||
// close if parent changed
|
||||
p.bind("keydown", function(){ft.slideUp('fast', function (){$(ft).remove();});});
|
||||
p.bind("keydown", function(){ft.slideUp('fast', function(){$(ft).remove();});});
|
||||
// Open fileTree
|
||||
ft.slideDown('fast');
|
||||
}
|
||||
@@ -1182,7 +1178,7 @@ button[type=button]{margin:0 20px 0 0}
|
||||
}
|
||||
function toggleReadmore() {
|
||||
var readm = $('#readmore_toggle');
|
||||
if ( readm.hasClass('readmore_collapsed') ) {
|
||||
if (readm.hasClass('readmore_collapsed')) {
|
||||
readm.removeClass('readmore_collapsed').addClass('readmore_expanded');
|
||||
$('#configLocationAdvanced').slideDown('fast');
|
||||
readm.find('a').html('<i class="fa fa-chevron-up"></i> Hide more settings ...');
|
||||
@@ -1194,7 +1190,7 @@ button[type=button]{margin:0 20px 0 0}
|
||||
}
|
||||
function toggleAllocations() {
|
||||
var readm = $('#allocations_toggle');
|
||||
if ( readm.hasClass('readmore_collapsed') ) {
|
||||
if (readm.hasClass('readmore_collapsed')) {
|
||||
readm.removeClass('readmore_collapsed').addClass('readmore_expanded');
|
||||
$('#dockerAllocations').slideDown('fast');
|
||||
readm.find('a').html('<i class="fa fa-chevron-up"></i> Hide docker allocations ...');
|
||||
@@ -1273,7 +1269,7 @@ button[type=button]{margin:0 20px 0 0}
|
||||
echo "$('.advanced-switch').siblings('.switch-button-background').click();";
|
||||
}?>
|
||||
});
|
||||
if ( window.location.href.indexOf("/Apps/") > 0 ) {
|
||||
if (window.location.href.indexOf("/Apps/") > 0) {
|
||||
$(".TemplateDropDown").hide();
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2019, Lime Technology
|
||||
* Copyright 2014-2019, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2019, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2014-2020, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -68,9 +68,20 @@ class DockerTemplates {
|
||||
return false;
|
||||
}
|
||||
|
||||
public function download_url($url, $path='', $bg=false) {
|
||||
exec('curl --max-time 60 --silent --insecure --location --fail '.($path ? ' -o '.escapeshellarg($path) : '').' '.escapeshellarg($url).' '.($bg ? '>/dev/null 2>&1 &' : '2>/dev/null'), $out, $exit_code);
|
||||
return $exit_code===0 ? implode("\n", $out) : false;
|
||||
public function download_url($url, $path='') {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 45);
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "");
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_REFERER, "");
|
||||
$out = curl_exec($ch) ?: false;
|
||||
curl_close($ch);
|
||||
if ($path && $out) file_put_contents($path,$out); elseif ($path) @unlink($path);
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function listDir($root, $ext=null) {
|
||||
@@ -286,8 +297,7 @@ class DockerTemplates {
|
||||
$tmp['Project'] = $tmp['Project'] ?? $this->getTemplateValue($image, 'Project');
|
||||
if (!$tmp['updated'] || $reload) {
|
||||
if ($reload) $DockerUpdate->reloadUpdateStatus($image);
|
||||
$vs = $DockerUpdate->getUpdateStatus($image);
|
||||
$tmp['updated'] = $vs===null ? 'undef' : ($vs===true ? 'true' : 'false');
|
||||
$tmp['updated'] = var_export($DockerUpdate->getUpdateStatus($image),true);
|
||||
}
|
||||
if (!$tmp['template'] || $reload) $tmp['template'] = $this->getUserTemplate($name);
|
||||
if ($reload) $DockerUpdate->updateUserTemplate($name);
|
||||
@@ -301,6 +311,7 @@ class DockerTemplates {
|
||||
public function getIcon($Repository) {
|
||||
global $docroot, $dockerManPaths;
|
||||
$imgUrl = $this->getTemplateValue($Repository, 'Icon');
|
||||
if (!$imgUrl) return '';
|
||||
preg_match_all("/(.*?):([\S]*$)/i", $Repository, $matches);
|
||||
$name = preg_replace("%\/|\\\%", '-', $matches[1][0]);
|
||||
$version = $matches[2][0];
|
||||
@@ -312,7 +323,7 @@ class DockerTemplates {
|
||||
if (!is_file($icon)) $this->download_url($imgUrl, $icon);
|
||||
@copy($icon, $iconRAM);
|
||||
}
|
||||
if ( !is_file($icon) && is_file($iconRAM) ) {
|
||||
if (!is_file($icon) && is_file($iconRAM)) {
|
||||
@copy($iconRAM,$icon);
|
||||
}
|
||||
return (is_file($iconRAM)) ? str_replace($docroot, '', $iconRAM) : '';
|
||||
@@ -338,18 +349,37 @@ class DockerUpdate{
|
||||
return strval(html_entity_decode($string, ENT_XML1, 'UTF-8'));
|
||||
}
|
||||
|
||||
public function download_url($url, $path='', $bg=false) {
|
||||
exec('curl --max-time 30 --silent --insecure --location --fail '.($path ? ' -o '.escapeshellarg($path) : '').' '.escapeshellarg($url).' '.($bg ? '>/dev/null 2>&1 &' : '2>/dev/null'), $out, $exit_code);
|
||||
return ($exit_code===0) ? implode("\n", $out) : false;
|
||||
public function download_url($url, $path='') {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 45);
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "");
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_REFERER, "");
|
||||
$out = curl_exec($ch) ?: false;
|
||||
curl_close($ch);
|
||||
if ($path && $out) file_put_contents($path,$out); elseif ($path) @unlink($path);
|
||||
return $out;
|
||||
}
|
||||
|
||||
public function download_url_and_headers($url, $headers=[], $path='', $bg=false) {
|
||||
$strHeaders = '';
|
||||
foreach ($headers as $header) {
|
||||
$strHeaders .= ' -H '.escapeshellarg($header);
|
||||
}
|
||||
exec('curl --max-time 30 --silent --insecure --location --fail -i '.$strHeaders.($path ? ' -o '.escapeshellarg($path) : '').' '.escapeshellarg($url).' '.($bg ? '>/dev/null 2>&1 &' : '2>/dev/null'), $out, $exit_code);
|
||||
return ($exit_code===0) ? implode("\n", $out) : false;
|
||||
public function download_url_and_headers($url, $headers=[], $path='') {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 45);
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "");
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_REFERER, "");
|
||||
$out = curl_exec($ch) ?: false;
|
||||
curl_close($ch);
|
||||
if ($path && $out) file_put_contents($path,$out); elseif ($path) @unlink($path);
|
||||
return $out;
|
||||
}
|
||||
|
||||
// DEPRECATED: Only used for Docker Index V1 type update checks
|
||||
@@ -363,88 +393,74 @@ class DockerUpdate{
|
||||
|
||||
public function getRemoteVersionV2($image) {
|
||||
list($strRepo, $strTag) = explode(':', DockerUtil::ensureImageTag($image));
|
||||
|
||||
/*
|
||||
* Step 1: Check whether or not the image is in a private registry, get corresponding auth data and generate manifest url
|
||||
*/
|
||||
$DockerClient = new DockerClient();
|
||||
$registryAuth = $DockerClient->getRegistryAuth( $image );
|
||||
if ( $registryAuth ) {
|
||||
$manifestURL = sprintf( '%s%s/manifests/%s', $registryAuth['apiUrl'], $registryAuth['imageName'], $registryAuth['imageTag'] );
|
||||
$registryAuth = $DockerClient->getRegistryAuth($image);
|
||||
if ($registryAuth) {
|
||||
$manifestURL = sprintf('%s%s/manifests/%s', $registryAuth['apiUrl'], $registryAuth['imageName'], $registryAuth['imageTag']);
|
||||
} else {
|
||||
$manifestURL = sprintf( 'https://registry-1.docker.io/v2/%s/manifests/%s', $strRepo, $strTag );
|
||||
$manifestURL = sprintf('https://registry-1.docker.io/v2/%s/manifests/%s', $strRepo, $strTag);
|
||||
}
|
||||
//$this->debug('Manifest URL: ' . $manifestURL);
|
||||
|
||||
//$this->debug('Manifest URL: '.$manifestURL);
|
||||
/*
|
||||
* Step 2: Get www-authenticate header from manifest url to generate token url
|
||||
*/
|
||||
$ch = getCurlHandle($manifestURL, 'HEAD');
|
||||
$response = curl_exec( $ch );
|
||||
$reply = curl_exec($ch);
|
||||
if (curl_errno($ch) !== 0) {
|
||||
//$this->debug('Error: curl error getting manifest: ' . curl_error($ch));
|
||||
//$this->debug('Error: curl error getting manifest: '.curl_error($ch));
|
||||
return null;
|
||||
}
|
||||
|
||||
preg_match('@www-authenticate:\s*Bearer\s*(.*)@i', $response, $matches);
|
||||
preg_match('@www-authenticate:\s*Bearer\s*(.*)@i', $reply, $matches);
|
||||
if (empty($matches[1])) {
|
||||
//this->debug('Error: Www-Authenticate header is empty or missing');
|
||||
return null;
|
||||
}
|
||||
|
||||
$strArgs = explode(',', $matches[1]);
|
||||
$args = [];
|
||||
foreach ($strArgs as $arg) {
|
||||
$arg = explode('=', $arg);
|
||||
$args[$arg[0]] = trim($arg[1], "\" \r\n");
|
||||
}
|
||||
|
||||
if (empty($args['realm']) || empty($args['service']) || empty($args['scope'])) {
|
||||
return null;
|
||||
}
|
||||
$url = $args['realm'] . '?service=' . urlencode($args['service']) . '&scope=' . urlencode($args['scope']);
|
||||
//$this->debug('Token URL: ' . $url);
|
||||
|
||||
if (empty($args['realm']) || empty($args['service']) || empty($args['scope'])) return null;
|
||||
$url = $args['realm'].'?service='.urlencode($args['service']).'&scope='.urlencode($args['scope']);
|
||||
//$this->debug('Token URL: '.$url);
|
||||
/**
|
||||
* Step 3: Get token from API and authenticate via username / password if in private registry and auth data was found
|
||||
*/
|
||||
$ch = getCurlHandle($url);
|
||||
if ($registryAuth) {
|
||||
curl_setopt( $ch, CURLOPT_USERPWD, $registryAuth['username'] . ':' . $registryAuth['password'] );
|
||||
}
|
||||
$response = curl_exec( $ch );
|
||||
if ($registryAuth) curl_setopt($ch, CURLOPT_USERPWD, $registryAuth['username'].':'.$registryAuth['password']);
|
||||
$reply = curl_exec($ch);
|
||||
if (curl_errno($ch) !== 0) {
|
||||
//$this->debug('Error: curl error getting token: ' . curl_error($ch));
|
||||
//$this->debug('Error: curl error getting token: '.curl_error($ch));
|
||||
return null;
|
||||
}
|
||||
$response = json_decode($response, true);
|
||||
if (!$response || empty($response['token'])) {
|
||||
$reply = json_decode($reply, true);
|
||||
if (!$reply || empty($reply['token'])) {
|
||||
//$this->debug('Error: Token response was empty or missing token');
|
||||
return null;
|
||||
}
|
||||
$token = $response['token'];
|
||||
|
||||
$token = $reply['token'];
|
||||
/**
|
||||
* Step 4: Get Docker-Content-Digest header from manifest file
|
||||
*/
|
||||
$ch = getCurlHandle($manifestURL, 'HEAD');
|
||||
curl_setopt( $ch, CURLOPT_HTTPHEADER, [
|
||||
'Accept: application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.docker.distribution.manifest.v2+json',
|
||||
'Authorization: Bearer ' . $token
|
||||
]);
|
||||
|
||||
$response = curl_exec( $ch );
|
||||
$ch = getCurlHandle($manifestURL, 'HEAD', $header);
|
||||
$header = ['Accept: application/vnd.docker.distribution.manifest.list.v2+json,application/vnd.docker.distribution.manifest.v2+json', 'Authorization: Bearer '.$token];
|
||||
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
|
||||
$reply = curl_exec($ch);
|
||||
if (curl_errno($ch) !== 0) {
|
||||
//$this->debug('Error: curl error getting manifest: ' . curl_error($ch));
|
||||
//$this->debug('Error: curl error getting manifest: '.curl_error($ch));
|
||||
return null;
|
||||
}
|
||||
preg_match('@Docker-Content-Digest:\s*(.*)@', $response, $matches);
|
||||
preg_match('@Docker-Content-Digest:\s*(.*)@', $reply, $matches);
|
||||
if (empty($matches[1])) {
|
||||
//$this->debug('Error: Docker-Content-Digest header is empty or missing');
|
||||
return null;
|
||||
}
|
||||
$digest = trim($matches[1]);
|
||||
//$this->debug('Remote Digest: ' . $digest);
|
||||
//$this->debug('Remote Digest: '.$digest);
|
||||
return $digest;
|
||||
}
|
||||
|
||||
@@ -469,7 +485,7 @@ class DockerUpdate{
|
||||
global $dockerManPaths;
|
||||
$DockerClient = new DockerClient();
|
||||
$updateStatus = DockerUtil::loadJSON($dockerManPaths['update-status']);
|
||||
$images = ($image) ? [DockerUtil::ensureImageTag($image)] : array_map(function($ar){return $ar['Tags'][0];}, $DockerClient->getDockerImages());
|
||||
$images = $image ? [DockerUtil::ensureImageTag($image)] : array_map(function($ar){return $ar['Tags'][0];}, $DockerClient->getDockerImages());
|
||||
foreach ($images as $img) {
|
||||
$localVersion = null;
|
||||
if (!empty($updateStatus[$img]) && array_key_exists('local', $updateStatus[$img])) {
|
||||
@@ -486,19 +502,15 @@ class DockerUpdate{
|
||||
DockerUtil::saveJSON($dockerManPaths['update-status'], $updateStatus);
|
||||
}
|
||||
|
||||
public function inspectLocalVersion( $image ) {
|
||||
public function inspectLocalVersion($image) {
|
||||
$DockerClient = new DockerClient();
|
||||
$inspect = $DockerClient->getDockerJSON( '/images/' . $image . '/json' );
|
||||
if ( empty( $inspect['RepoDigests'] ) ) {
|
||||
return null;
|
||||
}
|
||||
$inspect = $DockerClient->getDockerJSON('/images/'.$image.'/json');
|
||||
if (empty($inspect['RepoDigests'])) return null;
|
||||
|
||||
$shaPos = strpos( $inspect['RepoDigests'][0], '@sha256:' );
|
||||
if ( $shaPos === false ) {
|
||||
return null;
|
||||
}
|
||||
$shaPos = strpos($inspect['RepoDigests'][0], '@sha256:');
|
||||
if ($shaPos === false) return null;
|
||||
|
||||
return substr( $inspect['RepoDigests'][0], $shaPos + 1 );
|
||||
return substr($inspect['RepoDigests'][0], $shaPos + 1);
|
||||
}
|
||||
|
||||
public function setUpdateStatus($image, $version) {
|
||||
@@ -563,7 +575,7 @@ class DockerUpdate{
|
||||
$local_element = $template->xpath("//Config[@Type='$type'][@Target='$target']")[0];
|
||||
}
|
||||
// If the local template already have the pertinent Config element, loop through it's attributes and update those on validAttributes
|
||||
if (! empty($local_element)) {
|
||||
if (!empty($local_element)) {
|
||||
foreach ($remote_element->attributes() as $key => $value) {
|
||||
$rvalue = $this->xml_decode($value);
|
||||
$value = $this->xml_decode($local_element[$key]);
|
||||
@@ -763,13 +775,13 @@ class DockerClient {
|
||||
|
||||
public function pullImage($image, $callback=null) {
|
||||
$header = null;
|
||||
$registryAuth = $this->getRegistryAuth( $image );
|
||||
if ( $registryAuth ) {
|
||||
$header = 'X-Registry-Auth: ' . base64_encode( json_encode( [
|
||||
$registryAuth = $this->getRegistryAuth($image);
|
||||
if ($registryAuth) {
|
||||
$header = 'X-Registry-Auth: '.base64_encode(json_encode([
|
||||
'username' => $registryAuth['username'],
|
||||
'password' => $registryAuth['password'],
|
||||
'serveraddress' => $registryAuth['apiUrl'],
|
||||
] ) ) . "\r\n";
|
||||
]))."\r\n";
|
||||
}
|
||||
|
||||
$ret = $this->getDockerJSON("/images/create?fromImage=".urlencode($image), 'POST', $code, $callback, false, $header);
|
||||
@@ -789,7 +801,7 @@ class DockerClient {
|
||||
return false;
|
||||
}
|
||||
$dockerConfig = json_decode(file_get_contents($dockerConfig), true);
|
||||
if ( empty( $dockerConfig['auths'] ) || empty( $dockerConfig['auths'][ $matches[1] ] ) ) {
|
||||
if (empty($dockerConfig['auths']) || empty($dockerConfig['auths'][ $matches[1] ])) {
|
||||
return false;
|
||||
}
|
||||
list($user, $password) = explode(':', base64_decode($dockerConfig['auths'][ $matches[1] ]['auth']));
|
||||
@@ -800,7 +812,7 @@ class DockerClient {
|
||||
'registryName' => $matches[1],
|
||||
'imageName' => $matches[2],
|
||||
'imageTag' => $matches[3],
|
||||
'apiUrl' => 'https://' . $matches[1] . '/v2/',
|
||||
'apiUrl' => 'https://'.$matches[1].'/v2/',
|
||||
];
|
||||
}
|
||||
|
||||
@@ -841,9 +853,11 @@ class DockerClient {
|
||||
$c['Volumes'] = $info['HostConfig']['Binds'];
|
||||
$c['Created'] = $this->humanTiming($ct['Created']);
|
||||
$c['NetworkMode'] = $ct['HostConfig']['NetworkMode'];
|
||||
[$net, $id] = explode(':',$c['NetworkMode']);
|
||||
$c['CPUset'] = $info['HostConfig']['CpusetCpus'];
|
||||
$c['BaseImage'] = $ct['Labels']['BASEIMAGE'] ?? false;
|
||||
$c['Ports'] = [];
|
||||
if ($id) $c['NetworkMode'] = $net.str_replace('/',':',DockerUtil::ctMap($id)?:'/???');
|
||||
if ($driver[$c['NetworkMode']]=='bridge') {
|
||||
$ports = &$info['HostConfig']['PortBindings'];
|
||||
$nat = true;
|
||||
@@ -949,7 +963,7 @@ class DockerUtil {
|
||||
|
||||
public static function driver() {
|
||||
$list = [];
|
||||
foreach (static::docker("network ls --format='{{.Name}}={{.Driver}}'",true) as $network) {list($name,$driver) = explode('=',$network); $list[$name] = $driver;}
|
||||
foreach (static::docker("network ls --format='{{.Name}}={{.Driver}}'",true) as $network) {list($net,$driver) = explode('=',$network); $list[$net] = $driver;}
|
||||
return $list;
|
||||
}
|
||||
|
||||
@@ -957,10 +971,18 @@ class DockerUtil {
|
||||
return static::docker("network ls --filter driver='bridge' --filter driver='macvlan' --format='{{.Name}}'|grep -v '^bridge$'",true);
|
||||
}
|
||||
|
||||
public static function network($more) {
|
||||
public static function network($custom) {
|
||||
$list = ['bridge'=>'', 'host'=>'', 'none'=>''];
|
||||
foreach ($more as $net) $list[$net] = substr(static::docker("network inspect --format='{{range .IPAM.Config}}{{.Subnet}}, {{end}}' $net"),0,-1);
|
||||
foreach ($custom as $net) $list[$net] = implode(', ',array_filter(static::docker("network inspect --format='{{range .IPAM.Config}}{{println .Subnet}}{{end}}' $net",true)));
|
||||
return $list;
|
||||
}
|
||||
|
||||
public static function cpus() {
|
||||
exec('cat /sys/devices/system/cpu/*/topology/thread_siblings_list|sort -nu', $cpus);
|
||||
return $cpus;
|
||||
}
|
||||
public static function ctMap($ct, $type='Name') {
|
||||
return static::docker("inspect --format='{{.$type}}' $ct");
|
||||
}
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2014-2018, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2014-2020, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -51,7 +51,7 @@ foreach ($containers as $ct) {
|
||||
$running = $info['running'] ? 1 : 0;
|
||||
$paused = $info['paused'] ? 1 : 0;
|
||||
$is_autostart = $info['autostart'] ? 'true':'false';
|
||||
$updateStatus = $info['updated']=='true'||$info['updated']=='undef' ? 'true':'false';
|
||||
$updateStatus = substr($ct['NetworkMode'],-4)==':???' ? 2 : ($info['updated']=='true' ? 0 : ($info['updated']=='false' ? 1 : 3));
|
||||
$template = $info['template'];
|
||||
$shell = $info['shell'];
|
||||
$webGui = html_entity_decode($info['url']);
|
||||
@@ -59,11 +59,11 @@ foreach ($containers as $ct) {
|
||||
$project = html_entity_decode($info['Project']);
|
||||
$registry = html_entity_decode($info['registry']);
|
||||
$menu[] = sprintf("addDockerContainerContext('%s','%s','%s',%s,%s,%s,%s,'%s','%s','%s','%s','%s','%s');", addslashes($name), addslashes($ct['ImageId']), addslashes($template), $running, $paused, $updateStatus, $is_autostart, addslashes($webGui), $shell, $id, addslashes($support), addslashes($project),addslashes($registry));
|
||||
$docker[] = "docker.push({name:'$name',id:'$id',state:$running,pause:$paused,update:'$updateStatus'});";
|
||||
$docker[] = "docker.push({name:'$name',id:'$id',state:$running,pause:$paused,update:$updateStatus});";
|
||||
$shape = $running ? ($paused ? 'pause' : 'play') : 'square';
|
||||
$status = $running ? ($paused ? 'paused' : 'started') : 'stopped';
|
||||
$color = $status=='started' ? 'green-text' : ($status=='paused' ? 'orange-text' : 'red-text');
|
||||
$update = $updateStatus=='false' ? 'blue-text' : '';
|
||||
$update = $updateStatus==1 ? 'blue-text' : '';
|
||||
$icon = $info['icon'] ?: '/plugins/dynamix.docker.manager/images/question.png';
|
||||
$image = substr($icon,-4)=='.png' ? "<img src='$icon?".filemtime("$docroot{$info['icon']}")."' class='img'>" : (substr($icon,0,5)=='icon-' ? "<i class='$icon img'></i>" : "<i class='fa fa-$icon img'></i>");
|
||||
$wait = var_split($autostart[array_search($name,$names)],1);
|
||||
@@ -97,15 +97,23 @@ foreach ($containers as $ct) {
|
||||
echo htmlspecialchars($author);
|
||||
}
|
||||
echo "</span></td><td class='updatecolumn'>";
|
||||
if ($updateStatus=='false') {
|
||||
echo "<div class='advanced'><span class='orange-text' style='white-space:nowrap;'><i class='fa fa-flash fa-fw'></i> update ready</span></div>";
|
||||
echo "<a class='exec' onclick=\"updateContainer('".addslashes(htmlspecialchars($name))."');\"><span style='white-space:nowrap;'><i class='fa fa-cloud-download fa-fw'></i> apply update</span></a>";
|
||||
} elseif ($updateStatus=='true') {
|
||||
switch ($updateStatus) {
|
||||
case 0:
|
||||
echo "<span class='green-text' style='white-space:nowrap;'><i class='fa fa-check fa-fw'></i> up-to-date</span>";
|
||||
echo "<div class='advanced'><a class='exec' onclick=\"updateContainer('".addslashes(htmlspecialchars($name))."');\"><span style='white-space:nowrap;'><i class='fa fa-cloud-download fa-fw'></i> force update</span></a></div>";
|
||||
} else {
|
||||
echo "<span class='orange-text' style='white-space:nowrap;'><i class='fa fa-warning'></i> not available</span>";
|
||||
break;
|
||||
case 1:
|
||||
echo "<div class='advanced'><span class='orange-text' style='white-space:nowrap;'><i class='fa fa-flash fa-fw'></i> update ready</span></div>";
|
||||
echo "<a class='exec' onclick=\"updateContainer('".addslashes(htmlspecialchars($name))."');\"><span style='white-space:nowrap;'><i class='fa fa-cloud-download fa-fw'></i> apply update</span></a>";
|
||||
break;
|
||||
case 2:
|
||||
echo "<div class='advanced'><span class='orange-text' style='white-space:nowrap;'><i class='fa fa-flash fa-fw'></i> rebuild ready</span></div>";
|
||||
echo "<a class='exec'><span style='white-space:nowrap;'><i class='fa fa-recycle fa-fw'></i> rebuilding</span></a>";
|
||||
break;
|
||||
default:
|
||||
echo "<span class='orange-text' style='white-space:nowrap;'><i class='fa fa-unlink'></i> not available</span>";
|
||||
echo "<div class='advanced'><a class='exec' onclick=\"updateContainer('".addslashes(htmlspecialchars($name))."');\"><span style='white-space:nowrap;'><i class='fa fa-cloud-download fa-fw'></i> force update</span></a></div>";
|
||||
break;
|
||||
}
|
||||
echo "<div class='advanced'><i class='fa fa-info-circle fa-fw'></i> $version</div></td>";
|
||||
echo "<td>{$ct['NetworkMode']}</td>";
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2014-2018, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2014-2020, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2014-2018, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2014-2020, Guilherme Jardim, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -238,14 +238,14 @@ function xmlToVar($xml) {
|
||||
|
||||
function xmlSecurity(&$template) {
|
||||
foreach ($template as &$element) {
|
||||
if ( is_array($element) ) {
|
||||
if (is_array($element)) {
|
||||
xmlSecurity($element);
|
||||
} else {
|
||||
if ( is_string($element) ) {
|
||||
if (is_string($element)) {
|
||||
$tempElement = htmlspecialchars_decode($element);
|
||||
$tempElement = str_replace("[","<",$tempElement);
|
||||
$tempElement = str_replace("]",">",$tempElement);
|
||||
if ( preg_match('#<script(.*?)>(.*?)</script>#is',$tempElement) || preg_match('#<iframe(.*?)>(.*?)</iframe>#is',$tempElement) ) {
|
||||
if (preg_match('#<script(.*?)>(.*?)</script>#is',$tempElement) || preg_match('#<iframe(.*?)>(.*?)</iframe>#is',$tempElement)) {
|
||||
$element = "REMOVED";
|
||||
}
|
||||
}
|
||||
@@ -258,7 +258,7 @@ function xmlToCommand($xml, $create_paths=false) {
|
||||
$xml = xmlToVar($xml);
|
||||
$cmdName = strlen($xml['Name']) ? '--name='.escapeshellarg($xml['Name']) : '';
|
||||
$cmdPrivileged = strtolower($xml['Privileged'])=='true' ? '--privileged=true' : '';
|
||||
$cmdNetwork = '--net='.escapeshellarg(strtolower($xml['Network']));
|
||||
$cmdNetwork = preg_match('/\-\-net(work)?=/',$xml['ExtraParams']) ? "" : '--net='.escapeshellarg(strtolower($xml['Network']));
|
||||
$cmdMyIP = '';
|
||||
foreach (explode(' ',str_replace(',',' ',$xml['MyIP'])) as $myIP) if ($myIP) $cmdMyIP .= (strpos($myIP,':')?'--ip6=':'--ip=').escapeshellarg($myIP).' ';
|
||||
$cmdCPUset = strlen($xml['CPUset']) ? '--cpuset-cpus='.escapeshellarg($xml['CPUset']) : '';
|
||||
@@ -268,7 +268,7 @@ function xmlToCommand($xml, $create_paths=false) {
|
||||
$Labels = [''];
|
||||
$Devices = [''];
|
||||
// Bind Time
|
||||
$Variables[] = 'TZ="' . $var['timeZone'] . '"';
|
||||
$Variables[] = 'TZ="'.$var['timeZone'].'"';
|
||||
// Add HOST_OS variable
|
||||
$Variables[] = 'HOST_OS="Unraid"';
|
||||
|
||||
@@ -280,7 +280,7 @@ function xmlToCommand($xml, $create_paths=false) {
|
||||
if ($confType != "device" && !strlen($containerConfig)) continue;
|
||||
if ($confType == "path") {
|
||||
$Volumes[] = escapeshellarg($hostConfig).':'.escapeshellarg($containerConfig).':'.escapeshellarg($Mode);
|
||||
if ( ! file_exists($hostConfig) && $create_paths ) {
|
||||
if (!file_exists($hostConfig) && $create_paths) {
|
||||
@mkdir($hostConfig, 0777, true);
|
||||
@chown($hostConfig, 99);
|
||||
@chgrp($hostConfig, 100);
|
||||
@@ -439,7 +439,7 @@ function pullImage($name, $image, $echo=true) {
|
||||
if ($echo) @flush();
|
||||
});
|
||||
if ($echo) {
|
||||
echo "<script>addLog('<br><b>TOTAL DATA PULLED:</b> " . $DockerClient->formatBytes(array_sum($alltotals)) . "');</script>\n";
|
||||
echo "<script>addLog('<br><b>TOTAL DATA PULLED:</b> ".$DockerClient->formatBytes(array_sum($alltotals))."');</script>\n";
|
||||
@flush();
|
||||
}
|
||||
if (!empty($strError)) {
|
||||
@@ -469,7 +469,7 @@ function execCommand($command, $echo=true) {
|
||||
@flush();
|
||||
}
|
||||
$proc = proc_open($command." 2>&1", $descriptorspec, $pipes, '/', []);
|
||||
while ($out = fgets( $pipes[1] )) {
|
||||
while ($out = fgets($pipes[1])) {
|
||||
$out = preg_replace("%[\t\n\x0B\f\r]+%", '', $out);
|
||||
if ($echo) {
|
||||
echo '<script>addLog("'.htmlspecialchars($out).'");</script>';
|
||||
@@ -524,16 +524,22 @@ function getAllocations() {
|
||||
return $ports;
|
||||
}
|
||||
|
||||
function getCurlHandle($url, $method = 'GET') {
|
||||
$ch = curl_init();
|
||||
curl_setopt( $ch, CURLOPT_URL, $url );
|
||||
curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true );
|
||||
if ($method === 'HEAD') {
|
||||
curl_setopt( $ch, CURLOPT_CUSTOMREQUEST, 'HEAD' );
|
||||
curl_setopt( $ch, CURLOPT_HEADER, 1 );
|
||||
curl_setopt( $ch, CURLOPT_NOBODY, true );
|
||||
}
|
||||
|
||||
return $ch;
|
||||
function getCurlHandle($url, $method='GET') {
|
||||
$ch = curl_init();
|
||||
curl_setopt($ch, CURLOPT_URL, $url);
|
||||
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
|
||||
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
|
||||
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 15);
|
||||
curl_setopt($ch, CURLOPT_TIMEOUT, 45);
|
||||
curl_setopt($ch, CURLOPT_ENCODING, "");
|
||||
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
|
||||
curl_setopt($ch, CURLOPT_REFERER, "");
|
||||
if ($method === 'HEAD') {
|
||||
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'HEAD');
|
||||
curl_setopt($ch, CURLOPT_HEADER, true);
|
||||
curl_setopt($ch, CURLOPT_NOBODY, true);
|
||||
}
|
||||
return $ch;
|
||||
}
|
||||
?>
|
||||
|
||||
@@ -7,8 +7,8 @@ function addDockerContainerContext(container, image, template, started, paused,
|
||||
opts.push({text:'Console', icon:'fa-terminal', action:function(e){e.preventDefault(); dockerTerminal(container,shell);}});
|
||||
opts.push({divider:true});
|
||||
}
|
||||
if (!update) {
|
||||
opts.push({text:'Update', icon:'fa-arrow-down', action:function(e){e.preventDefault(); execUpContainer(container);}});
|
||||
if (update==1) {
|
||||
opts.push({text:'Update', icon:'fa-cloud-download', action:function(e){e.preventDefault(); execUpContainer(container);}});
|
||||
opts.push({divider:true});
|
||||
}
|
||||
if (started) {
|
||||
@@ -56,11 +56,6 @@ function dockerTerminal(container,shell) {
|
||||
var win = window.open('', container, 'resizeable=yes,scrollbars=yes,height='+height+',width='+width+',top='+top+',left='+left);
|
||||
$.get(eventURL,{action:'terminal',name:container,shell:shell},function(){win.location='/dockerterminal/'+container+'/'; win.focus();});
|
||||
}
|
||||
function execUpContainer(container) {
|
||||
var title = 'Updating the container: '+container;
|
||||
var address = '/plugins/dynamix.docker.manager/include/CreateDocker.php?updateContainer=true&ct[]='+encodeURIComponent(container);
|
||||
popupWithIframe(title, address, true, 'loadlist');
|
||||
}
|
||||
function popupWithIframe(title, cmd, reload, func) {
|
||||
pauseEvents();
|
||||
$('#iframe-popup').html('<iframe id="myIframe" frameborder="0" scrolling="yes" width="100%" height="99%"></iframe>');
|
||||
@@ -89,6 +84,11 @@ function popupWithIframe(title, cmd, reload, func) {
|
||||
$('.ui-dialog .ui-dialog-title').css('text-align', 'center').css('width', '100%');
|
||||
$('.ui-dialog .ui-dialog-content').css('padding', '12');
|
||||
}
|
||||
function execUpContainer(container) {
|
||||
var title = 'Updating the container: '+container;
|
||||
var cmd = '/plugins/dynamix.docker.manager/include/CreateDocker.php?updateContainer=true&ct[]='+encodeURIComponent(container);
|
||||
popupWithIframe(title, cmd, true, 'loadlist');
|
||||
}
|
||||
function addContainer() {
|
||||
var path = location.pathname;
|
||||
var x = path.indexOf('?');
|
||||
@@ -126,6 +126,7 @@ function rmContainer(container, image, id) {
|
||||
showLoaderOnConfirm:true
|
||||
},function(c){
|
||||
if (!c) {setTimeout(loadlist,0); return;}
|
||||
$('div.spinner.fixed').show('slow');
|
||||
if ($('#removeimagechk').prop('checked')) {
|
||||
eventControl({action:'remove_all', container:id, name:container, image:image},'loadlist');
|
||||
} else {
|
||||
@@ -145,6 +146,7 @@ function rmImage(image, imageName) {
|
||||
showLoaderOnConfirm:true
|
||||
},function(c){
|
||||
if (!c) {setTimeout(loadlist,0); return;}
|
||||
$('div.spinner.fixed').show('slow');
|
||||
eventControl({action:'remove_image', image:image},'loadlist');
|
||||
});
|
||||
}
|
||||
@@ -190,12 +192,17 @@ function checkAll() {
|
||||
}
|
||||
function updateAll() {
|
||||
$('input[type=button]').prop('disabled',true);
|
||||
$('#docker_list').append("<div class='spinner fixed'></div>");
|
||||
$('div.spinner').html(unraid_logo).show('slow');
|
||||
var list = '';
|
||||
for (var i=0,ct; ct=docker[i]; i++) if (ct.update=='false') list += '&ct[]='+encodeURI(ct.name);
|
||||
var address = '/plugins/dynamix.docker.manager/include/CreateDocker.php?updateContainer=true'+list;
|
||||
popupWithIframe('Updating all Containers', address, true, 'loadlist');
|
||||
var ct = '';
|
||||
for (var i=0,d; d=docker[i]; i++) if (d.update==1) ct += '&ct[]='+encodeURI(d.name);
|
||||
var cmd = '/plugins/dynamix.docker.manager/include/CreateDocker.php?updateContainer=true'+ct;
|
||||
popupWithIframe('Updating all Containers', cmd, true, 'loadlist');
|
||||
}
|
||||
function rebuildAll() {
|
||||
$('input[type=button]').prop('disabled',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
var ct = [];
|
||||
for (var i=0,d; d=docker[i]; i++) if (d.update==2) ct.push(encodeURI(d.name));
|
||||
$.get('/plugins/dynamix.docker.manager/include/CreateDocker.php',{updateContainer:true,mute:true,ct},function(){loadlist();});
|
||||
}
|
||||
function containerLogs(container, id) {
|
||||
var height = 600;
|
||||
|
||||
@@ -6,8 +6,8 @@ Tabs="true"
|
||||
Code="e944"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -44,14 +44,16 @@ function resize(bind) {
|
||||
}
|
||||
<?endif;?>
|
||||
function loadlist(id) {
|
||||
timers.plugins = setTimeout(function(){$('div.spinner.fixed').show('slow');},150);
|
||||
$.get('/plugins/dynamix.plugin.manager/include/ShowPlugins.php',{audit:id,check:<?=$check?>},function(d) {
|
||||
var data = d.split(/\0/);
|
||||
var list = $('#plugin_list');
|
||||
clearTimeout(timers.plugins);
|
||||
if (id) {
|
||||
var cmd = id.split(':');
|
||||
var tr = 'tr#'+cmd[0].replace(/[\. _]/g,'');
|
||||
switch (cmd[1]) {
|
||||
case 'return' : $('div.spinner').hide('slow').remove();list.html(data[0]); $('#plugin_table').trigger('destroy'); break;
|
||||
case 'return' : list.html(data[0]); $('#plugin_table').trigger('destroy'); break;
|
||||
case 'remove' : list.find(tr).remove(); break;
|
||||
case 'update' : list.find(tr).remove();
|
||||
case 'install': if (!list.find(tr).length) list.append(data[0]).trigger('update'); break;
|
||||
@@ -69,22 +71,19 @@ function loadlist(id) {
|
||||
<?if ($check):?>
|
||||
$('#checkall').find('input').prop('disabled',false).show();
|
||||
<?endif;?>
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
});
|
||||
}
|
||||
function spinner() {
|
||||
$('#plugin_list').append("<div class='spinner fixed'></div>");
|
||||
$('div.spinner').html(unraid_logo).show('slow');
|
||||
}
|
||||
$(function() {
|
||||
loadlist();
|
||||
$('#plugin_tree').fileTree({root:'/boot/',filter:'plg'}, function(file) {$('#plugin_file').val(file);});
|
||||
$('.tabs').append("<span id='updateall' class='status vhshift' style='display:none;margin-left:12px'><input type='button' value='Update All Plugins' onclick='spinner();openBox(\"/plugins/dynamix.plugin.manager/scripts/plugin&arg1=updateall\",\"Update All Plugins\",600,600,true,\"loadlist\",\":return\")'></span>");
|
||||
$('.tabs').append("<span id='updateall' class='status vhshift' style='display:none;margin-left:12px'><input type='button' value='Update All Plugins' onclick='openBox(\"/plugins/dynamix.plugin.manager/scripts/plugin&arg1=updateall\",\"Update All Plugins\",600,600,true,\"loadlist\",\":return\")'></span>");
|
||||
<?if ($check):?>
|
||||
$('.tabs').append("<span id='checkall' class='status vhshift'><input type='button' value='Check For Updates' onclick='spinner();openBox(\"/plugins/dynamix.plugin.manager/scripts/plugin&arg1=checkall\",\"Plugin Update Check\",600,600,true,\"loadlist\",\":return\")' disabled></span>");
|
||||
$('.tabs').append("<span id='checkall' class='status vhshift'><input type='button' value='Check For Updates' onclick='openBox(\"/plugins/dynamix.plugin.manager/scripts/plugin&arg1=checkall\",\"Plugin Update Check\",600,600,true,\"loadlist\",\":return\")' disabled></span>");
|
||||
<?endif;?>
|
||||
});
|
||||
</script>
|
||||
<table class='tablesorter plugins shift' id='plugin_table'>
|
||||
<thead><tr><th></th><th>Plugin</th><th>Author</th><th>Version</th><th>Status</th><th>Uninstall</th></tr></thead>
|
||||
<tbody id="plugin_list"><tr><td colspan="6"><div class="spinner"></div></td><tr></tbody>
|
||||
<tbody id="plugin_list"><tr><td colspan="6"></td><tr></tbody>
|
||||
</table>
|
||||
|
||||
@@ -4,8 +4,8 @@ Icon="icon-update"
|
||||
Tag="upload"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -16,7 +16,7 @@ Tag="upload"
|
||||
*/
|
||||
?>
|
||||
<?
|
||||
$empty = "<tr><td colspan='6'><div class='spinner'></div></td><tr>";
|
||||
$empty = "<tr><td colspan='6'><div class='spinner'></div></td></tr>";
|
||||
$version = $branch = $date = 'unknown';
|
||||
$bzroot = file_exists('/boot/previous/bzroot');
|
||||
$check = $notify['unraidos'] ? 0 : 1;
|
||||
@@ -36,7 +36,7 @@ if (file_exists('/boot/previous/changes.txt')) {
|
||||
<style>
|
||||
input[value='Install'],input[value='Update'],input[value='Restore']{margin:0}
|
||||
<?if (strstr('white,black',$display['theme'])):?>
|
||||
span.vhshift{margin-top:11px!important}
|
||||
span.vhshift{margin-top:13px!important}
|
||||
<?endif;?>
|
||||
</style>
|
||||
<script>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -48,16 +48,17 @@ foreach (glob($plugins,GLOB_NOSORT) as $plugin_link) {
|
||||
$checked = (!$audit && !$check) ? check_plugin(basename($plugin_file),$ncsi) : true;
|
||||
//OS update?
|
||||
$os = $system && $name==$builtin[0];
|
||||
$toggle = false;
|
||||
$past = false;
|
||||
//toggle stable/next release?
|
||||
if ($os && $branch) {
|
||||
$toggle = plugin('version',$plugin_file);
|
||||
$past = plugin('version',$plugin_file);
|
||||
$tmp_plg = "$name-.plg";
|
||||
$tmp_file = "/var/tmp/$name.plg";
|
||||
copy($plugin_file,$tmp_file);
|
||||
exec("sed -ri 's|^(<!ENTITY category).*|\\1 \"{$branch}\">|' $tmp_file");
|
||||
symlink($tmp_file,"/var/log/plugins/$tmp_plg");
|
||||
if (check_plugin($tmp_plg,$ncsi)) {
|
||||
$next = end(explode("\n",check_plugin($tmp_plg,$ncsi)));
|
||||
if (version_compare($next,$past,'>')) {
|
||||
copy("/tmp/plugins/$tmp_plg",$tmp_file);
|
||||
$plugin_file = $tmp_file;
|
||||
}
|
||||
@@ -108,7 +109,7 @@ foreach (glob($plugins,GLOB_NOSORT) as $plugin_link) {
|
||||
if ($url !== false) {
|
||||
$filename = "/tmp/plugins/".(($os && $branch) ? $tmp_plg : basename($url));
|
||||
if ($checked && file_exists($filename)) {
|
||||
if ($toggle && $toggle != $version) {
|
||||
if ($past && $past != $version) {
|
||||
$status = make_link('install',$plugin_file,'forced');
|
||||
} else {
|
||||
$latest = plugin('version',$filename);
|
||||
|
||||
@@ -5,9 +5,9 @@ Cond="is_file('/var/run/libvirt/libvirtd.pid')"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2015-2018, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -93,31 +93,32 @@ if (empty($vms)) {
|
||||
: 'Libvirt is not running. Goto Settings tab then click Start.';
|
||||
}
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/plugins/dynamix.vm.manager/styles/dynamix.vm.manager.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.ui.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.filetree.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<style type="text/css">
|
||||
.fileTree{width:300px;max-height:150px;overflow-y:scroll;position:absolute;z-index:100;display:none}
|
||||
div.four{font-size:1.1rem;width:300px}
|
||||
<style>
|
||||
th.th1{width:25%}
|
||||
th.th2{width:15%}
|
||||
th.th3{width:70px}
|
||||
div.four{font-size:1.1rem;width:260px}
|
||||
div.four label{float:left;display:table-cell;width:25%}
|
||||
div.four label:nth-child(4n+4){float:none;clear:both}
|
||||
div.four label.cpu1{width:32%}
|
||||
div.four label.cpu2{width:26%}
|
||||
th.vmname{width:350px}
|
||||
th.eight{width:8%}
|
||||
table.domdisk tbody tr:nth-child(even){background-color:transparent}
|
||||
table tbody td{line-height:normal}
|
||||
table.domdisk thead th:nth-child(1){width:76%;}
|
||||
table.domdisk thead th:nth-child(2){width:8%;}
|
||||
table.domdisk thead th:nth-child(3){width:8%;}
|
||||
table.domdisk thead tr th:nth-child(1){padding-left:72px}
|
||||
table.domdisk tbody tr td:nth-child(1){padding-left:72px}
|
||||
table.domdisk tbody tr:nth-child(even){background-color:transparent!important}
|
||||
table.domdisk tbody tr:nth-child(4n-1){background-color:transparent!important}
|
||||
</style>
|
||||
<table id="kvm_table" class="tablesorter four shift">
|
||||
<thead><tr><th class="vmname"><a href="#" style="cursor:hand;margin-left:12px;display:inline-block;width:32px" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-th-list"></i></a>Name</th><th>Description</th><th>CPUs</th><th>Memory</th><th>vDisks</th><th>Graphics</th><th class="eight">Autostart</th></tr></thead>
|
||||
<tbody id="kvm_list"><tr><td colspan='8'><div class="spinner"></div></td></tr></tbody>
|
||||
<thead><tr><th class="th1"><a href="#" style="cursor:hand;margin-left:12px;display:inline-block;width:32px" onclick="resetSorting()" title="Reset sorting"><i class="fa fa-th-list"></i></a>Name</th><th class="th2">Description</th><th>CPUs</th><th>Memory</th><th>vDisks</th><th>Graphics</th><th class="th3">Autostart</th></tr></thead>
|
||||
<tbody id="kvm_list"><tr><td colspan='8'></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" onclick="addVM()" id="btnAddVM" value="Add VM" style="display:none">
|
||||
<input type="button" onclick="startAll()" value="Start All" style="display:none">
|
||||
<input type="button" onclick="stopAll()" value="Stop All" style="display:none">
|
||||
|
||||
<script src="<?autov('/webGui/javascript/jquery.filetree.js')?>"></script>
|
||||
<script src="<?autov('/webGui/javascript/jquery.switchbutton.js')?>"></script>
|
||||
<script src="<?autov('/plugins/dynamix.vm.manager/javascript/dynamix.vm.manager.js')?>"></script>
|
||||
<script src="<?autov('/plugins/dynamix.vm.manager/javascript/vmmanager.js')?>"></script>
|
||||
@@ -146,7 +147,9 @@ var sortableHelper = function(e,i){
|
||||
return i;
|
||||
};
|
||||
function loadlist() {
|
||||
timers.vm = setTimeout(function(){$('div.spinner.fixed').show('slow');},150);
|
||||
$.get('/plugins/dynamix.vm.manager/include/VMMachines.php',{show:$.cookie('vmshow')},function(d) {
|
||||
clearTimeout(timers.vm);
|
||||
var data = d.split(/\0/);
|
||||
$('#kvm_list').html(data[0]).sortable({helper:sortableHelper,items:'tr.sortable',cursor:'move',axis:'y',containment:'parent',delay:100,opacity:0.5,zIndex:9999,
|
||||
update:function(e,ui){
|
||||
@@ -186,6 +189,7 @@ function loadlist() {
|
||||
},'json');
|
||||
});
|
||||
context.init({preventDoubleContext:false,left:true,above:false});
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
$('input[type=button]').prop('disabled',false).show('slow');
|
||||
$('.text').click(showInput);
|
||||
$('.input').blur(hideInput);
|
||||
|
||||
@@ -4,9 +4,9 @@ Icon="icon-virtualization"
|
||||
Tag="columns"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2019, Lime Technology
|
||||
* Copyright 2015-2019, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2019, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -21,12 +21,10 @@ require_once "$docroot/plugins/dynamix.vm.manager/include/libvirt_helpers.php";
|
||||
|
||||
// Check for Intel VT-x (vmx) or AMD-V (svm) cpu virtualization support
|
||||
// If either kvm_intel or kvm_amd are loaded then Intel VT-x (vmx) or AMD-V (svm) cpu virtualization support was found
|
||||
$strLoadedModules = shell_exec("/etc/rc.d/rc.libvirt test");
|
||||
if (empty($strLoadedModules)) {
|
||||
echo "<p class='notice'>Your hardware does not have Intel VT-x or AMD-V capability. This is required to create VMs in KVM.";
|
||||
$hardware = !empty(shell_exec("/etc/rc.d/rc.libvirt test"));
|
||||
if (!$hardware) {
|
||||
echo "<p class='notice'>Your hardware does not have Intel VT-x or AMD-V capability. This is required to create VMs in KVM. Please disable the VM function. ";
|
||||
echo "<a href='http://lime-technology.com/wiki/index.php/UnRAID_Manual_6#Hardware-Assisted_Virtualization_.28HVM.29' target='_blank'> Click here to see the Unraid Wiki for more information</a></p>";
|
||||
echo "<input type='button' value='Done' onclick='done()'>";
|
||||
exit;
|
||||
}
|
||||
|
||||
function scan($area, $text) {
|
||||
@@ -58,7 +56,6 @@ $pcie_acs_override = detect($syslinux, 'pcie_acs_override');
|
||||
$vfio_allow_unsafe = detect($syslinux, 'allow_unsafe_interrupts');
|
||||
$bgcolor = strstr('white,azure',$display['theme']) ? '#f2f2f2' : '#1c1c1c';
|
||||
?>
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/plugins/dynamix.vm.manager/styles/dynamix.vm.manager.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.filetree.css')?>">
|
||||
<link type="text/css" rel="stylesheet" href="<?autov('/webGui/styles/jquery.switchbutton.css')?>">
|
||||
<style>
|
||||
@@ -77,7 +74,9 @@ body{-webkit-overflow-scrolling:touch}
|
||||
#remove_button span{font-family:clear-sans}
|
||||
</style>
|
||||
|
||||
<?if ($hardware):?>
|
||||
<span class="status vhshift"><input type="checkbox" class="advancedview"></span>
|
||||
<?endif;?>
|
||||
<form markdown="1" id="settingsForm" method="POST" action="/update.php" target="progressFrame">
|
||||
<input type="hidden" name="#file" value="<?=htmlspecialchars($domain_cfgfile)?>">
|
||||
<input type="hidden" name="#command" value="/plugins/dynamix/scripts/emcmd">
|
||||
@@ -87,14 +86,17 @@ Enable VMs:
|
||||
<?= mk_option($libvirt_service, 'disable', 'No'); ?>
|
||||
<?= mk_option($libvirt_service, 'enable', 'Yes'); ?>
|
||||
</select>
|
||||
<?if ($hardware):?>
|
||||
<?if ($var['fsState'] != "Started"):?>
|
||||
<span id="arraystopped"><i class="fa fa-warning icon warning"></i> <?=($libvirt_service=='enable')?'VMs will be available after Array is Started':'Apply to activate VMs after Array is Started'?></span>
|
||||
<?elseif (!is_dir(dirname($domain_cfg['IMAGE_FILE'])) || !is_dir($domain_cfg['DOMAINDIR']) || !is_dir($domain_cfg['MEDIADIR'])):?>
|
||||
<span class="basic" style="display:inline"><i class="fa fa-warning icon warning"></i> One or more paths do not exist (<a href="#" onclick="$('.advancedview').switchButton('option','checked',true); return false">view</a>)</span>
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
|
||||
> Stopping the VM Manager will first attempt to shutdown all running VMs. After 60 seconds, any remaining VM instances will be terminated.
|
||||
|
||||
<?if ($hardware):?>
|
||||
<div class="advanced" markdown="1">
|
||||
<?if ($libvirt_running == 'yes'):?>
|
||||
<?$libvirt_info = libvirt_version('libvirt')?>
|
||||
@@ -230,6 +232,7 @@ VFIO allow unsafe interrupts:
|
||||
<?else:?>
|
||||
|
||||
<?endif;?>
|
||||
<?endif;?>
|
||||
: <input type="button" id="applyBtn" value="Apply" disabled><input type="button" value="Done" onclick="done()">
|
||||
</form>
|
||||
<div class="notice reboot" style="display:none;margin-bottom:24px">System must be rebooted for changes to take effect!</div>
|
||||
@@ -400,6 +403,7 @@ $(function(){
|
||||
$('.advanced').show();
|
||||
$('.basic').hide();
|
||||
}
|
||||
<?if ($hardware):?>
|
||||
$('.advancedview').switchButton({
|
||||
labels_placement: "left",
|
||||
on_label: 'Advanced View',
|
||||
@@ -411,6 +415,7 @@ $(function(){
|
||||
$('.basic').toggle('slow');
|
||||
$.cookie('vmsettings_view_mode', $('.advancedview').is(':checked') ? 'advanced' : 'basic', {expires:3650});
|
||||
});
|
||||
<?endif;?>
|
||||
showStatus('pid','libvirt/libvirtd');
|
||||
<?if ($var['fsState'] == "Started"):?>
|
||||
$("input[data-pickroot]").fileTreeAttach();
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2015-2018, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2015-2020, Derek Macias, Eric Schultz, Jon Panozzo.
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -113,7 +113,7 @@ foreach ($vms as $vm) {
|
||||
|
||||
/* Disk device information */
|
||||
echo "<tr child-id='$i' id='name-$i".(in_array('name-'.$i++,$show) ? "'>" : "' style='display:none'>");
|
||||
echo "<td colspan='7' style='overflow:hidden'>";
|
||||
echo "<td colspan='8' style='margin:0;padding:0'>";
|
||||
echo "<table class='tablesorter domdisk' id='domdisk_table'>";
|
||||
echo "<thead><tr><th><i class='fa fa-hdd-o'></i> <b>Disk devices</b></th><th>Bus</th><th>Capacity</th><th>Allocation</th></tr></thead>";
|
||||
echo "<tbody id='domdisk_list'>";
|
||||
@@ -152,7 +152,6 @@ foreach ($vms as $vm) {
|
||||
$bus = $arrValidDiskBuses[$arrCD['bus']] ?? 'VirtIO';
|
||||
echo "<tr><td>$disk</td><td>$bus</td><td>$capacity</td><td>$allocation</td></tr>";
|
||||
}
|
||||
|
||||
echo "</tbody></table>";
|
||||
echo "</td></tr>";
|
||||
}
|
||||
|
||||
@@ -500,9 +500,9 @@ function formatWarning(val) {
|
||||
</form>
|
||||
<?endif;?><!-- markdown fix -->
|
||||
<table class="array_status noshift">
|
||||
<tr><td></td><td><input type="button" id="button-down" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('down')" value="Spin Down"<?=$parity?' disabled':''?>><input type="button" id="button-up" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('up')" value="Spin Up"<?=$parity?' disabled':''?>></td>
|
||||
<td><strong>Spin Down</strong> will immediately spin down all disks.<br><strong>Spin Up</strong> will immediately spin up all disks.</td></tr>
|
||||
<tr><td></td><td><input type="button" value="Clear Statistics" onclick="toggle_state('Clear')"></td><td><strong>Clear Statistics</strong> will immediately clear all disk statistics.</td></tr>
|
||||
<tr><td></td><td><input type="button" id="button-up" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('up')" value="Spin Up"<?=$parity?' disabled':''?>><input type="button" id="button-down" onclick="$('[id^=button-]').prop('disabled',true);toggle_state('down')" value="Spin Down"<?=$parity?' disabled':''?>></td>
|
||||
<td><strong>Spin Up</strong> will immediately spin up all disks.<br><strong>Spin Down</strong> will immediately spin down all disks.</td></tr>
|
||||
<tr><td></td><td><input type="button" value="Clear" onclick="toggle_state('Clear')"></td><td><strong>Clear</strong> will immediately clear all disk statistics.</td></tr>
|
||||
<tr><td></td><td class="line" colspan="2"></td></tr>
|
||||
</table>
|
||||
<?if ($var['shareCacheEnabled']=="yes" && is_dir("/mnt/cache")):?>
|
||||
@@ -510,9 +510,9 @@ function formatWarning(val) {
|
||||
<table class="array_status noshift">
|
||||
<tr><td></td>
|
||||
<?if ($mover):?>
|
||||
<td><input type="submit" name="cmdStartMover" value="Move now" disabled></td><td>Disabled - Mover is running.</td>
|
||||
<td><input type="submit" name="cmdStartMover" value="Move" disabled></td><td>Disabled - Mover is running.</td>
|
||||
<?else:?>
|
||||
<td><input type="submit" name="cmdStartMover" value="Move now"></td><td><strong>Move now</strong> will immediately invoke the Mover. <a href="/Main/Scheduler"<?if ($tabbed):?> onclick="$.cookie('one','tab2',{path:'/'})"<?endif;?>>(Schedule)</a></td>
|
||||
<td><input type="submit" name="cmdStartMover" value="Move"></td><td><strong>Move</strong> will immediately invoke the Mover. <a href="/Main/Scheduler"<?if ($tabbed):?> onclick="$.cookie('one','tab2',{path:'/'})"<?endif;?>>(Schedule)</a></td>
|
||||
<?endif;?>
|
||||
</tr>
|
||||
</table>
|
||||
@@ -530,8 +530,8 @@ function formatWarning(val) {
|
||||
<?endif;?><!-- markdown fix -->
|
||||
<form name="shutdownOps" method="POST" action="/webGui/include/Boot.php">
|
||||
<table class="array_status noshift">
|
||||
<tr><td></td><td><input type="button" name="reboot" value="Reboot" onclick="shutdown_now(this.form,'reboot')"><input type="button" name="shutdown" value="Power down" onclick="shutdown_now(this.form,'shutdown')"></td>
|
||||
<td><strong>Reboot</strong> will activate a <em>clean</em> system reset.<br><strong>Power down</strong> will activate a <em>clean</em> power down.</td></tr>
|
||||
<tr><td></td><td><input type="button" name="reboot" value="Reboot" onclick="shutdown_now(this.form,'reboot')"><input type="button" name="shutdown" value="Shutdown" onclick="shutdown_now(this.form,'shutdown')"></td>
|
||||
<td><strong>Reboot</strong> will activate a <em>clean</em> system reset.<br><strong>Shutdown</strong> will activate a <em>clean</em> system power down.</td></tr>
|
||||
<tr><td></td><td class="line" colspan="2"></td></tr>
|
||||
</table>
|
||||
</form>
|
||||
|
||||
@@ -3,8 +3,8 @@ Tag="navicon"
|
||||
Markdown="false"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -20,7 +20,9 @@ Markdown="false"
|
||||
</style>
|
||||
<script>
|
||||
$(function(){
|
||||
timers.browse = setTimeout(function(){$('div.spinner.fixed').show('slow');},150);
|
||||
$.get('/webGui/include/Browse.php',{dir:"<?=addslashes(urlencode($dir))?>",path:"<?=$path?>",user:<?=strpos($dir,'/mnt/user')===0?1:0?>},function(data){
|
||||
clearTimeout(timers.browse);
|
||||
var table = $('table.indexer');
|
||||
var col = $.cookie('col')||1;
|
||||
var dir = $.cookie('dir')||0;
|
||||
@@ -30,12 +32,13 @@ $(function(){
|
||||
$.cookie('col',sort[0],{path:'/'});
|
||||
$.cookie('dir',sort[1],{path:'/'});
|
||||
});
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
table.tablesorter({sortList:[[col,dir],[1,0]],sortAppend:[[1,0]],textAttribute:'data'});
|
||||
});
|
||||
});
|
||||
</script>
|
||||
<table class="indexer tablesorter shift">
|
||||
<thead><tr><th>Type</th><th class='sorter-text'>Name</th><th>Size</th><th>Last Modified</th><th>Location</th></tr></thead>
|
||||
<tbody><tr><td colspan="5"><div class="spinner"></div></td></tr></tbody>
|
||||
<tbody><tr><td colspan="5"></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" value="Done" onclick="done('Browse')">
|
||||
|
||||
@@ -4,8 +4,8 @@ Icon="icon-clock"
|
||||
Tag="clock-o"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -32,7 +32,7 @@ Time zone:
|
||||
> Select your applicable time zone from the drop-down list.
|
||||
|
||||
Use NTP:
|
||||
: <select name="USE_NTP" size="1" class="narrow" onchange="checkDateTimeSettings(this.form)">
|
||||
: <select name="USE_NTP" size="1" onchange="checkDateTimeSettings(this.form)">
|
||||
<?=mk_option($var['USE_NTP'], "yes", "Yes")?>
|
||||
<?=mk_option($var['USE_NTP'], "no", "No")?>
|
||||
</select>
|
||||
@@ -43,27 +43,27 @@ Use NTP:
|
||||
> Note: if using `pool.ntp.org` time servers, please also refer to [their documentation](http://www.pool.ntp.org/en/use.html).
|
||||
|
||||
NTP server 1:
|
||||
: <input type="text" name="NTP_SERVER1" maxlength="80" value="<?=htmlspecialchars($var['NTP_SERVER1'])?>">
|
||||
: <input type="text" name="NTP_SERVER1" maxlength="40" class="narrow" value="<?=htmlspecialchars($var['NTP_SERVER1'])?>">
|
||||
|
||||
> This is the primary NTP server to use. Enter a FQDN or an IP address.
|
||||
|
||||
NTP server 2:
|
||||
: <input type="text" name="NTP_SERVER2" maxlength="80" value="<?=htmlspecialchars($var['NTP_SERVER2'])?>">
|
||||
: <input type="text" name="NTP_SERVER2" maxlength="40" class="narrow" value="<?=htmlspecialchars($var['NTP_SERVER2'])?>">
|
||||
|
||||
> This is the alternate NTP server to use if NTP Server 1 is down.
|
||||
|
||||
NTP server 3:
|
||||
: <input type="text" name="NTP_SERVER3" maxlength="80" value="<?=htmlspecialchars($var['NTP_SERVER3'])?>">
|
||||
: <input type="text" name="NTP_SERVER3" maxlength="40" class="narrow" value="<?=htmlspecialchars($var['NTP_SERVER3'])?>">
|
||||
|
||||
> This is the alternate NTP Server to use if NTP Servers 1 and 2 are both down.
|
||||
|
||||
NTP server 4:
|
||||
: <input type="text" name="NTP_SERVER4" maxlength="80" value="<?=htmlspecialchars($var['NTP_SERVER4'])?>">
|
||||
: <input type="text" name="NTP_SERVER4" maxlength="40" class="narrow" value="<?=htmlspecialchars($var['NTP_SERVER4'])?>">
|
||||
|
||||
> This is the alternate NTP Server to use if NTP Servers 1, 2, and 3 are all down.
|
||||
|
||||
New date and time:
|
||||
: <input type="text" name="newDateTime" maxlength="40" value="<?=my_time(time(), "%F %T")?>">
|
||||
: <input type="text" name="newDateTime" maxlength="20" class="narrow" value="<?=my_time(time(), "%F %T")?>">
|
||||
|
||||
> Enter the current time-of-day. Use format YYYY-MM-DD HH:MM:SS. Greyed out when using NTP.
|
||||
|
||||
|
||||
@@ -4,8 +4,8 @@ Icon="icon-diagnostics"
|
||||
Tag="tv"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -47,7 +47,6 @@ function diagnostics(file) {
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<div class="spinner" style="display:none"></div>
|
||||
<div id="pleaseWait" style="display:none;font-weight:bold;color:red;text-align:center;margin:0">Please wait... collecting diagnostic information (this may take several minutes)</div>
|
||||
This utility is used for troubleshooting purposes. It will collect all of the system information and configuration files, and package these files in a single ZIP file which can be saved locally.
|
||||
Subsequently, this file can be included in your correspondence with Limetech or the Unraid forum.
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Type="xmenu"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -33,13 +33,17 @@ $next = urlencode($i<$end ? $refs[$i+1] : $refs[0]);
|
||||
<style>
|
||||
div.clone1{position:absolute;right:0;margin-top:0}
|
||||
div.clone2{position:absolute;right:0;margin-top:48px}
|
||||
select.clone{min-width:144px;margin-right:0}
|
||||
<?if ($themes1):?>
|
||||
span.wrap{display:inline-block;width:128px}
|
||||
select.clone{min-width:123px;margin-right:0}
|
||||
<?else:?>
|
||||
span.wrap{display:inline-block;width:150px}
|
||||
select.clone{min-width:145px;margin-right:0}
|
||||
<?endif;?>
|
||||
input.clone{margin-left:8px;margin-right:0}
|
||||
span.clone,i.clone{margin-right:4px}
|
||||
</style>
|
||||
<script>
|
||||
var ctrl = "<span class='ctrl2 status <?=$tabbed?'vhshift':'vshift'?>'><a href='/Shares/Disk?name=<?=$prev?>' title='previous disk share'><button type='button' style='margin-right:4px'><i class='fa fa-chevron-left fa-fw'></i></button></a><a href='/Shares/Disk?name=<?=$next?>' title='next disk share'><button type='button'><i class='fa fa-chevron-right fa-fw'></i></button></a></span>";
|
||||
|
||||
function toggleButton(button,id) {
|
||||
var disabled = true;
|
||||
switch (id) {
|
||||
@@ -52,6 +56,9 @@ function toggleButton(button,id) {
|
||||
}
|
||||
$('input#'+button).prop('disabled',disabled);
|
||||
}
|
||||
|
||||
var ctrl = "<span class='ctrl2 status <?=$tabbed?'vhshift':'vshift'?>'><a href='/Shares/Disk?name=<?=$prev?>' title='previous disk share'><button type='button' style='margin-right:4px'><i class='fa fa-chevron-left fa-fw'></i></button></a><a href='/Shares/Disk?name=<?=$next?>' title='next disk share'><button type='button'><i class='fa fa-chevron-right fa-fw'></i></button></a></span>";
|
||||
|
||||
$(function() {
|
||||
<?if ($tabbed):?>
|
||||
$('.tabs').append(ctrl);
|
||||
|
||||
@@ -3,8 +3,8 @@ Title="Flash Device Settings"
|
||||
Tag="usb"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -42,7 +42,6 @@ function backup() {
|
||||
});
|
||||
}
|
||||
</script>
|
||||
<div class="spinner" style="display:none"></div>
|
||||
<div id="pleaseWait" style="display:none;text-align:center;margin-bottom:24px"><span class="red-text strong">Please wait... creating Flash backup zip file (this may take several minutes)</span></div>
|
||||
|
||||
Flash Vendor:
|
||||
|
||||
@@ -4,8 +4,8 @@ Icon="icon-archive"
|
||||
Tag="archive"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
* Copyright 2012, Andrew Hamer-Adams, http://www.pixeleyes.co.nz.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
@@ -43,7 +43,9 @@ function resize(bind) {
|
||||
}
|
||||
<?endif;?>
|
||||
function archiveList(init) {
|
||||
timers.archive = setTimeout(function(){$('div.spinner.fixed').show('slow');},150);
|
||||
$.get('/webGui/include/NotificationsArchive.php',{filter:'<?=addslashes(htmlspecialchars($_GET['filter']))?>'},function(data) {
|
||||
clearTimeout(timers.archive);
|
||||
if (data) $('#archive_list').html(data);
|
||||
if (init) {
|
||||
<?if ($display['resize']):?>
|
||||
@@ -55,6 +57,7 @@ function archiveList(init) {
|
||||
}
|
||||
$('#archive_list .tablesorter-childRow td').hide();
|
||||
for (var i = 0; i < rows.length; i++) $('#archive_list .tablesorter-childRow.row'+rows[i]+' td').show();
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
setTimeout(archiveList,30000);
|
||||
});
|
||||
}
|
||||
@@ -82,6 +85,6 @@ $(function(){
|
||||
</script>
|
||||
<table class="tablesorter left shift" id="archive_table">
|
||||
<thead><tr><th>Time</th><th>Event</th><th>Subject</th><th>Description</th><th>Importance</th><th><?if ($files):?><a href="#" onclick="askConfirmation();return false" title="Delete all notifications"><i class="fa fa-trash"></i></a><?endif;?></th></tr></thead>
|
||||
<tbody id="archive_list"><tr><td></td><td colspan="4"><div class="spinner"></div></td><td></td></tr></tbody>
|
||||
<tbody id="archive_list"><tr><td colspan="6"></td></tr></tbody>
|
||||
</table>
|
||||
<input type="button" value="Done" onclick="done()">
|
||||
|
||||
@@ -3,8 +3,8 @@ Title="SMB Settings"
|
||||
Tag="windows"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -51,7 +51,7 @@ Enhanced macOS interoperability:
|
||||
> Please also refer to the [VFS_FRUIT MAN PAGE](https://www.mankier.com/8/vfs_fruit).
|
||||
|
||||
Enable NetBIOS:
|
||||
: <select name="USE_NETBIOS" size="1" class="narrow" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
: <select name="USE_NETBIOS" size="1" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
<?=mk_option($var['USE_NETBIOS'], "no", "No")?>
|
||||
<?=mk_option($var['USE_NETBIOS'], "yes", "Yes")?>
|
||||
</select>
|
||||
@@ -60,7 +60,7 @@ Enable NetBIOS:
|
||||
> clients must use SMBv2 or higher.
|
||||
|
||||
Enable WSD:
|
||||
: <select name="USE_WSD" size="1" class="narrow" onchange="checkWSDSettings()" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
: <select name="USE_WSD" size="1" onchange="checkWSDSettings()" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
<?=mk_option($var['USE_WSD'], "no", "No")?>
|
||||
<?=mk_option($var['USE_WSD'], "yes", "Yes")?>
|
||||
</select>
|
||||
@@ -69,7 +69,7 @@ Enable WSD:
|
||||
> old LAN setup based on SMBv1.
|
||||
|
||||
WSD options [experimental]:
|
||||
: <input type="text" name="WSD_OPT" maxlength="80" value="<?=htmlspecialchars($var['WSD_OPT'])?>" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
: <input type="text" name="WSD_OPT" maxlength="80" class="narrow" value="<?=htmlspecialchars($var['WSD_OPT'])?>" <?if ($var['fsState']=="Started"):?>disabled<?endif;?>>
|
||||
|
||||
> This is a command line otions string passed to the WSD daemon upon startup. Leave this field blank unless
|
||||
> instructed by support to put something here.
|
||||
|
||||
@@ -4,8 +4,8 @@ Tag="apple"
|
||||
Cond="(($var['shareAFPEnabled']!='no') && (isset($name)?array_key_exists($name,$sec_afp):0))"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -30,8 +30,8 @@ $width = [123,300];
|
||||
> Select the desired destinations and press **Write** to copy the AFP security settings to the selected shares.
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left clone"></i>
|
||||
<select name="readafp" size="1" class="clone" onchange="toggleButton('readafp',false)">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readafp" size="1" class="clone" onchange="toggleButton('readafp',false)">
|
||||
<option disabled selected>select...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
@@ -40,11 +40,11 @@ if (isset($disks[$name])) {
|
||||
foreach ($shares as $list) if ($list['name']!=$name) echo mk_option("", $list['name'], $list['name']);
|
||||
}
|
||||
?>
|
||||
</select><input type="button" id="readafp" value="Read" class="clone" onclick="readAFP()" disabled>
|
||||
</select></span><input type="button" id="readafp" value="Read" class="clone" onclick="readAFP()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right clone"></i>
|
||||
<select id="afp1" name="writeafp" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeafp',this.id)">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="afp1" name="writeafp" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeafp',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
@@ -55,7 +55,7 @@ if (isset($disks[$name])) {
|
||||
if ($rows) echo "<option>(All)</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select><input type="button" id="writeafp" value="Write" class="clone" onclick="writeAFP()" disabled>
|
||||
</select></span><input type="button" id="writeafp" value="Write" class="clone" onclick="writeAFP()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="afp_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writeafp',true);$('#afp1').dropdownchecklist('disable')">
|
||||
@@ -139,8 +139,8 @@ Security:
|
||||
> Select the desired destinations and press **Write** to copy the AFP User access settings to the selected shares.
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left clone"></i>
|
||||
<select name="readuserafp" size="1" class="clone" onchange="toggleButton('readuserafp',false)">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readuserafp" size="1" class="clone" onchange="toggleButton('readuserafp',false)">
|
||||
<option disabled selected>select...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
@@ -149,11 +149,11 @@ if (isset($disks[$name])) {
|
||||
foreach ($shares as $list) if ($list['name']!=$name && $sec_afp[$list['name']]['security']=='secure') echo mk_option("", $list['name'], $list['name']);
|
||||
}
|
||||
?>
|
||||
</select><input type="button" id="readuserafp" value="Read" class="clone" onclick="readUserAFP()" disabled>
|
||||
</select></span><input type="button" id="readuserafp" value="Read" class="clone" onclick="readUserAFP()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right clone"></i>
|
||||
<select id="afp2" name="writeuserafp" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeuserafp',this.id)">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="afp2" name="writeuserafp" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeuserafp',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
@@ -164,7 +164,7 @@ if (isset($disks[$name])) {
|
||||
if ($rows) echo "<option>(All)</option>";
|
||||
foreach ($rows as $row)echo $row;
|
||||
?>
|
||||
</select><input type="button" id="writeuserafp" value="Write" class="clone" onclick="writeUserAFP()" disabled>
|
||||
</select></span><input type="button" id="writeuserafp" value="Write" class="clone" onclick="writeUserAFP()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="afp_user_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writeuserafp',true);$('#afp2').dropdownchecklist('disable')">
|
||||
@@ -187,8 +187,8 @@ foreach ($rows as $row)echo $row;
|
||||
> Select the desired destinations and press **Write** to copy the AFP User access settings to the selected shares.
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left clone"></i>
|
||||
<select name="readuserafp" size="1" class="clone" onchange="toggleButton('readuserafp',false)">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readuserafp" size="1" class="clone" onchange="toggleButton('readuserafp',false)">
|
||||
<option disabled selected>select...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
@@ -197,11 +197,11 @@ if (isset($disks[$name])) {
|
||||
foreach ($shares as $list) if ($list['name']!=$name && $sec_afp[$list['name']]['security']=='private') echo mk_option("", $list['name'], $list['name']);
|
||||
}
|
||||
?>
|
||||
</select><input type="button" id="readuserafp" value="Read" class="clone" onclick="readUserAFP()" disabled>
|
||||
</select></span><input type="button" id="readuserafp" value="Read" class="clone" onclick="readUserAFP()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right clone"></i>
|
||||
<select id="afp2" name="writeuserafp" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeuserafp',this.id)">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="afp2" name="writeuserafp" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeuserafp',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
@@ -212,7 +212,7 @@ if (isset($disks[$name])) {
|
||||
if ($rows) echo "<option>(All)</option>";
|
||||
foreach($rows as $row) echo $row;
|
||||
?>
|
||||
</select><input type="button" id="writeuserafp" value="Write" class="clone" onclick="writeUserAFP()" disabled>
|
||||
</select></span><input type="button" id="writeuserafp" value="Write" class="clone" onclick="writeUserAFP()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="afp_user_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writeuserafp',true);$('#afp2').dropdownchecklist('disable')">
|
||||
@@ -260,21 +260,31 @@ function readAFP() {
|
||||
});
|
||||
$(form).find('select').trigger('change');
|
||||
}
|
||||
function writeAFP() {
|
||||
var data = {}, copied = false;
|
||||
data.shareExportAFP = '<?=addslashes(htmlspecialchars($sec_afp[$name]['export']))?>';
|
||||
data.shareVolsizelimitAFP = '<?=addslashes(htmlspecialchars($sec_afp[$name]['volsizelimit']))?>';
|
||||
data.shareVoldbpathAFP = '<?=addslashes(htmlspecialchars($sec_afp[$name]['voldbpath']))?>';
|
||||
data.shareSecurityAFP = '<?=addslashes(htmlspecialchars($sec_afp[$name]['security']))?>';
|
||||
data.changeShareSecurityAFP = 'Apply';
|
||||
$('select#afp1 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data.shareName = $(this).val();
|
||||
$.post('/update.htm', data);
|
||||
copied = true;
|
||||
function writeAFP(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeAFP(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writeafp',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
});
|
||||
if (copied) swal({title:'Clone complete',text:'AFP security settings are written to the selected shares',type:'success'},function(){refresh();});
|
||||
} else {
|
||||
$('select#afp1 option').map(function(i) {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['shareExportAFP'] = '<?=addslashes(htmlspecialchars($sec_afp[$name]['export']))?>';
|
||||
data[i]['shareVolsizelimitAFP'] = '<?=addslashes(htmlspecialchars($sec_afp[$name]['volsizelimit']))?>';
|
||||
data[i]['shareVoldbpathAFP'] = '<?=addslashes(htmlspecialchars($sec_afp[$name]['voldbpath']))?>';
|
||||
data[i]['shareSecurityAFP'] = '<?=addslashes(htmlspecialchars($sec_afp[$name]['security']))?>';
|
||||
data[i]['changeShareSecurityAFP'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writeafp',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeAFP(data,0,i);
|
||||
}
|
||||
}
|
||||
function readUserAFP() {
|
||||
var form = document.afp_user_edit;
|
||||
@@ -296,32 +306,43 @@ function readUserAFP() {
|
||||
});
|
||||
$(form).find('select').trigger('change');
|
||||
}
|
||||
function writeUserAFP() {
|
||||
var data = {}, copied = false;
|
||||
data['userAccess.0'] = 'no-access';
|
||||
function writeUserAFP(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeUserAFP(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writeuserafp',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$('select#afp2 option').map(function(i) {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['userAccess.0'] = 'no-access';
|
||||
<?
|
||||
$read_list = explode(",", $sec_afp[$name]['readList']);
|
||||
$write_list = explode(",", $sec_afp[$name]['writeList']);
|
||||
foreach ($users as $user) {
|
||||
if ($user['name'] == "root") continue;
|
||||
$idx = $user['idx'];
|
||||
$userAccess = null;
|
||||
if ($sec_afp[$name]['security']=='secure') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : "read-only";
|
||||
} elseif ($sec_afp[$name]['security'] == 'private') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : (in_array($user['name'], $read_list) ? "read-only" : "no-access");
|
||||
}
|
||||
if ($userAccess) echo " data['userAccess.$idx'] = '$userAccess';\n";
|
||||
}
|
||||
$read_list = explode(",", $sec_afp[$name]['readList']);
|
||||
$write_list = explode(",", $sec_afp[$name]['writeList']);
|
||||
foreach ($users as $user) {
|
||||
if ($user['name'] == "root") continue;
|
||||
$idx = $user['idx'];
|
||||
$userAccess = null;
|
||||
if ($sec_afp[$name]['security']=='secure') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : "read-only";
|
||||
} elseif ($sec_afp[$name]['security'] == 'private') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : (in_array($user['name'], $read_list) ? "read-only" : "no-access");
|
||||
}
|
||||
if ($userAccess) echo "data[i]['userAccess.$idx'] = '$userAccess';\n";
|
||||
}
|
||||
?>
|
||||
data.changeShareAccessAFP = 'Apply';
|
||||
$('select#afp2 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data.shareName = $(this).val();
|
||||
$.post('/update.htm', data);
|
||||
copied = true;
|
||||
}
|
||||
});
|
||||
if (copied) swal({title:'Clone complete',text:'AFP User Access settings are written to the selected shares',type:'success'},function(){refresh();});
|
||||
data[i]['changeShareAccessAFP'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writeuserafp',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeUserAFP(data,0,i);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,8 +4,8 @@ Tag="linux"
|
||||
Cond="(($var['shareNFSEnabled']!='no') && (isset($name)?array_key_exists($name,$sec_nfs):0))"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -27,8 +27,8 @@ $width = [123,300];
|
||||
> Select the desired destinations and press **Write** to copy the NFS security settings to the selected shares.
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left clone"></i>
|
||||
<select name="readnfs" size="1" class="clone" onchange="toggleButton('readnfs',false)">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readnfs" size="1" class="clone" onchange="toggleButton('readnfs',false)">
|
||||
<option disabled selected>select...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
@@ -37,11 +37,11 @@ if (isset($disks[$name])) {
|
||||
foreach ($shares as $list) if ($list['name']!=$name) echo mk_option("", $list['name'], $list['name']);
|
||||
}
|
||||
?>
|
||||
</select><input type="button" id="readnfs" value="Read" class="clone" onclick="readNFS()" disabled>
|
||||
</select></span><input type="button" id="readnfs" value="Read" class="clone" onclick="readNFS()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right clone"></i>
|
||||
<select id="nfs1" name="writenfs" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writenfs',this.id)">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="nfs1" name="writenfs" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writenfs',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
@@ -52,7 +52,7 @@ if (isset($disks[$name])) {
|
||||
if ($rows) echo "<option>(All)</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select><input type="button" id="writenfs" value="Write" class="clone" onclick="writeNFS()" disabled>
|
||||
</select></span><input type="button" id="writenfs" value="Write" class="clone" onclick="writeNFS()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="nfs_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writenfs',true);$('#nfs1').dropdownchecklist('disable')">
|
||||
@@ -116,18 +116,29 @@ function readNFS() {
|
||||
});
|
||||
$(form).find('select').trigger('change');
|
||||
}
|
||||
function writeNFS() {
|
||||
var data = {}, copied = false;
|
||||
data.shareExportNFS = '<?=addslashes(htmlspecialchars($sec_nfs[$name]['export']))?>';
|
||||
data.shareSecurityNFS = '<?=addslashes(htmlspecialchars($sec_nfs[$name]['security']))?>';
|
||||
data.changeShareSecurityNFS = 'Apply';
|
||||
$('select#nfs1 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data.shareName = $(this).val();
|
||||
$.post('/update.htm', data);
|
||||
copied = true;
|
||||
function writeNFS(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeNFS(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writenfs',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
});
|
||||
if (copied) swal({title:'Clone complete',text:'NFS security settings are written to the selected shares',type:'success'},function(){refresh();});
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$('select#nfs1 option').map(function(i) {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['shareExportNFS'] = '<?=addslashes(htmlspecialchars($sec_nfs[$name]['export']))?>';
|
||||
data[i]['shareSecurityNFS'] = '<?=addslashes(htmlspecialchars($sec_nfs[$name]['security']))?>';
|
||||
data[i]['changeShareSecurityNFS'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writenfs',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeNFS(data,0,i);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,8 +4,8 @@ Tag="windows"
|
||||
Cond="(($var['shareSMBEnabled']!='no') && (isset($name)?array_key_exists($name,$sec):0))"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -27,8 +27,8 @@ $width = [123,300];
|
||||
> Select the desired destinations and press **Write** to copy the SMB security settings to the selected shares.
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left clone"></i>
|
||||
<select name="readsmb" size="1" class="clone" onchange="toggleButton('readsmb',false)">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readsmb" size="1" class="clone" onchange="toggleButton('readsmb',false)">
|
||||
<option disabled selected>select...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
@@ -37,11 +37,11 @@ if (isset($disks[$name])) {
|
||||
foreach ($shares as $list) if ($list['name']!=$name) echo mk_option("", $list['name'], $list['name']);
|
||||
}
|
||||
?>
|
||||
</select><input type="button" id="readsmb" value="Read" class="clone" onclick="readSMB()" disabled>
|
||||
</select></span><input type="button" id="readsmb" value="Read" class="clone" onclick="readSMB()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right clone"></i>
|
||||
<select id="smb1" name="writesmb" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writesmb',this.id)">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="smb1" name="writesmb" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writesmb',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
@@ -52,7 +52,7 @@ if (isset($disks[$name])) {
|
||||
if ($rows) echo "<option>(All)</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select><input type="button" id="writesmb" value="Write" class="clone" onclick="writeSMB()" disabled>
|
||||
</select></span><input type="button" id="writesmb" value="Write" class="clone" onclick="writeSMB()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="smb_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writesmb',true);$('#smb1').dropdownchecklist('disable')">
|
||||
@@ -126,8 +126,8 @@ Security:
|
||||
> Select the desired destinations and press **Write** to copy the SMB User access settings to the selected shares.
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left clone"></i>
|
||||
<select name="readusersmb" size="1" class="clone" onchange="toggleButton('readusersmb',false)">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readusersmb" size="1" class="clone" onchange="toggleButton('readusersmb',false)">
|
||||
<option disabled selected>select...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
@@ -136,11 +136,11 @@ if (isset($disks[$name])) {
|
||||
foreach ($shares as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='secure') echo mk_option("", $list['name'], $list['name']);
|
||||
}
|
||||
?>
|
||||
</select><input type="button" id="readusersmb" value="Read" class="clone" onclick="readUserSMB()" disabled>
|
||||
</select></span><input type="button" id="readusersmb" value="Read" class="clone" onclick="readUserSMB()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right clone"></i>
|
||||
<select id="smb2" name="writeusersmb" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeusersmb',this.id)">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="smb2" name="writeusersmb" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeusersmb',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
@@ -151,7 +151,7 @@ if (isset($disks[$name])) {
|
||||
if ($rows) echo "<option>(All)</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select><input type="button" id="writeusersmb" value="Write" class="clone" onclick="writeUserSMB()" disabled>
|
||||
</select></span><input type="button" id="writeusersmb" value="Write" class="clone" onclick="writeUserSMB()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="smb_user_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writeusersmb',true);$('#smb2').dropdownchecklist('disable')">
|
||||
@@ -174,8 +174,8 @@ foreach ($rows as $row) echo $row;
|
||||
> Select the desired destinations and press **Write** to copy the SMB User access settings to the selected shares.
|
||||
|
||||
<div class="clone1">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left clone"></i>
|
||||
<select name="readusersmb" size="1" class="clone" onchange="toggleButton('readusersmb',false)">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readusersmb" size="1" class="clone" onchange="toggleButton('readusersmb',false)">
|
||||
<option disabled selected>select...</option>
|
||||
<?
|
||||
if (isset($disks[$name])) {
|
||||
@@ -184,11 +184,11 @@ if (isset($disks[$name])) {
|
||||
foreach ($shares as $list) if ($list['name']!=$name && $sec[$list['name']]['security']=='private') echo mk_option("", $list['name'], $list['name']);
|
||||
}
|
||||
?>
|
||||
</select><input type="button" id="readusersmb" value="Read" class="clone" onclick="readUserSMB()" disabled>
|
||||
</select></span><input type="button" id="readusersmb" value="Read" class="clone" onclick="readUserSMB()" disabled>
|
||||
</div>
|
||||
<div class="clone2">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right clone"></i>
|
||||
<select id="smb2" name="writeusersmb" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeusersmb',this.id)">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="smb2" name="writeusersmb" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeusersmb',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
if (isset($disks[$name])) {
|
||||
@@ -199,7 +199,7 @@ if (isset($disks[$name])) {
|
||||
if ($rows) echo "<option>(All)</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select><input type="button" id="writeusersmb" value="Write" class="clone" onclick="writeUserSMB()" disabled>
|
||||
</select></span><input type="button" id="writeusersmb" value="Write" class="clone" onclick="writeUserSMB()" disabled>
|
||||
</div>
|
||||
|
||||
<form markdown="1" name="smb_user_edit" method="POST" action="/update.htm" target="progressFrame" onchange="toggleButton('writeusersmb',true);$('#smb2').dropdownchecklist('disable')">
|
||||
@@ -246,20 +246,31 @@ function readSMB() {
|
||||
});
|
||||
$(form).find('select').trigger('change');
|
||||
}
|
||||
function writeSMB() {
|
||||
var data = {}, copied = false;
|
||||
data.shareExport = '<?=addslashes(htmlspecialchars($sec[$name]['export']))?>';
|
||||
data.shareFruit = '<?=addslashes(htmlspecialchars($sec[$name]['fruit']))?>';
|
||||
data.shareSecurity = '<?=addslashes(htmlspecialchars($sec[$name]['security']))?>';
|
||||
data.changeShareSecurity = 'Apply';
|
||||
$('select#smb1 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data.shareName = $(this).val();
|
||||
$.post('/update.htm', data);
|
||||
copied = true;
|
||||
function writeSMB(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeSMB(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writesmb',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
});
|
||||
if (copied) swal({title:'Clone complete',text:'SMB security settings are written to the selected shares',type:'success'},function(){refresh();});
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$('select#smb1 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['shareExport'] = '<?=addslashes(htmlspecialchars($sec[$name]['export']))?>';
|
||||
data[i]['shareFruit'] = '<?=addslashes(htmlspecialchars($sec[$name]['fruit']))?>';
|
||||
data[i]['shareSecurity'] = '<?=addslashes(htmlspecialchars($sec[$name]['security']))?>';
|
||||
data[i]['changeShareSecurity'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writesmb',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeSMB(data,0,i);
|
||||
}
|
||||
}
|
||||
function readUserSMB() {
|
||||
var form = document.smb_user_edit;
|
||||
@@ -281,32 +292,43 @@ function readUserSMB() {
|
||||
});
|
||||
$(form).find('select').trigger('change');
|
||||
}
|
||||
function writeUserSMB() {
|
||||
var data = {}, copied = false;
|
||||
data['userAccess.0'] = 'no-access';
|
||||
function writeUserSMB(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeUserSMB(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writeusersmb',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$('select#smb2 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['userAccess.0'] = 'no-access';
|
||||
<?
|
||||
$read_list = explode(",", $sec[$name]['readList']);
|
||||
$write_list = explode(",", $sec[$name]['writeList']);
|
||||
foreach ($users as $user) {
|
||||
if ($user['name'] == "root") continue;
|
||||
$idx = $user['idx'];
|
||||
$userAccess = null;
|
||||
if ($sec[$name]['security']=='secure') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : "read-only";
|
||||
} elseif ($sec[$name]['security'] == 'private') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : (in_array($user['name'], $read_list) ? "read-only" : "no-access");
|
||||
}
|
||||
if ($userAccess) echo " data['userAccess.$idx'] = '$userAccess';\n";
|
||||
}
|
||||
$read_list = explode(",", $sec[$name]['readList']);
|
||||
$write_list = explode(",", $sec[$name]['writeList']);
|
||||
foreach ($users as $user) {
|
||||
if ($user['name'] == "root") continue;
|
||||
$idx = $user['idx'];
|
||||
$userAccess = null;
|
||||
if ($sec[$name]['security']=='secure') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : "read-only";
|
||||
} elseif ($sec[$name]['security'] == 'private') {
|
||||
$userAccess = in_array($user['name'], $write_list) ? "read-write" : (in_array($user['name'], $read_list) ? "read-only" : "no-access");
|
||||
}
|
||||
if ($userAccess) echo "data[i]['userAccess.$idx'] = '$userAccess';\n";
|
||||
}
|
||||
?>
|
||||
data.changeShareAccess = 'Apply';
|
||||
$('select#smb2 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data.shareName = $(this).val();
|
||||
$.post('/update.htm', data);
|
||||
copied = true;
|
||||
}
|
||||
});
|
||||
if (copied) swal({title:'Clone complete',text:'SMB User Access settings are written to the selected shares',type:'success'},function(){refresh();});
|
||||
data[i]['changeShareAccess'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writeusersmb',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeUserSMB(data,0,i);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Type="xmenu"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -36,9 +36,15 @@ if ($name) {
|
||||
<style>
|
||||
div.clone1{position:absolute;right:0;margin-top:0}
|
||||
div.clone2{position:absolute;right:0;margin-top:48px}
|
||||
select.clone{min-width:132px;margin-right:0}
|
||||
<?if ($themes1):?>
|
||||
span.wrap{display:inline-block;width:128px}
|
||||
select.clone{min-width:123px;margin-right:0}
|
||||
<?else:?>
|
||||
span.wrap{display:inline-block;width:150px}
|
||||
select.clone{min-width:145px;margin-right:0}
|
||||
<?endif;?>
|
||||
input.clone{margin-left:8px;margin-right:0}
|
||||
span.clone,i.clone{margin-right:4px}
|
||||
span.clone{margin-right:4px}
|
||||
</style>
|
||||
<script>
|
||||
function toggleButton(button,id) {
|
||||
@@ -53,6 +59,7 @@ function toggleButton(button,id) {
|
||||
}
|
||||
$('input#'+button).prop('disabled',disabled);
|
||||
}
|
||||
|
||||
<?if ($name):?>
|
||||
var ctrl = "<span class='ctrl1 status <?=$tabbed?'vhshift':'vshift'?>'><a href='/Shares/Share?name=<?=$prev?>' title='previous user share'><button type='button' style='margin-right:4px'><i class='fa fa-chevron-left fa-fw'></i></button></a><a href='/Shares/Share?name=<?=$next?>' title='next user share'><button type='button'><i class='fa fa-chevron-right fa-fw'></i></button></a></span>";
|
||||
|
||||
|
||||
@@ -3,8 +3,8 @@ Title="Share Settings"
|
||||
Tag="share-alt-square"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2019, Lime Technology
|
||||
* Copyright 2012-2019, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -67,25 +67,25 @@ $myDisks = array_filter(array_diff(array_keys($disks), explode(',',$var['shareUs
|
||||
<?endif;?>
|
||||
|
||||
<div id="" class="clone1">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left clone"></i>
|
||||
<select name="readshare" size="1" class="clone" onchange="toggleButton('readshare',false)">
|
||||
<span class="clone">Read settings from</span><i class="fa fa-arrow-left fa-fw"></i>
|
||||
<span class="wrap"><select name="readshare" size="1" class="clone" onchange="toggleButton('readshare',false)">
|
||||
<option disabled selected>select...</option>
|
||||
<?
|
||||
foreach ($shares as $list) if ($list['name']!=$name || !$name) echo mk_option("", $list['name'], $list['name']);
|
||||
?>
|
||||
</select><input type="button" id="readshare" value="Read" class="clone" onclick="readShare()" disabled>
|
||||
</select></span><input type="button" id="readshare" value="Read" class="clone" onclick="readShare()" disabled>
|
||||
</div>
|
||||
<?if ($name):?>
|
||||
<div id="" class="clone2">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right clone"></i>
|
||||
<select id="s3" name="writeshare" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeshare',this.id)">
|
||||
<span class="clone">Write settings to</span><i class="fa fa-arrow-right fa-fw"></i>
|
||||
<span class="wrap"><select id="s3" name="writeshare" size="1" multiple="multiple" style="display:none" onchange="toggleButton('writeshare',this.id)">
|
||||
<?
|
||||
$rows = [];
|
||||
foreach ($shares as $list) if ($list['name']!=$name) $rows[] = mk_option("", $list['name'], $list['name']);
|
||||
if ($rows) echo "<option>(All)</option>";
|
||||
foreach ($rows as $row) echo $row;
|
||||
?>
|
||||
</select><input type="button" id="writeshare" value="Write" class="clone" onclick="writeShare()" disabled>
|
||||
</select></span><input type="button" id="writeshare" value="Write" class="clone" onclick="writeShare()" disabled>
|
||||
</div>
|
||||
<?endif;?>
|
||||
|
||||
@@ -372,23 +372,34 @@ function readShare() {
|
||||
});
|
||||
$(form).find('select').trigger('change');
|
||||
}
|
||||
function writeShare() {
|
||||
var data = {}, copied = false;
|
||||
data.shareAllocator = '<?=addslashes(htmlspecialchars($share['allocator']))?>';
|
||||
data.shareFloor = '<?=addslashes(htmlspecialchars($share['floor']))?>';
|
||||
data.shareSplitLevel = '<?=addslashes(htmlspecialchars($share['splitLevel']))?>';
|
||||
data.shareInclude = '<?=addslashes(htmlspecialchars($share['include']))?>';
|
||||
data.shareExclude = '<?=addslashes(htmlspecialchars($share['exclude']))?>';
|
||||
data.shareUseCache = '<?=addslashes(htmlspecialchars($share['useCache']))?>';
|
||||
data.cmdEditShare = 'Apply';
|
||||
$('select#s3 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data.shareNameOrig = $(this).val();
|
||||
data.shareName = $(this).val();
|
||||
$.post('/update.htm', data);
|
||||
copied = true;
|
||||
function writeShare(data,n,i) {
|
||||
if (data) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){writeShare(data,++n,i);},3000);});
|
||||
} else {
|
||||
toggleButton('writeshare',false);
|
||||
$('div.spinner.fixed').hide();
|
||||
}
|
||||
});
|
||||
if (copied) swal({title:'Clone complete',text:'Share settings are cloned to the selected shares',type:'success'},function(){refresh();});
|
||||
} else {
|
||||
var data = [], i = 0;
|
||||
$('select#s3 option').map(function() {
|
||||
if ($(this).prop('selected')==true && $(this).val()!='(All)') {
|
||||
data[i] = {};
|
||||
data[i]['shareName'] = $(this).val();
|
||||
data[i]['shareNameOrig'] = $(this).val();
|
||||
data[i]['shareAllocator'] = '<?=addslashes(htmlspecialchars($share['allocator']))?>';
|
||||
data[i]['shareFloor'] = '<?=addslashes(htmlspecialchars($share['floor']))?>';
|
||||
data[i]['shareSplitLevel'] = '<?=addslashes(htmlspecialchars($share['splitLevel']))?>';
|
||||
data[i]['shareInclude'] = '<?=addslashes(htmlspecialchars($share['include']))?>';
|
||||
data[i]['shareExclude'] = '<?=addslashes(htmlspecialchars($share['exclude']))?>';
|
||||
data[i]['shareUseCache'] = '<?=addslashes(htmlspecialchars($share['useCache']))?>';
|
||||
data[i]['cmdEditShare'] = 'Apply';
|
||||
i++;
|
||||
}
|
||||
});
|
||||
toggleButton('writeshare',true);
|
||||
$('div.spinner.fixed').show('slow');
|
||||
writeShare(data,0,i);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -4,8 +4,8 @@ Icon="icon-log"
|
||||
Tag="list"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -77,28 +77,26 @@ function toggle(checked) {
|
||||
function resize() {
|
||||
$('pre.up').height(Math.max(window.innerHeight-320,330));
|
||||
}
|
||||
function showLog(log) {
|
||||
function showLog(log,init) {
|
||||
logfile = log;
|
||||
$('span.label input[type=checkbox]').prop('checked',true);
|
||||
$('span.label').each(function(){
|
||||
var type = $(this).attr('class').replace('label','').replace(/-/g,'');
|
||||
$(this).removeClass().addClass(type+' label');
|
||||
});
|
||||
timers.syslog = setTimeout(function(){$('div.spinner.fixed').show('slow');},150);
|
||||
$.post('/webGui/include/Syslog.php',{log:log},function(data){
|
||||
clearTimeout(timers.syslog);
|
||||
$('pre.up').html(data);
|
||||
<?if ($display['resize']):?>
|
||||
resize();
|
||||
if (init) $(window).bind('resize',function(){resize();});
|
||||
<?endif;?>
|
||||
$('div.spinner.fixed').hide('slow');
|
||||
});
|
||||
}
|
||||
$(function() {
|
||||
$.post('/webGui/include/Syslog.php',{log:'<?=$log?>'},function(data){
|
||||
$('pre.up').html(data);
|
||||
<?if ($display['resize']):?>
|
||||
resize();
|
||||
$(window).bind('resize',function(){resize();});
|
||||
<?endif;?>
|
||||
});
|
||||
showLog(logfile,true);
|
||||
});
|
||||
$('.tabs').append("<span class='status'><?=$select?><span class='lite label'><label>Text<input type='checkbox' class='ctrl' onclick='highlight(!this.checked,\"N\")' checked></label></span><span class='error label'><label>Error<input type='checkbox' onclick='highlight(this.checked,\"E\")' checked></label></span><span class='warn label'><label>Warning<input type='checkbox' onclick='highlight(this.checked,\"W\")' checked></label></span><span class='system label'><label>System<input type='checkbox' onclick='highlight(this.checked,\"S\")' checked></label></span><span class='array label'><label>Array<input type='checkbox' onclick='highlight(this.checked,\"A\")' checked></label></span><span class='login label'><label>Login<input type='checkbox' onclick='highlight(this.checked,\"L\")' checked></label></span><span class='lite label'><input type='checkbox' class='ctrl' onclick='toggle(this.checked)' checked></span></span>");
|
||||
</script>
|
||||
|
||||
@@ -4,8 +4,8 @@ Icon="icon-eula"
|
||||
Tag="file-text-o"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2018, Lime Technology
|
||||
* Copyright 2012-2018, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -40,7 +40,7 @@ $(function(){
|
||||
<input type="hidden" name="#command" value="/webGui/scripts/rsyslog_config">
|
||||
|
||||
Local syslog server:
|
||||
: <span class="span"><select name="local_server" class="narrow" onchange="localFolder(this.value,'slow')">
|
||||
: <span class="span"><select name="local_server" onchange="localFolder(this.value,'slow')">
|
||||
<?=mk_option($syslog['local_server'], "", "Disabled")?>
|
||||
<?=mk_option($syslog['local_server'], "1", "Enabled")?>
|
||||
</select></span>
|
||||
@@ -58,7 +58,7 @@ Local syslog server:
|
||||
|
||||
<div markdown="1" id="local_folder" style="display:none">
|
||||
Local syslog folder:
|
||||
: <select name="server_folder" class="narrow">
|
||||
: <select name="server_folder">
|
||||
<?=mk_option(0,'','<custom>','disabled')?>
|
||||
<?foreach ($shares as $share){echo mk_option($syslog['server_folder'], '/mnt/user/'.$share['name'], $share['name']);}?>
|
||||
</select>
|
||||
@@ -67,7 +67,7 @@ Local syslog folder:
|
||||
> It is recommended that you use a share located on the cache drive to prevent array disk spinups.
|
||||
|
||||
Local syslog rotation:
|
||||
: <select name="log_rotation" class="narrow" onchange="logOptions(this.value,'slow')">
|
||||
: <select name="log_rotation" onchange="logOptions(this.value,'slow')">
|
||||
<?=mk_option($syslog['log_rotation'], "", "Disabled")?>
|
||||
<?=mk_option($syslog['log_rotation'], "1", "Enabled")?>
|
||||
</select>
|
||||
@@ -78,7 +78,7 @@ Local syslog rotation:
|
||||
|
||||
<div markdown="1" id="log_options" style="display:none">
|
||||
Local syslog maximum file size:
|
||||
: <select name="log_size" class="narrow">
|
||||
: <select name="log_size">
|
||||
<?=mk_option($syslog['log_size'], '1M', '1 MB')?>
|
||||
<?=mk_option($syslog['log_size'], '2M', '2 MB')?>
|
||||
<?=mk_option($syslog['log_size'], '5M', '5 MB')?>
|
||||
@@ -93,7 +93,7 @@ Local syslog maximum file size:
|
||||
> Specifies the maximum LOG size. When exceeded LOG rotation will occur.
|
||||
|
||||
Local syslog number of files:
|
||||
: <select name="log_files" class="narrow">
|
||||
: <select name="log_files">
|
||||
<?=mk_option($syslog['log_files'], '1', '1')?>
|
||||
<?=mk_option($syslog['log_files'], '2', '2')?>
|
||||
<?=mk_option($syslog['log_files'], '3', '3')?>
|
||||
@@ -117,7 +117,7 @@ Remote syslog server:
|
||||
> This will send a copy of the syslog messages to the designated server.
|
||||
|
||||
Mirror syslog to flash:
|
||||
: <select name="syslog_flash" class="narrow" size="1">
|
||||
: <select name="syslog_flash" size="1">
|
||||
<?=mk_option($syslog['syslog_flash'], "", "No")?>
|
||||
<?=mk_option($syslog['syslog_flash'], "1", "Yes")?>
|
||||
</select>
|
||||
|
||||
@@ -3,8 +3,8 @@ Title="Edit User"
|
||||
Tag="user"
|
||||
---
|
||||
<?PHP
|
||||
/* Copyright 2005-2019, Lime Technology
|
||||
* Copyright 2012-2019, Bergware International.
|
||||
/* Copyright 2005-2020, Lime Technology
|
||||
* Copyright 2012-2020, Bergware International.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License version 2,
|
||||
@@ -198,12 +198,11 @@ function updateAccess(form,data,n,i) {
|
||||
if (n<i) {
|
||||
$.post('/update.htm',data[n], function(){setTimeout(function(){updateAccess(form,data,++n,i);},3000);});
|
||||
} else {
|
||||
$('div.spinner').html(unraid_logo).hide();
|
||||
$('div.spinner.fixed').hide();
|
||||
$('input[value="Reset"]').val('Done').prop('disabled',false).prop('onclick',null).off('click').click(function(){done('UserEdit');});
|
||||
}
|
||||
} else {
|
||||
var data = [];
|
||||
var i = 0;
|
||||
var data = [], i = 0;
|
||||
$(form).find('select').each(function(){
|
||||
if ($(this).prop('id')) {
|
||||
var share = decodeURI($(this).prop('id'));
|
||||
@@ -235,7 +234,7 @@ function updateAccess(form,data,n,i) {
|
||||
}
|
||||
});
|
||||
$(form).find('input').prop('disabled',true);
|
||||
$('div.spinner').html(unraid_logo).show();
|
||||
$('div.spinner.fixed').show();
|
||||
updateAccess(form,data,0,i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,19 +88,19 @@ var before = new Date();
|
||||
// page timer events
|
||||
var timers = {};
|
||||
|
||||
function pauseEvents(id){
|
||||
$.each(timers, function(i, timer) {
|
||||
function pauseEvents(id) {
|
||||
$.each(timers, function(i,timer){
|
||||
if (!id || i==id) clearTimeout(timer);
|
||||
});
|
||||
}
|
||||
function resumeEvents(id,delay){
|
||||
function resumeEvents(id,delay) {
|
||||
var startDelay = delay||50;
|
||||
$.each(timers, function(i, timer) {
|
||||
$.each(timers, function(i,timer) {
|
||||
if (!id || i==id) timers[i] = setTimeout(i+'()', startDelay);
|
||||
startDelay += 50;
|
||||
});
|
||||
}
|
||||
function plus(value, label, last) {
|
||||
function plus(value,label,last) {
|
||||
return value>0 ? (value+' '+label+(value!=1?'s':'')+(last?'':', ')) : '';
|
||||
}
|
||||
function updateTime() {
|
||||
@@ -222,21 +222,14 @@ var osUpgradeWarning = false;
|
||||
|
||||
function addBannerWarning(text,warning=true,noDismiss=false) {
|
||||
var cookieText = text.replace(/[^a-z0-9]/gi,'');
|
||||
if ( $.cookie(cookieText) == "true" ) { return false; }
|
||||
|
||||
if ( warning ) {
|
||||
text = "<i class='fa fa-warning' style='float:initial;'></i> "+text;
|
||||
}
|
||||
if ($.cookie(cookieText) == "true") return false;
|
||||
if (warning) text = "<i class='fa fa-warning' style='float:initial;'></i> "+text;
|
||||
var arrayEntry = bannerWarnings.push("placeholder") - 1;
|
||||
if ( ! noDismiss ) {
|
||||
text = text + "<a class='bannerDismiss' onclick='dismissBannerWarning("+arrayEntry+",""+cookieText+"")'></a>";
|
||||
}
|
||||
if (!noDismiss) text = text + "<a class='bannerDismiss' onclick='dismissBannerWarning("+arrayEntry+",""+cookieText+"")'></a>";
|
||||
bannerWarnings[arrayEntry] = text;
|
||||
if ( ! bannerWarningInterval ) {
|
||||
if (!bannerWarningInterval) {
|
||||
showBannerWarnings();
|
||||
bannerWarningInterval = setInterval(function() {
|
||||
showBannerWarnings()
|
||||
},10000);
|
||||
bannerWarningInterval = setInterval(showBannerWarnings,10000);
|
||||
}
|
||||
return arrayEntry;
|
||||
}
|
||||
@@ -254,33 +247,28 @@ function removeBannerWarning(entry) {
|
||||
function bannerFilterArray(array) {
|
||||
var newArray = [];
|
||||
array.filter(function(value,index,arr) {
|
||||
if ( value ) {
|
||||
newArray.push(value);
|
||||
}
|
||||
});
|
||||
if (value) newArray.push(value);
|
||||
});
|
||||
return newArray;
|
||||
}
|
||||
|
||||
function showBannerWarnings() {
|
||||
var allWarnings = bannerFilterArray(Object.values(bannerWarnings));
|
||||
if ( allWarnings.length == 0 ) {
|
||||
if (allWarnings.length == 0) {
|
||||
$(".upgrade_notice").hide();
|
||||
clearInterval(bannerWarningInterval);
|
||||
bannerWarningInterval = false;
|
||||
return;
|
||||
}
|
||||
if ( currentBannerWarning >= allWarnings.length ) {
|
||||
currentBannerWarning = 0;
|
||||
}
|
||||
if (currentBannerWarning >= allWarnings.length) currentBannerWarning = 0;
|
||||
$(".upgrade_notice").show().html(allWarnings[currentBannerWarning]);
|
||||
currentBannerWarning++;
|
||||
}
|
||||
|
||||
function showUpgrade(data,noDismiss=false) {
|
||||
function showUpgrade(text,noDismiss=false) {
|
||||
if ($.cookie('os_upgrade')==null) {
|
||||
if (osUpgradeWarning)
|
||||
removeBannerWarning(osUpgradeWarning);
|
||||
osUpgradeWarning = addBannerWarning(data.replace(/<a>(.*)<\/a>/,"<a href='#' onclick='hideUpgrade();openUpgrade();'>$1</a>"),false,noDismiss);
|
||||
if (osUpgradeWarning) removeBannerWarning(osUpgradeWarning);
|
||||
osUpgradeWarning = addBannerWarning(text.replace(/<a>(.*)<\/a>/,"<a href='#' onclick='openUpgrade()'>$1</a>").replace(/<b>(.*)<\/b>/,"<a href='#' onclick='document.rebootNow.submit()'>$1</a>"),false,noDismiss);
|
||||
}
|
||||
}
|
||||
function hideUpgrade(set) {
|
||||
@@ -291,6 +279,7 @@ function hideUpgrade(set) {
|
||||
$.removeCookie('os_upgrade',{path:'/'});
|
||||
}
|
||||
function openUpgrade() {
|
||||
hideUpgrade();
|
||||
swal({title:'Update Unraid OS',text:'Do you want to update to the new version?',type:'warning',showCancelButton:true},function(){
|
||||
openBox('/plugins/dynamix.plugin.manager/scripts/plugin&arg1=update&arg2=unRAIDServer.plg','Update Unraid OS',600,900,true);
|
||||
});
|
||||
@@ -502,6 +491,7 @@ unset($pages,$page,$pgs,$pg,$icon);
|
||||
?>
|
||||
</div></div>
|
||||
<div class="spinner fixed"></div>
|
||||
<form name="rebootNow" method="POST" action="/webGui/include/Boot.php"><input type="hidden" name="cmd" value="reboot"></form>
|
||||
<iframe id="progressFrame" name="progressFrame" frameborder="0"></iframe>
|
||||
<?
|
||||
// Build footer
|
||||
@@ -605,6 +595,8 @@ $('.back_to_top').click(function(event) {
|
||||
return false;
|
||||
});
|
||||
$(function() {
|
||||
$('div.spinner.fixed').html(unraid_logo);
|
||||
setTimeout(function(){$('div.spinner').not('.fixed').each(function(){$(this).html(unraid_logo);});},150); // display animation if page loading takes longer than 150ms
|
||||
shortcut.add('F1',function(){HelpButton();});
|
||||
<?if ($var['regTy']=='unregistered'):?>
|
||||
$('#licensetype').addClass('orange-text');
|
||||
@@ -629,9 +621,9 @@ $(function() {
|
||||
<?else:?>
|
||||
<?$readme = @file_get_contents("$docroot/plugins/unRAIDServer/README.md",false,null,0,20);?>
|
||||
<?if (strpos($readme,'REBOOT REQUIRED')!==false):?>
|
||||
showUpgrade('<b>Reboot required</b> to apply Unraid OS update',true);
|
||||
showUpgrade('<b>Reboot Now</b> to upgrade Unraid OS',true);
|
||||
<?elseif (strpos($readme,'DOWNGRADE')!==false):?>
|
||||
showUpgrade('<b>Reboot required</b> to downgrade Unraid OS',true);
|
||||
showUpgrade('<b>Reboot Now</b> to downgrade Unraid OS',true);
|
||||
<?elseif ($version = plugin_update_available('unRAIDServer',true)):?>
|
||||
showUpgrade('Unraid OS v<?=$version?> is available. <a>Update Now</a>');
|
||||
<?endif;?>
|
||||
@@ -690,7 +682,6 @@ $(function() {
|
||||
});
|
||||
}
|
||||
$('form').append($('<input>').attr({type:'hidden', name:'csrf_token', value:'<?=$var['csrf_token']?>'}));
|
||||
setTimeout(function(){$('div.spinner').each(function(){$(this).html(unraid_logo);});},150); // display animation if page loading takes longer than 150ms
|
||||
watchdog.start();
|
||||
});
|
||||
</script>
|
||||
|
||||
@@ -139,9 +139,10 @@ table.array_status tr>td+td+td{width:auto}
|
||||
table.array_status td.line{border-top:1px solid #f3f0f4}
|
||||
table.settings{padding-top:8px;line-height:4.2rem}
|
||||
table.settings td:first-child{width:35%;padding-left:12px}
|
||||
table.settings td+td{padding-left:8px}
|
||||
table.settings tr>td+td{line-height:1.6rem}
|
||||
table.settings.shifted{padding:0;margin-left:0;margin-top:0}
|
||||
table.settings.shifted td:first-child{padding-left:0}
|
||||
table.settings.shifted td{padding-left:0}
|
||||
table.share_status{white-space:nowrap;margin-top:12px}
|
||||
table.share_status thead tr:first-child td{font-size:1.2rem;letter-spacing:1px;text-transform:uppercase;color:#9794a0;border-bottom:1px solid #606e7f}
|
||||
table.share_status tr>td{text-align:left;padding-left:12px}
|
||||
|
||||
@@ -131,10 +131,11 @@ table.array_status tr>td+td{padding-left:2px;width:20%}
|
||||
table.array_status tr>td+td+td{width:auto}
|
||||
table.array_status td.line{border-top:1px solid #2b2b2b}
|
||||
table.array_status.noshift{margin-top:0}
|
||||
table.settings{margin:0;padding:0}
|
||||
table.settings{margin:0;padding:0;background-color:transparent}
|
||||
table.settings td:first-child{width:35%;padding-left:12px}
|
||||
table.settings td+td{padding-left:8px}
|
||||
table.settings.shifted{padding:0;margin-left:0;margin-top:0}
|
||||
table.settings.shifted td:first-child{padding-left:0}
|
||||
table.settings.shifted td{padding-left:0}
|
||||
table.access_list{border-spacing:0;margin-top:10px;border:none}
|
||||
table.access_list tr:first-child td{font-size:1.1rem;text-transform:uppercase;letter-spacing:1px;vertical-align:middle;text-align:left;border:1px solid #2b2b2b;border-bottom:1px solid #2b2b2b;background-color:#262626}
|
||||
table.access_list td:first-child{font-weight:normal;width:35%;padding-left:12px}
|
||||
@@ -235,7 +236,7 @@ span.label{font-size:1.2rem;padding:2px 0 2px 6px;margin-right:6px;border-radius
|
||||
span.cpu-speed{display:block;color:#3b5998}
|
||||
span.status{float:right;font-size:1.4rem;margin-top:30px;padding-right:8px;letter-spacing:1.8px}
|
||||
span.status.vhshift{margin-top:0;margin-right:0}
|
||||
span.status.vshift{margin-top:-18px}
|
||||
span.status.vshift{margin-top:-16px}
|
||||
span.status.hshift{margin-right:-20px}
|
||||
span.diskinfo{float:left;clear:both;margin-top:5px;padding-left:10px}
|
||||
span.bitstream{font-family:bitstream;font-size:1.1rem}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
@font-face{font-family:clear-sans;font-weight:normal;font-style:normal;
|
||||
src:url('clear-sans.eot?20191026');src:url('clear-sans.eot?20191026#iefix') format('embedded-opentype'),url('clear-sans.woff?20191026') format('woff'),url('clear-sans.ttf?20191026') format('truetype'),url('clear-sans.svg?20191026#clear-sans') format('svg')}
|
||||
src:url('clear-sans.eot?20200211');src:url('clear-sans.eot?20200211#iefix') format('embedded-opentype'),url('clear-sans.woff?20200211') format('woff'),url('clear-sans.ttf?20200211') format('truetype'),url('clear-sans.svg?20200211#clear-sans') format('svg')}
|
||||
@font-face{font-family:clear-sans;font-weight:bold;font-style:normal;
|
||||
src:url('clear-sans-bold.eot?20191026');src:url('clear-sans-bold.eot?20191026?#iefix') format('embedded-opentype'),url('clear-sans-bold.woff?20191026') format('woff'),url('clear-sans-bold.ttf?20191026') format('truetype'),url('clear-sans-bold.svg?20191026#clear-sans-bold') format('svg')}
|
||||
src:url('clear-sans-bold.eot?20200211');src:url('clear-sans-bold.eot?20200211?#iefix') format('embedded-opentype'),url('clear-sans-bold.woff?20200211') format('woff'),url('clear-sans-bold.ttf?20200211') format('truetype'),url('clear-sans-bold.svg?20200211#clear-sans-bold') format('svg')}
|
||||
@font-face{font-family:clear-sans;font-weight:normal;font-style:italic;
|
||||
src:url('clear-sans-italic.eot?20191026');src:url('clear-sans-italic.eot?20191026?#iefix') format('embedded-opentype'),url('clear-sans-italic.woff?20191026') format('woff'),url('clear-sans-italic.ttf?20191026') format('truetype'),url('clear-sans-italic.svg?20191026#clear-sans-italic') format('svg')}
|
||||
src:url('clear-sans-italic.eot?20200211');src:url('clear-sans-italic.eot?20200211?#iefix') format('embedded-opentype'),url('clear-sans-italic.woff?20200211') format('woff'),url('clear-sans-italic.ttf?20200211') format('truetype'),url('clear-sans-italic.svg?20200211#clear-sans-italic') format('svg')}
|
||||
@font-face{font-family:clear-sans;font-weight:bold;font-style:italic;
|
||||
src:url('clear-sans-bold-italic.eot?20191026');src:url('clear-sans-bold-italic.eot?20191026?#iefix') format('embedded-opentype'),url('clear-sans-bold-italic.woff?20191026') format('woff'),url('clear-sans-bold-italic.ttf?20191026') format('truetype'),url('clear-sans-bold-italic.svg?20191026#clear-sans-bold-italic') format('svg')}
|
||||
src:url('clear-sans-bold-italic.eot?20200211');src:url('clear-sans-bold-italic.eot?20200211?#iefix') format('embedded-opentype'),url('clear-sans-bold-italic.woff?20200211') format('woff'),url('clear-sans-bold-italic.ttf?20200211') format('truetype'),url('clear-sans-bold-italic.svg?20200211#clear-sans-bold-italic') format('svg')}
|
||||
|
||||
@font-face{font-family:bitstream;font-weight:normal;font-style:normal;
|
||||
src:url('bitstream.eot?20191026');src:url('bitstream.eot?20191026?#iefix') format('embedded-opentype'),url('bitstream.woff?20191026') format('woff'),url('bitstream.ttf?20191026') format('truetype'),url('bitstream.svg?20191026#bitstream') format('svg')}
|
||||
src:url('bitstream.eot?20200211');src:url('bitstream.eot?20200211?#iefix') format('embedded-opentype'),url('bitstream.woff?20200211') format('woff'),url('bitstream.ttf?20200211') format('truetype'),url('bitstream.svg?20200211#bitstream') format('svg')}
|
||||
|
||||
@font-face{font-family:docker-icon;font-weight:normal;font-style:normal;
|
||||
src:url('docker-icon.eot?20191026');src:url('docker-icon.eot?20191026?#iefix') format('embedded-opentype'),url('docker-icon.woff?20191026') format('woff'),url('docker-icon.ttf?20191026') format('truetype'),url('docker-icon.svg?20191026#docker-icon') format('svg')}
|
||||
src:url('docker-icon.eot?20200211');src:url('docker-icon.eot?20200211?#iefix') format('embedded-opentype'),url('docker-icon.woff?20200211') format('woff'),url('docker-icon.ttf?20200211') format('truetype'),url('docker-icon.svg?20200211#docker-icon') format('svg')}
|
||||
[data-icon]:before{content:attr(data-icon)}
|
||||
[data-icon]:before,.fa-docker:before{font-family:docker-icon!important;content:'\f100'}
|
||||
|
||||
@font-face{font-family:unraid;font-weight:normal;font-style:normal;
|
||||
src:url('font-unraid.eot?20191026');src:url('font-unraid.eot?20191026#iefix') format('embedded-opentype'),url('font-unraid.ttf?20191026') format('truetype'),url('font-unraid.woff?20191026') format('woff'),url('font-unraid.svg?20191026#unraid') format('svg')}
|
||||
src:url('font-unraid.eot?20200211');src:url('font-unraid.eot?20200211#iefix') format('embedded-opentype'),url('font-unraid.ttf?20200211') format('truetype'),url('font-unraid.woff?20200211') format('woff'),url('font-unraid.svg?20200211#unraid') format('svg')}
|
||||
[class^='icon-'],[class*=' icon-']{font-family:unraid!important;speak:none;font-style:normal;font-weight:normal;font-variant:normal;text-transform:none}
|
||||
.icon-algorithm:before{content:'\e97b'}
|
||||
.icon-app:before{content:'\e900'}
|
||||
@@ -24,6 +24,7 @@ src:url('font-unraid.eot?20191026');src:url('font-unraid.eot?20191026#iefix') fo
|
||||
.icon-apps:before{content:'\e942'}
|
||||
.icon-archive:before{content:'\e91a'}
|
||||
.icon-audio:before{content:'\e948'}
|
||||
.icon-chat:before{content:'\e981'}
|
||||
.icon-clock:before{content:'\e902'}
|
||||
.icon-cloud-services:before{content:'\e949'}
|
||||
.icon-config:before{content:'\e91b'}
|
||||
@@ -43,8 +44,10 @@ src:url('font-unraid.eot?20191026');src:url('font-unraid.eot?20191026#iefix') fo
|
||||
.icon-energysaving:before{content:'\e977'}
|
||||
.icon-ethernet:before{content:'\e90c'}
|
||||
.icon-eula:before{content:'\e91e'}
|
||||
.icon-experiments:before{content:'\e980'}
|
||||
.icon-fan:before{content:'\e90d'}
|
||||
.icon-folder:before{content:'\e92a'}
|
||||
.icon-fort:before{content:'\e97f'}
|
||||
.icon-ftp:before{content:'\e90e'}
|
||||
.icon-hardware:before{content:'\e91f'}
|
||||
.icon-home:before{content:'\e90f'}
|
||||
@@ -63,6 +66,7 @@ src:url('font-unraid.eot?20191026');src:url('font-unraid.eot?20191026#iefix') fo
|
||||
.icon-permissions:before{content:'\e923'}
|
||||
.icon-picture:before{content:'\e94b'}
|
||||
.icon-plugins:before{content:'\e944'}
|
||||
.icon-plugins-fill:before{content:'\e982'}
|
||||
.icon-preclear:before{content:'\e94c'}
|
||||
.icon-processes:before{content:'\e924'}
|
||||
.icon-profile:before{content:'\e909'}
|
||||
@@ -71,6 +75,7 @@ src:url('font-unraid.eot?20191026');src:url('font-unraid.eot?20191026#iefix') fo
|
||||
.icon-registration:before{content:'\e925'}
|
||||
.icon-remote-access:before{content:'\e94d'}
|
||||
.icon-repeatable:before{content:'\e96e'}
|
||||
.icon-rocket:before{content:'\e97e'}
|
||||
.icon-scheduler:before{content:'\e914'}
|
||||
.icon-security:before{content:'\e975'}
|
||||
.icon-share:before{content:'\e915'}
|
||||
@@ -113,7 +118,7 @@ src:url('font-unraid.eot?20191026');src:url('font-unraid.eot?20191026#iefix') fo
|
||||
.icon-u-pause:before{content:'\e939'}
|
||||
.icon-update:before{content:'\e927'}
|
||||
.icon-u-play:before{content:'\e93a'}
|
||||
.icon-u-plus-Copy-3:before{content:'\e968'}
|
||||
.icon-u-plus:before{content:'\e968'}
|
||||
.icon-u-polygon:before{content:'\e93b'}
|
||||
.icon-ups:before{content:'\e916'}
|
||||
.icon-u-restart:before{content:'\e93c'}
|
||||
@@ -140,6 +145,7 @@ src:url('font-unraid.eot?20191026');src:url('font-unraid.eot?20191026#iefix') fo
|
||||
.icon-video:before{content:'\e94e'}
|
||||
.icon-virtualization:before{content:'\e918'}
|
||||
.icon-vpn:before{content:'\e95c'}
|
||||
.icon-windows:before{content:'\e919'}
|
||||
.icon-warning:before{content:'\e97d'}
|
||||
.icon-windows:before{content:'\e919'}
|
||||
.icon-wireguard:before{content:'\e95d'}
|
||||
.icon-zip:before{content:'\e974'}
|
||||
|
||||
@@ -139,9 +139,10 @@ table.array_status tr>td+td+td{width:auto}
|
||||
table.array_status td.line{border-top:1px solid #0c0f0b}
|
||||
table.settings{padding-top:8px;line-height:4.2rem}
|
||||
table.settings td:first-child{width:35%;padding-left:12px}
|
||||
table.settings td+td{padding-left:8px}
|
||||
table.settings tr>td+td{line-height:1.6rem}
|
||||
table.settings.shifted{padding:0;margin-left:0;margin-top:0}
|
||||
table.settings.shifted td:first-child{padding-left:0}
|
||||
table.settings.shifted td{padding-left:0}
|
||||
table.share_status{white-space:nowrap;margin-top:12px}
|
||||
table.share_status thead tr:first-child td{font-size:1.2rem;letter-spacing:1px;text-transform:uppercase;color:#82857e;border-bottom:1px solid #606e7f}
|
||||
table.share_status tr>td{text-align:left;padding-left:12px}
|
||||
|
||||
@@ -131,10 +131,11 @@ table.array_status tr>td+td{padding-left:2px;width:20%}
|
||||
table.array_status tr>td+td+td{width:auto}
|
||||
table.array_status td.line{border-top:1px solid #e3e3e3}
|
||||
table.array_status.noshift{margin-top:0}
|
||||
table.settings{margin:0;padding:0}
|
||||
table.settings td:first-child{width:35%;padding-left:12px}
|
||||
table.settings{margin:0;padding:0;background-color:transparent}
|
||||
table.settings td:first-child{width:35%;padding:12px}
|
||||
table.settings td+td{padding-left:8px}
|
||||
table.settings.shifted{padding:0;margin-left:0;margin-top:0}
|
||||
table.settings.shifted td:first-child{padding-left:0}
|
||||
table.settings.shifted td{padding-left:0}
|
||||
table.access_list{border-spacing:0;margin-top:10px;border:none}
|
||||
table.access_list tr:first-child td{font-size:1.1rem;text-transform:uppercase;letter-spacing:1px;vertical-align:middle;text-align:left;border:1px solid #e3e3e3;border-bottom:1px solid #e3e3e3;background-color:#e8e8e8}
|
||||
table.access_list td:first-child{font-weight:normal;width:35%;padding-left:12px}
|
||||
@@ -235,7 +236,7 @@ span.label{font-size:1.2rem;padding:2px 0 2px 6px;margin-right:6px;border-radius
|
||||
span.cpu-speed{display:block;color:#3b5998}
|
||||
span.status{float:right;font-size:1.4rem;margin-top:30px;padding-right:8px;letter-spacing:1.8px}
|
||||
span.status.vhshift{margin-top:0;margin-right:0}
|
||||
span.status.vshift{margin-top:-18px}
|
||||
span.status.vshift{margin-top:-16px}
|
||||
span.status.hshift{margin-right:-20px}
|
||||
span.diskinfo{float:left;clear:both;margin-top:5px;padding-left:10px}
|
||||
span.bitstream{font-family:bitstream;font-size:1.1rem}
|
||||
|
||||
Binary file not shown.
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 74 KiB After Width: | Height: | Size: 79 KiB |
Binary file not shown.
Binary file not shown.
@@ -53,7 +53,7 @@ function addLog(logLine) {
|
||||
}
|
||||
|
||||
function disablePage() {
|
||||
for (var i=0,div; div=top.document.getElementsByClassName('spinner')[i]; i++) div.style.display = 'block';
|
||||
top.document.getElementsByClassName('spinner fixed')[0].style.display = 'block';
|
||||
for (var i=0,element; element=top.document.querySelectorAll('input,button,select')[i]; i++) element.disabled = true;
|
||||
for (var i=0,link; link=top.document.getElementsByTagName('a')[i]; i++) link.style.color = "gray"; //fake disable
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user