فهرست منبع

Finalized RAID management interface

aroz 1 سال پیش
والد
کامیت
94538f18e0
5فایلهای تغییر یافته به همراه155 افزوده شده و 49 حذف شده
  1. 8 12
      disk.go
  2. 12 0
      mod/disk/raid/handler.go
  3. 119 36
      web/SystemAO/disk/raid/index.html
  4. 1 1
      web/SystemAO/disk/smart/smart.html
  5. 15 0
      web/SystemAO/system_setting/index.html

+ 8 - 12
disk.go

@@ -165,21 +165,17 @@ func DiskServiceInit() {
 					}
 					raidManager.HandleRemoveRaideDevice(w, r)
 				})
+				adminRouter.HandleFunc("/system/disk/raid/assemble", func(w http.ResponseWriter, r *http.Request) {
+					if !AuthValidateSecureRequest(w, r) {
+						return
+					}
+					raidManager.HandleForceAssembleReload(w, r)
+				})
 				adminRouter.HandleFunc("/system/disk/raid/format", raidManager.HandleFormatRaidDevice)
 				adminRouter.HandleFunc("/system/disk/raid/detail", raidManager.HandleLoadArrayDetail)
 				adminRouter.HandleFunc("/system/disk/raid/devinfo", raidManager.HandlListChildrenDeviceInfo)
-				adminRouter.HandleFunc("/system/disk/raid/addMemeber", func(w http.ResponseWriter, r *http.Request) {
-					//if !AuthValidateSecureRequest(w, r) {
-					//	return
-					//}
-					raidManager.HandleAddDiskToRAIDVol(w, r)
-				})
-				adminRouter.HandleFunc("/system/disk/raid/removeMemeber", func(w http.ResponseWriter, r *http.Request) {
-					//if !AuthValidateSecureRequest(w, r) {
-					//	return
-					//}
-					raidManager.HandleRemoveDiskFromRAIDVol(w, r)
-				})
+				adminRouter.HandleFunc("/system/disk/raid/addMemeber", raidManager.HandleAddDiskToRAIDVol)
+				adminRouter.HandleFunc("/system/disk/raid/removeMemeber", raidManager.HandleRemoveDiskFromRAIDVol)
 
 				/* Device Management functions */
 				adminRouter.HandleFunc("/system/disk/devices/list", raidManager.HandleListUsableDevices)

+ 12 - 0
mod/disk/raid/handler.go

@@ -575,3 +575,15 @@ func (m *Manager) HandleRemoveRaideDevice(w http.ResponseWriter, r *http.Request
 	//Done
 	utils.SendOK(w)
 }
+
+// Force reload all RAID config from file
+func (m *Manager) HandleForceAssembleReload(w http.ResponseWriter, r *http.Request) {
+	err := m.FlushReload()
+	if err != nil {
+		m.Options.Logger.PrintAndLog("RAID", "mdadm reload failed: "+err.Error(), err)
+		utils.SendErrorResponse(w, err.Error())
+		return
+	}
+
+	utils.SendOK(w)
+}

+ 119 - 36
web/SystemAO/disk/raid/index.html

@@ -166,8 +166,8 @@
                         <button title="Add new RAID volume" onclick="addNewRaidVolume()" class="circular basic green large ui icon button">
                             <i class="green add icon"></i>
                         </button>
-                        <button title="Assemble RAID Pools" onclick="assembleRaidVolumes()" class="circular basic orange large ui icon button">
-                            <i class="orange refresh icon"></i>
+                        <button title="Assemble RAID Pools" onclick="assembleRaidVolumes()" class="circular basic orange large ui button">
+                            <i class="orange refresh icon"></i> Assemble
                         </button>
                     </div>
                 </div>
@@ -251,9 +251,6 @@
                             <p><i class="yellow exclamation triangle icon"></i> Danger Zone <i class="yellow exclamation triangle icon"></i></p>
                         </div>
                         <div style="width: 100%;" align="center">
-                            <button onclick="" class="circular basic red ui button">
-                                <i class="red stop icon"></i> Stop RAID
-                            </button>
                             <button onclick="RAIDRemove();" class="circular red ui button">
                                 <i class="trash icon"></i> Remove RAID
                             </button>
@@ -333,11 +330,68 @@
         <script>
 
             var raidManager = {
+                raidDetails: {}, //The raid array details from last server req
                 editingArray: "",
                 removePendingDisk: "",
                 removePendingSourceVol: ""
             };
 
