|
@@ -13,9 +13,9 @@
|
|
background-color:white;
|
|
background-color:white;
|
|
}
|
|
}
|
|
.themebackground{
|
|
.themebackground{
|
|
- background-color:#29cc96 !important;
|
|
|
|
|
|
+ background-color:#242424 !important;
|
|
color:white !important;
|
|
color:white !important;
|
|
- background-image: url("/img/public/slate.png") !important;
|
|
|
|
|
|
+ background-image: url("../../img/system/slates/pool-slate.png") !important;
|
|
background-repeat: no-repeat !important;
|
|
background-repeat: no-repeat !important;
|
|
background-attachment: fixed !important;
|
|
background-attachment: fixed !important;
|
|
height:100px;
|
|
height:100px;
|
|
@@ -192,15 +192,55 @@
|
|
</form>
|
|
</form>
|
|
<div class="ui divider"></div>
|
|
<div class="ui divider"></div>
|
|
</div>
|
|
</div>
|
|
- <br>
|
|
|
|
- <button class="ui green button" onclick="toggleCreateNewFileHandler();"><i class="add icon"></i>New File System Handler</button>
|
|
|
|
- <button class="ui right floated button" onclick="done();"></i>Done</button>
|
|
|
|
- <br><br>
|
|
|
|
|
|
+
|
|
|
|
+ <!-- Bridge File System Handler options -->
|
|
|
|
+ <div id="bridgeFsh" style="display:none;">
|
|
|
|
+ <h3><i class="pallet icon"></i> Bridge File System Handler</h3>
|
|
|
|
+ <p>Bridge a File System Handler (FSH) from other Storage Pool to this pool. The bridged FSH will implements the same permission and hierarchy as its source pool.</p>
|
|
|
|
+ <div class="ui form">
|
|
|
|
+ <p>Source File System Handler</p>
|
|
|
|
+ <div class="field">
|
|
|
|
+ <label>Storage Pool from Permission Group</label>
|
|
|
|
+ <div class="ui selection dropdown">
|
|
|
|
+ <input id="bridgeTargetPool" type="hidden" name="sourcePool" value="" onchange="loadFSHForPool(this.value);">
|
|
|
|
+ <i class="dropdown icon"></i>
|
|
|
|
+ <div class="default text"></div>
|
|
|
|
+ <div id="otherPools" class="menu">
|
|
|
|
+
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+
|
|
|
|
+ <div class="field">
|
|
|
|
+ <label>Target File System Handler</label>
|
|
|
|
+ <div class="ui selection dropdown">
|
|
|
|
+ <input id="souceFSH" type="hidden" name="souceFSH" value="">
|
|
|
|
+ <i class="dropdown icon"></i>
|
|
|
|
+ <div class="default text"></div>
|
|
|
|
+ <div id="sourceFSH" class="menu">
|
|
|
|
+
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <div class="ui blue message">
|
|
|
|
+ Notes: All users that has access to this storage pool will be able to access the newly bridged File System Handler
|
|
|
|
+ </div>
|
|
|
|
+ <button class="ui right floated button" onclick='event.preventDefault(); $("#bridgeFsh").slideUp("fast"); '>Close</button>
|
|
|
|
+ <button class="ui green right floated button" onclick="bridgeFSH();">Bridge Handler to Pool</button>
|
|
|
|
+ <br><br>
|
|
|
|
+ <div class="ui divider"></div>
|
|
|
|
+ </div>
|
|
|
|
+ </div>
|
|
|
|
+ <button class="ui blue button" onclick="toggleCreateNewFileHandler();"><i class="add icon"></i>New File System Handler</button><br>
|
|
|
|
+ <button style="margin-top: 8px;" class="ui basic button" onclick="toggleBridgeFileHandler();"><i class="pallet icon"></i>Bridge FSH from other Pool</button>
|
|
|
|
+ <button style="margin-top: 8px;" class="ui right floated button" onclick="done();"></i>Done</button>
|
|
|
|
+ <br><br><br>
|
|
</div>
|
|
</div>
|
|
|
|
|
|
<script>
|
|
<script>
|
|
//Load the editing storage pool from window hash
|
|
//Load the editing storage pool from window hash
|
|
var editingStoragePool = "system"
|
|
var editingStoragePool = "system"
|
|
|
|
+ var otherPoolConfigMap = {};
|
|
if (window.location.hash.length > 1){
|
|
if (window.location.hash.length > 1){
|
|
editingStoragePool = window.location.hash.substr(1)
|
|
editingStoragePool = window.location.hash.substr(1)
|
|
}
|
|
}
|
|
@@ -214,12 +254,22 @@
|
|
$(".ui.dropdown").dropdown();
|
|
$(".ui.dropdown").dropdown();
|
|
$(".ui.checkbox").checkbox();
|
|
$(".ui.checkbox").checkbox();
|
|
|
|
|
|
|
|
+ initBridgingOptions();
|
|
|
|
+
|
|
function toggleCreateNewFileHandler(){
|
|
function toggleCreateNewFileHandler(){
|
|
|
|
+ $("#bridgeFsh").slideUp("fast");
|
|
$("#newfsh").slideToggle("fast", function(){
|
|
$("#newfsh").slideToggle("fast", function(){
|
|
$(window).scrollTop($("#newfsh").offset().top - 10);
|
|
$(window).scrollTop($("#newfsh").offset().top - 10);
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ function toggleBridgeFileHandler(){
|
|
|
|
+ $("#newfsh").slideUp("fast");
|
|
|
|
+ $("#bridgeFsh").slideDown("fast", function(){
|
|
|
|
+ $(window).scrollTop($("#bridgeFsh").offset().top - 10);
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
function PoolAlreadyListed(uuid){
|
|
function PoolAlreadyListed(uuid){
|
|
var alreadyExisted = false;
|
|
var alreadyExisted = false;
|
|
$(".fsh").each(function(){
|
|
$(".fsh").each(function(){
|
|
@@ -235,6 +285,73 @@
|
|
ao_module_close();
|
|
ao_module_close();
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ function initBridgingOptions(){
|
|
|
|
+ $.get("../../system/storage/pool/list", function(data){
|
|
|
|
+ $("#otherPools").html('');
|
|
|
|
+ var firstPool = "";
|
|
|
|
+ for (var i = 0; i < data.length; i++){
|
|
|
|
+ let thisPool = data[i];
|
|
|
|
+ if (thisPool.Owner == "system"){
|
|
|
|
+ //Do not allow bridging
|
|
|
|
+ continue;
|
|
|
|
+ }
|
|
|
|
+ if (thisPool.Owner != editingStoragePool){
|
|
|
|
+ if (firstPool == ""){
|
|
|
|
+ firstPool = JSON.parse(JSON.stringify(thisPool.Owner));
|
|
|
|
+ }
|
|
|
|
+ if (thisPool.Storages == null || thisPool.Storages.length == 0){
|
|
|
|
+ otherPoolConfigMap[thisPool.Owner] = [];
|
|
|
|
+ }else{
|
|
|
|
+ otherPoolConfigMap[thisPool.Owner] = thisPool.Storages
|
|
|
|
+ }
|
|
|
|
+ $("#otherPools").append(`<div class="item" data-value="${thisPool.Owner}">${thisPool.Owner}</div>`);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ $("#otherPools").parent().dropdown();
|
|
|
|
+ $("#otherPools").parent().dropdown("set selected", firstPool);
|
|
|
|
+ loadFSHForPool(firstPool);
|
|
|
|
+ });
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function getDiskIcon(Hierarchy){
|
|
|
|
+ let diskIcon = "disk";
|
|
|
|
+ if (Hierarchy == "user"){
|
|
|
|
+ diskIcon = "blue disk";
|
|
|
|
+ }else if (Hierarchy == "public"){
|
|
|
|
+ diskIcon = "grey disk";
|
|
|
|
+ }else if (Hierarchy == "backup"){
|
|
|
|
+ diskIcon = "green refresh";
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ return diskIcon;
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ function loadFSHForPool(poolName){
|
|
|
|
+ if (otherPoolConfigMap[poolName]){
|
|
|
|
+ $("#sourceFSH").html("");
|
|
|
|
+ $("#sourceFSH").parent().removeClass('disabled');
|
|
|
|
+ var storages = otherPoolConfigMap[poolName];
|
|
|
|
+ if (storages.length > 0){
|
|
|
|
+ storages.forEach(fsh => {
|
|
|
|
+ var diskIcon = getDiskIcon(fsh.Hierarchy);
|
|
|
|
+ $("#sourceFSH").append(`<div class="item" data-value="${fsh.UUID}"><i class="${diskIcon} icon"></i> ${fsh.Name} (${fsh.UUID}:/)</div>`);
|
|
|
|
+ });
|
|
|
|
+ $("#sourceFSH").parent().dropdown();
|
|
|
|
+ $("#sourceFSH").parent().dropdown("set selected", storages[0].UUID);
|
|
|
|
+ }else{
|
|
|
|
+ //No storage inside
|
|
|
|
+ $("#sourceFSH").parent().addClass('disabled');
|
|
|
|
+ $("#sourceFSH").append(`<div class="item" data-value="nodisk"><i class="remove icon"></i> No File System Handler in this Storage Pool</div>`);
|
|
|
|
+ $("#sourceFSH").parent().dropdown();
|
|
|
|
+ $("#sourceFSH").parent().dropdown("set selected", "nodisk");
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ }else{
|
|
|
|
+ //Pool not exists
|
|
|
|
+ $("#sourceFSH").parent().addClass('disabled');
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+
|
|
function loadStoragePoolForGroup(pgname){
|
|
function loadStoragePoolForGroup(pgname){
|
|
$("#fshList").html("");
|
|
$("#fshList").html("");
|
|
$.get("../../system/storage/pool/list?filter=" + pgname, function(data){
|
|
$.get("../../system/storage/pool/list?filter=" + pgname, function(data){
|
|
@@ -252,8 +369,10 @@
|
|
usableIcon = "remove";
|
|
usableIcon = "remove";
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ var diskIcon = getDiskIcon(storage.Hierarchy);
|
|
|
|
+
|
|
$("#fshList").append(`<div class="ui ${color} segment fsh" uuid="${storage.UUID}">
|
|
$("#fshList").append(`<div class="ui ${color} segment fsh" uuid="${storage.UUID}">
|
|
- <h3><i class="disk icon"></i> ${storage.Name} (${storage.UUID}:/)</h3>
|
|
|
|
|
|
+ <h3><i class="${diskIcon} icon typeicon"></i> ${storage.Name} (${storage.UUID}:/)</h3>
|
|
<ol class="ui list">
|
|
<ol class="ui list">
|
|
<li value="-"><i class="folder icon"></i> Mount Point: ${storage.Path}</li>
|
|
<li value="-"><i class="folder icon"></i> Mount Point: ${storage.Path}</li>
|
|
<li value="-"><i class="user icon"></i> Hierarchy: ${storage.Hierarchy}</li>
|
|
<li value="-"><i class="user icon"></i> Hierarchy: ${storage.Hierarchy}</li>
|
|
@@ -264,7 +383,7 @@
|
|
<div class="ui text loader">Waiting Response</div>
|
|
<div class="ui text loader">Waiting Response</div>
|
|
</div>
|
|
</div>
|
|
<div class="controls">
|
|
<div class="controls">
|
|
- <a title="Edit Config" uuid="${storage.UUID}" group="${pgname}" onclick="editFSH(this);"><i class="edit icon"></i></a>
|
|
|
|
|
|
+ <a class="edit" title="Edit Config" uuid="${storage.UUID}" group="${pgname}" onclick="editFSH(this);"><i class="edit icon"></i></a>
|
|
<a title="Close Handler" uuid="${storage.UUID}" group="${pgname}" onclick="toggleFSH(this);"><i class="power off icon"></i></a>
|
|
<a title="Close Handler" uuid="${storage.UUID}" group="${pgname}" onclick="toggleFSH(this);"><i class="power off icon"></i></a>
|
|
<a title="Remove Handler" uuid="${storage.UUID}" group="${pgname}" onclick="removeThisFSH(this);"><i class="remove icon"></i></a>
|
|
<a title="Remove Handler" uuid="${storage.UUID}" group="${pgname}" onclick="removeThisFSH(this);"><i class="remove icon"></i></a>
|
|
</div>
|
|
</div>
|
|
@@ -320,10 +439,29 @@
|
|
//List the handlers that will be removed during next boot
|
|
//List the handlers that will be removed during next boot
|
|
onlineFSH.forEach(ofsh => {
|
|
onlineFSH.forEach(ofsh => {
|
|
if (allFSH.includes(ofsh) == false){
|
|
if (allFSH.includes(ofsh) == false){
|
|
- //Currently online but not in original config. aka Delete Pending
|
|
|
|
|
|
+ //Currently online but not in original config. aka Delete Pending or it is bridged
|
|
$(".fsh").each(function(){
|
|
$(".fsh").each(function(){
|
|
if ($(this).attr("uuid") == ofsh && !($(this).attr("uuid") == "user" || $(this).attr("uuid") == "tmp")){
|
|
if ($(this).attr("uuid") == ofsh && !($(this).attr("uuid") == "user" || $(this).attr("uuid") == "tmp")){
|
|
- $(this).append("<p style='color: red;'>**Will be removed after next reboot</p>")
|
|
|
|
|
|
+ let targetDOMElement = $(this);
|
|
|
|
+ $.ajax({
|
|
|
|
+ url: "../../system/storage/pool/checkBridge",
|
|
|
|
+ data: {base: editingStoragePool, fsh: ofsh},
|
|
|
|
+ success: function(data){
|
|
|
|
+ if (data.error != undefined){
|
|
|
|
+
|
|
|
|
+ }else{
|
|
|
|
+ if (data == true){
|
|
|
|
+ targetDOMElement.find(".controls").find(".edit").remove();
|
|
|
|
+ targetDOMElement.find(".typeicon").attr("class","blue pallet icon typeicon");
|
|
|
|
+ targetDOMElement.find(".ui.list").prepend(`<li value="-"><i class="exchange icon"></i> Bridged File System Handler</i>`);
|
|
|
|
+
|
|
|
|
+ }else{
|
|
|
|
+ targetDOMElement.append("<p style='color: red;'>**Will be removed after next reboot</p>")
|
|
|
|
+ targetDOMElement.find(".controls").find(".edit").remove();
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ });
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
@@ -372,8 +510,12 @@
|
|
url: "../../system/storage/pool/removeHandler",
|
|
url: "../../system/storage/pool/removeHandler",
|
|
data: {uuid: uuid, group: group},
|
|
data: {uuid: uuid, group: group},
|
|
success: function(data){
|
|
success: function(data){
|
|
- console.log(data);
|
|
|
|
- window.location.href = "removeSuccess.html#" + JSON.stringify([group, uuid]);
|
|
|
|
|
|
+ if (data.error !== undefined){
|
|
|
|
+ alert(data.error);
|
|
|
|
+ }else{
|
|
|
|
+ window.location.href = "removeSuccess.html#" + JSON.stringify([group, uuid]);
|
|
|
|
+ }
|
|
|
|
+
|
|
}
|
|
}
|
|
});
|
|
});
|
|
}
|
|
}
|
|
@@ -414,6 +556,26 @@
|
|
});
|
|
});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
+ function bridgeFSH(){
|
|
|
|
+ var currentStoragePool = editingStoragePool;
|
|
|
|
+ var selectedSourceFSH = $("#souceFSH").val();
|
|
|
|
+
|
|
|
|
+ $.ajax({
|
|
|
|
+ url: "../../system/storage/pool/bridge",
|
|
|
|
+ data: {base: currentStoragePool, fsh: selectedSourceFSH},
|
|
|
|
+ success: function(data){
|
|
|
|
+ if (data.error !== undefined){
|
|
|
|
+ alert(data.error);
|
|
|
|
+ }else{
|
|
|
|
+ //Success
|
|
|
|
+ $("#bridgeFsh").slideUp("fast");
|
|
|
|
+ loadStoragePoolForGroup(editingStoragePool);
|
|
|
|
+ $(window).scrollTop(0);
|
|
|
|
+ }
|
|
|
|
+ }
|
|
|
|
+ })
|
|
|
|
+ }
|
|
|
|
+
|
|
function finishFshEdit(){
|
|
function finishFshEdit(){
|
|
//Reload storage pool
|
|
//Reload storage pool
|
|
loadStoragePoolForGroup(editingStoragePool);
|
|
loadStoragePoolForGroup(editingStoragePool);
|