+            /* Information Update Ticker */
+            function RAIDInfoUpdateTicker(){
+                function compareRAIDstate(oldState, newState) {
+                    const fieldsToCompare = [
+                        "Consistency",
+                        "FailedDevices",
+                        "RebuildStatus",
+                        "SpareDevices",
+                        "State",
+                        "TotalDevices",
+                        "WorkingDevices"
+                    ];
+
+                    for (const field of fieldsToCompare) {
+                        if (oldState[field] !== newState[field]) {
+                            return false;
+                        }
+                    }
+
+                    return true;
+                }
+
+
+
+                if ($("#raidDiskOverview").length > 0){
+                    //Still on the RAID manager page
+                   if (raidManager.editingArray == undefined || raidManager.editingArray == ""){
+                        //Nothing selected or loaded. Skip this round
+                        setTimeout(RAIDInfoUpdateTicker, 10000);
+                        return;
+                    }
+                    $.get("../../system/disk/raid/detail?devName=" + raidManager.editingArray, function(data){
+                        if (data.error != undefined){
+                            //Something went wrong loading this array (removed by another admin?)
+                        }else{
+                            //Validate if both details are identical
+                            if (compareRAIDstate(data,raidManager.raidDetails)){
+                                //No information updated
+
+                            }else{
+                                //Something updated. Reload the RAID volume info
+                                loadRAIDVolDetail(raidManager.editingArray);
+                            }
+                        }
+
+                        //Update again in 3s
+                        setTimeout(RAIDInfoUpdateTicker, 5000);
+                    });
+                    
+                }
+                
+            }
+
+            //Set the ticker
+            setTimeout(RAIDInfoUpdateTicker, 1000);
+
             /* RAID Create Functions */
             function addNewRaidVolume(){
                 //Open newRAID window
@@ -353,9 +407,15 @@
             }
 
             window.handleRAIDCreateCallback = function(data){
-                //Done adding disk
+                //Done adding raid vol
                 setTimeout(function(){
                     reloadRAIDVolDetail();
+                    if (data.error != undefined){
+                        msgbox(data.error, false, 5000);
+                    }else{
+                        msgbox("New RAID volume created");
+                    }
+                    
                 }, 300);
             }
 
@@ -398,7 +458,7 @@
             window.handleRAIDRemoveCallback = function(data){
                 if (data.error != undefined){
                     //Something went wrong
-                    alert(data.error);
+                    msgbox(data.error, false, 5000);
                 }else{
                     setTimeout(function(){
                         //RAID volume not exist anymore. Reset everything
@@ -429,6 +489,7 @@
             window.handleAddDiskCallback = function(data){
                 //Done adding disk
                 setTimeout(function(){
+                    msgbox("New disk added");
                     reloadRAIDVolDetail();
                 }, 300);
             }
@@ -445,34 +506,6 @@
             
 
             function confirmRemoveDisk(){
-                /*
-                let raidName = raidManager.removePendingSourceVol.split("/").pop();
-                var apiObject = {
-                    api: "../system/disk/raid/removeMemeber",
-                    data: {
-                        raidDev:  raidManager.removePendingSourceVol,
-                        memDev: raidManager.removePendingDisk
-                    },
-                    title: `<i class='yellow exclamation triangle icon'></i> Remove Disk From Volume <i class='yellow exclamation triangle icon'></i>`,
-                    desc: `Confirm remove ${raidManager.removePendingDisk} from ${raidManager.removePendingSourceVol}`,
-                    thisuser: true, //This username as default, set to false for entering other user
-                    method: "POST",
-                    success: undefined
-                }
-                apiObject = encodeURIComponent(JSON.stringify(apiObject));
-                
-               
-                parent.newFloatWindow({
-                    url: "SystemAO/security/authreq.html#" + apiObject,
-                    width: 480,
-                    height: 300,
-                    appicon: "SystemAO/security/img/lock.svg",
-                    title: `Confirm Disk Remove`,
-                    parent: ao_module_windowID,
-                    callback: "handleRemoveDiskCallback"
-                });
-                */
-
                 $.ajax({
                     url: "../../system/disk/raid/removeMemeber",
                     data: {
@@ -492,6 +525,7 @@
                 raidManager.removePendingDisk = "";
                 raidManager.removePendingSourceVol = "";
                 setTimeout(function(){
+                    msgbox("Target disk removed");
                     reloadRAIDVolDetail();
                 }, 300);
             }
@@ -537,7 +571,6 @@
 
             //Reload the current raid volume detail
             function reloadRAIDVolDetail(){
-                $("#raidDataLossWarning").hide();
                 if (raidManager.editingArray != undefined){
                     initRAIDVolList(raidManager.editingArray);
                 } 
@@ -590,6 +623,7 @@
                             </h3>`);
                             return;
                         }
+                        raidManager.raidDetails = data
 
                         //Update the active disks info
                         $("#RAIDOverviewDiskpath").html(data.DevicePath + ` <span class="mdevice">(${data.RaidLevel.toUpperCase()})</span>`);
@@ -600,6 +634,14 @@
                         $("#RAIDFailedDevices").text(data.FailedDevices);
                         $("#RAIDSpareDevices").text(data.SpareDevices);
                         $("#RAIDOverviewStateIcon").attr("class", getStateIconFromStateText(data.State));
+                        
+                        //Update the RAIDVol Button on the left menu as well
+                        $(".raidVol").each(function(){
+                            if ($(this).attr("devpath") == data.DevicePath){
+                                //this is the one we are updating
+                                $(this).find(".healthIcon i").attr("class", getStateIconFromStateText(data.State))
+                            }
+                        });
 
                         //Render the disk list
                         $("#raidDiskList").html("");
@@ -696,6 +738,8 @@
                         if (!allowRemoveDisk){
                             $(".removeDiskBtn.normal").addClass("disabled");
                             $("#raidDataLossWarning").show();
+                        }else{
+                            $("#raidDataLossWarning").hide();
                         }
 
                     });
@@ -774,6 +818,45 @@
             }
             initRAIDVolList();
             
+            /* Force unload all RAID volume and remount them from config files */
+            function assembleRaidVolumes(){
+                var apiObject = {
+                    api: "../system/disk/raid/assemble",
+                    data: {},
+                    title: `<i class='yellow exclamation triangle icon'></i> Force Assemble`,
+                    desc: `Confirm force stop & reload RAID from mdadm.conf?`,
+                    thisuser: true, //This username as default, set to false for entering other user
+                    method: "POST",
+                    success: undefined
+                }
+                apiObject = encodeURIComponent(JSON.stringify(apiObject));
+                
+               
+                parent.newFloatWindow({
+                    url: "SystemAO/security/authreq.html#" + apiObject,
+                    width: 480,
+                    height: 300,
+                    appicon: "SystemAO/security/img/lock.svg",
+                    title: `Confirm Force Assemble`,
+                    parent: ao_module_windowID,
+                    callback: "handleForceAssembleCallback"
+                });
+            }
+
+            window.handleForceAssembleCallback = function(data){
+                if (data.error != undefined){
+                    //Something went wrong
+                    msgbox(data.error, false, 5000);
+                }else{
+                    setTimeout(function(){
+                        //Reload all RAID volumes
+                        raidManager = {};
+                        initRAIDVolList();
+                        msgbox("Force RAID Assemble Completed");
+                    }, 300);
+                }
+                
+            }
         </script>
     </body>
 </html>

+ 1 - 1
web/SystemAO/disk/smart/smart.html

@@ -141,7 +141,7 @@
                     $("#modal_smart").append("<td>" + value.healthy + "</td>");
                     $("#modal_smart").append("</tr>");
             });
-            $('.ui.modal').modal('show');
+            $('.smartdetails').modal('show');
           }
         </script>
    

+ 15 - 0
web/SystemAO/system_setting/index.html

@@ -42,6 +42,13 @@
                 padding-top: 1em;
                 border-radius: 0 0 0 0 !important;
             }
+
+            #msgbox{
+                position: fixed;
+                bottom: 0.2em;
+                right: 2em;
+                display:none;
+            }
         </style>
     </head>
     <body>
@@ -70,6 +77,9 @@
           </div>
           <div id="settingContentLoader" class="ui bottom attached segment">
 
+          </div>
+          <div id="msgbox" class="ui compact small message">
+            Hello World
           </div>
           </div>
          
@@ -238,6 +248,11 @@
                 alert(keyword);
               }
 
+              function msgbox(message, succ=true, delay=3000){
+                $("#msgbox").html(`<i class="ui ${succ?"green circle check":"red circle times"} icon"></i> ${message}`);
+                $("#msgbox").stop().finish().fadeIn("fast").delay(delay).fadeOut("fast");
+              }
+
           </script>
     </body>
 </html>