Преглед на файлове

Added smart potential fix

Toby Chui преди 2 години
родител
ревизия
de63b155ba
променени са 5 файла, в които са добавени 45 реда и са изтрити 647 реда
  1. 1 1
      Makefile
  2. 11 4
      mod/disk/smart/smart.go
  3. 0 3
      system/lang/en-HK.json
  4. 33 34
      web/SystemAO/info/gomod-license.csv
  5. 0 605
      web/SystemAO/storage/poolEditor.html

+ 1 - 1
Makefile

@@ -1,5 +1,5 @@
 # PLATFORMS := darwin/amd64 darwin/arm64 freebsd/amd64 linux/386 linux/amd64 linux/arm linux/arm64 linux/mipsle windows/386 windows/amd64 windows/arm windows/arm64
-PLATFORMS := darwin/amd64 darwin/arm64 linux/amd64 linux/arm linux/arm64 linux/mipsle  linux/riscv64 windows/amd64 windows/arm64
+PLATFORMS := darwin/amd64 darwin/arm64 linux/amd64 linux/386 linux/arm linux/arm64 linux/mipsle  linux/riscv64 windows/amd64 windows/arm64
 temp = $(subst /, ,$@)
 os = $(word 1, $(temp))
 arch = $(word 2, $(temp))

+ 11 - 4
mod/disk/smart/smart.go

@@ -14,6 +14,7 @@ import (
 	"encoding/json"
 	"log"
 	"net/http"
+	"os"
 	"strconv"
 	"strings"
 
@@ -44,6 +45,12 @@ func NewSmartListener() (*SMARTListener, error) {
 		return &SMARTListener{}, errors.New("smartctl not found")
 	}
 
+	//Updated 5 June 2023: Try to chmod it if it is on linux so that
+	//broken permissions still works in sudo mode
+	if runtime.GOOS == "linux" {
+		os.Chmod(smartExec, 0777)
+	}
+
 	driveList := scanAvailableDevices(smartExec)
 	readSMARTDevices(smartExec, &driveList)
 	fillHealthyStatus(&driveList)
@@ -54,7 +61,7 @@ func NewSmartListener() (*SMARTListener, error) {
 	}, nil
 }
 
-//this function used for fetch available devices by using smartctl
+// this function used for fetch available devices by using smartctl
 func scanAvailableDevices(smartExec string) DevicesList {
 	rawInfo := execCommand(smartExec, "--scan", "--json=c")
 	devicesList := new(DevicesList)
@@ -70,7 +77,7 @@ func scanAvailableDevices(smartExec string) DevicesList {
 	return *devicesList
 }
 
-//this function used for merge SMART Information into devicesList
+// this function used for merge SMART Information into devicesList
 func readSMARTDevices(smartExec string, devicesList *DevicesList) {
 	for i, device := range devicesList.Devices {
 		rawInfo := execCommand(smartExec, device.Name, "--info", "--all", "--json=c")
@@ -80,7 +87,7 @@ func readSMARTDevices(smartExec string, devicesList *DevicesList) {
 	}
 }
 
-//used for fill the healthy status to the array
+// used for fill the healthy status to the array
 func fillHealthyStatus(devicesList *DevicesList) {
 	devicesList.Healthy = "Normal"
 	for i, device := range devicesList.Devices {
@@ -103,7 +110,7 @@ func fillHealthyStatus(devicesList *DevicesList) {
 	}
 }
 
-//fill the capacity if windows
+// fill the capacity if windows
 func fillCapacity(devicesList *DevicesList) {
 	if runtime.GOOS == "windows" {
 		DiskNames := wmicGetinfo("diskdrive", "Model")

+ 0 - 3
system/lang/en-HK.json

@@ -1,3 +0,0 @@
-{
-    
-}

+ 33 - 34
web/SystemAO/info/gomod-license.csv

@@ -1,29 +1,28 @@
-cloud.google.com/go/compute/metadata,https://github.com/googleapis/google-cloud-go/blob/compute/v1.9.0/compute/LICENSE,Apache-2.0
-github.com/Microsoft/go-winio,https://github.com/Microsoft/go-winio/blob/v0.5.2/LICENSE,MIT
-github.com/ProtonMail/go-crypto,https://github.com/ProtonMail/go-crypto/blob/4b6e5c587895/LICENSE,BSD-3-Clause
-github.com/andybalholm/brotli,https://github.com/andybalholm/brotli/blob/v1.0.4/LICENSE,MIT
+cloud.google.com/go/compute/metadata,https://github.com/googleapis/google-cloud-go/blob/compute/metadata/v0.2.3/compute/metadata/LICENSE,Apache-2.0
+github.com/Microsoft/go-winio,https://github.com/Microsoft/go-winio/blob/v0.6.1/LICENSE,MIT
+github.com/ProtonMail/go-crypto,https://github.com/ProtonMail/go-crypto/blob/58e86b294756/LICENSE,BSD-3-Clause
+github.com/andybalholm/brotli,https://github.com/andybalholm/brotli/blob/v1.0.5/LICENSE,MIT
 github.com/boltdb/bolt,https://github.com/boltdb/bolt/blob/v1.3.1/LICENSE,MIT
 github.com/cenkalti/backoff,https://github.com/cenkalti/backoff/blob/v2.2.1/LICENSE,MIT
-github.com/cloudflare/circl,https://github.com/cloudflare/circl/blob/v1.2.0/LICENSE,BSD-3-Clause
+github.com/cloudflare/circl,https://github.com/cloudflare/circl/blob/v1.3.3/LICENSE,BSD-3-Clause
 github.com/dhowden/tag,https://github.com/dhowden/tag/blob/adf36e896086/LICENSE,BSD-2-Clause
 github.com/disintegration/imaging,https://github.com/disintegration/imaging/blob/v1.6.2/LICENSE,MIT
 github.com/dsnet/compress,https://github.com/dsnet/compress/blob/f66993602bf5/LICENSE.md,BSD-3-Clause
 github.com/emirpasic/gods,https://github.com/emirpasic/gods/blob/v1.18.1/LICENSE,BSD-2-Clause
-github.com/fclairamb/ftpserverlib,https://github.com/fclairamb/ftpserverlib/blob/v0.19.1/license.txt,MIT
+github.com/fclairamb/ftpserverlib,https://github.com/fclairamb/ftpserverlib/blob/v0.21.0/license.txt,MIT
 github.com/fclairamb/go-log,https://github.com/fclairamb/go-log/blob/v0.4.1/license.txt,MIT
 github.com/fogleman/fauxgl,https://github.com/fogleman/fauxgl/blob/27cddc103802/LICENSE.md,MIT
 github.com/fogleman/simplify,https://github.com/fogleman/simplify/blob/d32f302d5046/LICENSE.md,MIT
-github.com/gabriel-vasile/mimetype,https://github.com/gabriel-vasile/mimetype/blob/v1.4.1/LICENSE,MIT
+github.com/gabriel-vasile/mimetype,https://github.com/gabriel-vasile/mimetype/blob/v1.4.2/LICENSE,MIT
 github.com/geoffgarside/ber,https://github.com/geoffgarside/ber/blob/v1.1.0/LICENSE,BSD-3-Clause
 github.com/go-git/gcfg,https://github.com/go-git/gcfg/blob/v1.5.0/LICENSE,BSD-3-Clause
-github.com/go-git/go-billy/v5,https://github.com/go-git/go-billy/blob/v5.3.1/LICENSE,Apache-2.0
-github.com/go-git/go-git/v5,https://github.com/go-git/go-git/blob/v5.4.2/LICENSE,Apache-2.0
+github.com/go-git/go-billy/v5,https://github.com/go-git/go-billy/blob/v5.4.1/LICENSE,Apache-2.0
+github.com/go-git/go-git/v5,https://github.com/go-git/go-git/blob/v5.6.1/LICENSE,Apache-2.0
 github.com/go-ldap/ldap,https://github.com/go-ldap/ldap/blob/v3.0.3/LICENSE,MIT
 github.com/golang/freetype,Unknown,Unknown
 github.com/golang/freetype/raster,Unknown,Unknown
 github.com/golang/freetype/truetype,Unknown,Unknown
 github.com/golang/snappy,https://github.com/golang/snappy/blob/v0.0.4/LICENSE,BSD-3-Clause
-github.com/google/uuid,https://github.com/google/uuid/blob/v1.3.0/LICENSE,BSD-3-Clause
 github.com/gorilla/securecookie,https://github.com/gorilla/securecookie/blob/v1.1.1/LICENSE,BSD-3-Clause
 github.com/gorilla/sessions,https://github.com/gorilla/sessions/blob/v1.2.1/LICENSE,BSD-3-Clause
 github.com/gorilla/websocket,https://github.com/gorilla/websocket/blob/v1.5.0/LICENSE,BSD-2-Clause
@@ -31,46 +30,46 @@ github.com/grandcat/zeroconf,https://github.com/grandcat/zeroconf/blob/v1.0.0/LI
 github.com/hashicorp/errwrap,https://github.com/hashicorp/errwrap/blob/v1.1.0/LICENSE,MPL-2.0
 github.com/hashicorp/go-multierror,https://github.com/hashicorp/go-multierror/blob/v1.1.1/LICENSE,MPL-2.0
 github.com/hirochachacha/go-smb2,https://github.com/hirochachacha/go-smb2/blob/v1.1.0/LICENSE,BSD-2-Clause
-github.com/imdario/mergo,https://github.com/imdario/mergo/blob/v0.3.13/LICENSE,BSD-3-Clause
+github.com/imdario/mergo,https://github.com/imdario/mergo/blob/v0.3.15/LICENSE,BSD-3-Clause
 github.com/jbenet/go-context/io,https://github.com/jbenet/go-context/blob/d14ea06fba99/LICENSE,MIT
 github.com/jlaffaye/ftp,https://github.com/jlaffaye/ftp/blob/v0.1.0/LICENSE,ISC
 github.com/kevinburke/ssh_config,https://github.com/kevinburke/ssh_config/blob/v1.2.0/LICENSE,MIT
-github.com/klauspost/compress,https://github.com/klauspost/compress/blob/v1.15.9/LICENSE,Apache-2.0
-github.com/klauspost/compress/internal/snapref,https://github.com/klauspost/compress/blob/v1.15.9/internal\snapref\LICENSE,BSD-3-Clause
-github.com/klauspost/compress/zstd/internal/xxhash,https://github.com/klauspost/compress/blob/v1.15.9/zstd\internal\xxhash\LICENSE.txt,MIT
-github.com/klauspost/pgzip,https://github.com/klauspost/pgzip/blob/v1.2.5/LICENSE,MIT
-github.com/koron/go-ssdp,https://github.com/koron/go-ssdp/blob/v0.0.3/LICENSE,MIT
+github.com/klauspost/compress,https://github.com/klauspost/compress/blob/v1.16.5/LICENSE,Apache-2.0
+github.com/klauspost/compress/internal/snapref,https://github.com/klauspost/compress/blob/v1.16.5/internal\snapref\LICENSE,BSD-3-Clause
+github.com/klauspost/compress/zstd/internal/xxhash,https://github.com/klauspost/compress/blob/v1.16.5/zstd\internal\xxhash\LICENSE.txt,MIT
+github.com/klauspost/pgzip,https://github.com/klauspost/pgzip/blob/v1.2.6/LICENSE,MIT
+github.com/koron/go-ssdp,https://github.com/koron/go-ssdp/blob/v0.0.4/LICENSE,MIT
 github.com/kr/fs,https://github.com/kr/fs/blob/v0.1.0/LICENSE,BSD-3-Clause
 github.com/mholt/archiver/v3,https://github.com/mholt/archiver/blob/v3.5.1/LICENSE,MIT
-github.com/miekg/dns,https://github.com/miekg/dns/blob/v1.1.50/LICENSE,BSD-3-Clause
-github.com/mitchellh/go-homedir,https://github.com/mitchellh/go-homedir/blob/v1.1.0/LICENSE,MIT
+github.com/miekg/dns,https://github.com/miekg/dns/blob/v1.1.54/LICENSE,BSD-3-Clause
 github.com/nfnt/resize,https://github.com/nfnt/resize/blob/83c6a9932646/LICENSE,ISC
 github.com/nwaples/rardecode,https://github.com/nwaples/rardecode/blob/v1.1.3/LICENSE,BSD-2-Clause
 github.com/oliamb/cutter,https://github.com/oliamb/cutter/blob/v0.2.2/LICENSE,MIT
 github.com/oov/psd,https://github.com/oov/psd/blob/5db5eafcecbb/LICENSE,MIT
-github.com/pierrec/lz4/v4,https://github.com/pierrec/lz4/blob/v4.1.15/LICENSE,BSD-3-Clause
+github.com/pierrec/lz4/v4,https://github.com/pierrec/lz4/blob/v4.1.17/LICENSE,BSD-3-Clause
+github.com/pjbgf/sha1cd,https://github.com/pjbgf/sha1cd/blob/v0.3.0/LICENSE,Apache-2.0
 github.com/pkg/sftp,https://github.com/pkg/sftp/blob/v1.13.5/LICENSE,BSD-2-Clause
-github.com/robertkrimen/otto,https://github.com/robertkrimen/otto/blob/b87d35c0b86f/LICENSE,MIT
+github.com/robertkrimen/otto,https://github.com/robertkrimen/otto/blob/v0.2.1/LICENSE,MIT
 github.com/satori/go.uuid,https://github.com/satori/go.uuid/blob/v1.2.0/LICENSE,MIT
-github.com/sergi/go-diff/diffmatchpatch,https://github.com/sergi/go-diff/blob/v1.2.0/LICENSE,MIT
-github.com/spf13/afero,https://github.com/spf13/afero/blob/v1.9.2/LICENSE.txt,Apache-2.0
-github.com/studio-b12/gowebdav,https://github.com/studio-b12/gowebdav/blob/c7b1ff8a5e62/LICENSE,BSD-3-Clause
-github.com/tidwall/pretty,https://github.com/tidwall/pretty/blob/v1.2.0/LICENSE,MIT
-github.com/ulikunitz/xz,https://github.com/ulikunitz/xz/blob/v0.5.10/LICENSE,BSD-3-Clause
+github.com/sergi/go-diff/diffmatchpatch,https://github.com/sergi/go-diff/blob/v1.3.1/LICENSE,MIT
+github.com/skeema/knownhosts,https://github.com/skeema/knownhosts/blob/v1.1.0/LICENSE,Apache-2.0
+github.com/spf13/afero,https://github.com/spf13/afero/blob/v1.9.5/LICENSE.txt,Apache-2.0
+github.com/studio-b12/gowebdav,https://github.com/studio-b12/gowebdav/blob/3282f94193f2/LICENSE,BSD-3-Clause
+github.com/ulikunitz/xz,https://github.com/ulikunitz/xz/blob/v0.5.11/LICENSE,BSD-3-Clause
 github.com/valyala/bytebufferpool,https://github.com/valyala/bytebufferpool/blob/v1.0.0/LICENSE,MIT
-github.com/valyala/fasttemplate,https://github.com/valyala/fasttemplate/blob/v1.2.1/LICENSE,MIT
-github.com/xanzy/ssh-agent,https://github.com/xanzy/ssh-agent/blob/v0.3.2/LICENSE,Apache-2.0
+github.com/valyala/fasttemplate,https://github.com/valyala/fasttemplate/blob/v1.2.2/LICENSE,MIT
+github.com/xanzy/ssh-agent,https://github.com/xanzy/ssh-agent/blob/v0.3.3/LICENSE,Apache-2.0
 github.com/xi2/xz,Unknown,Unknown
 gitlab.com/NebulousLabs/fastrand,https://gitlab.com/NebulousLabs/fastrand/blob/603482d69e40/LICENSE,MIT
 gitlab.com/NebulousLabs/go-upnp,https://gitlab.com/NebulousLabs/go-upnp/blob/11da932010b6/LICENSE,MIT
 gitlab.com/NebulousLabs/go-upnp/goupnp,https://gitlab.com/NebulousLabs/go-upnp/blob/11da932010b6/goupnp\LICENSE,BSD-2-Clause
-golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/v0.3.0:LICENSE,BSD-3-Clause
-golang.org/x/image,https://cs.opensource.google/go/x/image/+/e7cb9697:LICENSE,BSD-3-Clause
-golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.2.0:LICENSE,BSD-3-Clause
-golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/0ebed06d:LICENSE,BSD-3-Clause
-golang.org/x/sync/syncmap,https://cs.opensource.google/go/x/sync/+/7fc1605a:LICENSE,BSD-3-Clause
-golang.org/x/sys,https://cs.opensource.google/go/x/sys/+/v0.3.0:LICENSE,BSD-3-Clause
-golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.4.0:LICENSE,BSD-3-Clause
+golang.org/x/crypto,https://cs.opensource.google/go/x/crypto/+/v0.9.0:LICENSE,BSD-3-Clause
+golang.org/x/image,https://cs.opensource.google/go/x/image/+/v0.7.0:LICENSE,BSD-3-Clause
+golang.org/x/net,https://cs.opensource.google/go/x/net/+/v0.10.0:LICENSE,BSD-3-Clause
+golang.org/x/oauth2,https://cs.opensource.google/go/x/oauth2/+/v0.8.0:LICENSE,BSD-3-Clause
+golang.org/x/sync/syncmap,https://cs.opensource.google/go/x/sync/+/v0.2.0:LICENSE,BSD-3-Clause
+golang.org/x/sys,https://cs.opensource.google/go/x/sys/+/v0.8.0:LICENSE,BSD-3-Clause
+golang.org/x/text,https://cs.opensource.google/go/x/text/+/v0.9.0:LICENSE,BSD-3-Clause
 gopkg.in/asn1-ber.v1,https://github.com/go-asn1-ber/asn1-ber/blob/f715ec2f112d/LICENSE,MIT
 gopkg.in/sourcemap.v1,https://github.com/go-sourcemap/sourcemap/blob/v1.0.5/LICENSE,BSD-2-Clause
 gopkg.in/warnings.v0,https://github.com/go-warnings/warnings/blob/v0.1.2/LICENSE,BSD-2-Clause

+ 0 - 605
web/SystemAO/storage/poolEditor.html

@@ -1,605 +0,0 @@
-<!DOCTYPE html>
-<html>
-<head>
-    <meta charset="UTF-8">
-    <link rel="stylesheet" href="../../script/semantic/semantic.min.css">
-    <script type="text/javascript" src="../../script/jquery.min.js"></script>
-    <script type="text/javascript" src="../../script/semantic/semantic.min.js"></script>
-    <script type="text/javascript" src="../../script/ao_module.js"></script>
-    <title>Storage Pool Editor</title>
-    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
-    <style>
-        body{
-            background-color:white;
-        }
-        .themebackground{
-            background-color:#242424 !important;
-            color:white !important;
-            background-image: url("../../img/system/slates/pool-slate.png") !important;
-            background-repeat: no-repeat !important;
-            background-attachment: fixed !important;
-            height:100px;
-            border: 0px solid transparent !important;
-            padding:24px !important;
-        }
-        .fshList{
-            max-height: 300px;
-            overflow-y: auto;
-        }
-
-        .controls{
-            position: absolute;
-            top: 12px;
-            right: 12px;
-        }
-
-        a{
-            cursor: pointer;
-        }
-        .false{
-            color: #eb0909;
-        }
-
-        .true{
-            color: #05b074;
-        }
-
-        .backuponly{
-            display:none;
-        }
-    </style>
-</head>
-<body>
-    <div class="ui fluid attached segment themebackground" >
-        <h24 class="ui inverted header">
-            <i class="server icon"></i>
-            <div class="content">
-                Edit Storage Pool
-            <div class="sub header">Edit storage pool and its mounted file system handlers</div>
-            </div>
-        </h4>
-    </div>
-    <br>
-    <div class="ui container">
-        <div class="ui header" id="editingGroupName"></div>
-        <p>File System Handlers currently mounted in this storage pool: </p>
-        <div class="ui divider"></div>
-        <div id="fshList">
-            
-        </div>
-        <div class="ui divider"></div>
-        
-        <div id="newfsh" style="display:none;">
-            <h3><i class="plus icon"></i> Create New File System Handler</h3>
-            <p>Invalid setting might lead to system fail to start. Please make sure your settings are valid before pressing the create button.</p>
-            <form class="ui form" action="../../system/storage/pool/newHandler" method="POST">
-                <p>Basic Virtual Disk Settings</p>
-                <div class="field" style="display: none;">
-                    <label>Group</label>
-                    <input type="text" name="group" id="groupfield" readonly="true">
-                  </div>
-                <div class="field">
-                  <label>Name</label>
-                  <input type="text" name="name" placeholder="e.g. My Folder">
-                </div>
-                <div class="field">
-                  <label>UUID</label>
-                  <input type="text" name="uuid" placeholder="e.g. myfolder">
-                </div>
-                <div class="field">
-                    <label>Path</label>
-                    <input type="text" name="path" placeholder="e.g. /media/myfolder">
-                </div>
-                <div id="accPermission" class="field">
-                    <label>Access Permission</label>
-                    <div class="ui selection dropdown">
-                        <input type="hidden" name="access" value="readwrite">
-                        <i class="dropdown icon"></i>
-                        <div class="default text">Access Permission</div>
-                        <div class="menu">
-                            <div class="item" data-value="readonly">Read Only</div>
-                            <div class="item" data-value="readwrite">Read Write</div>
-                        </div>
-                    </div>
-                </div>
-                <div class="field">
-                    <label>Storage Hierarchy</label>
-                    <div class="ui selection dropdown">
-                        <input type="hidden" autocomplete="false" name="hierarchy" value="user" onchange="handleHierarchyChange(this.value);">
-                        <i class="dropdown icon"></i>
-                        <div class="default text">Storage Hierarchy</div>
-                        <div class="menu">
-                            <div class="item" data-value="user">Isolated User Folders</div>
-                            <div class="item" data-value="public">Public Access Folders</div>
-                            <div class="item" data-value="backup">Backup Storage</div>
-                        </div>
-                    </div>
-                </div>
-                <div class="ui divider backuponly"></div>
-                <p class="backuponly">Backup Settings</p>
-                <div class="field backuponly">
-                    <label>Backup Virtual Disk UID</label>
-                    <div class="ui selection dropdown">
-                        <input type="hidden" autocomplete="false" name="parentuid" value="">
-                        <i class="dropdown icon"></i>
-                        <div class="default text">Storage Hierarchy</div>
-                        <div class="menu" id="backupIdList">
-                            
-                        </div>
-                    </div>
-                  </div>
-                  <div class="field backuponly">
-                    <label>Backup Mode</label>
-                    <div class="ui selection dropdown">
-                        <input type="hidden" autocomplete="false" name="backupmode" value="">
-                        <i class="dropdown icon"></i>
-                        <div class="default text">Storage Hierarchy</div>
-                        <div class="menu">
-                            <div class="item" data-value="basic">Basic</div>
-                            <div class="item" data-value="nightly">Nightly</div>
-                            <div class="item" data-value="version">Versioning</div>
-                        </div>
-                    </div>
-                  </div>
-                <div class="ui divider"></div>
-                <p>Physical Disks Settings</p>
-                <div class="field">
-                    <label>Filesystem Type</label>
-                    <div class="ui selection dropdown">
-                    <input type="hidden" name="filesystem" value="ntfs">
-                    <i class="dropdown icon"></i>
-                    <div class="default text">Filesystem Type</div>
-                    <div class="menu">
-                        <div class="item" data-value="ext4">EXT4</div>
-                        <div class="item" data-value="ext3">EXT3</div>
-                        <div class="item" data-value="ntfs">NTFS</div>
-                        <div class="item" data-value="vfat">VFAT</div>
-                        <div class="item" data-value="fat">FAT</div>
-                    </div>
-                    </div>
-                </div>
-                <div class="field">
-                    <label>Mount Device</label>
-                    <input type="text" name="mountdev" placeholder="e.g. /dev/sda1">
-                </div>
-                <div class="field">
-                    <label>Mount Point</label>
-                    <input type="text" name="mountpt" placeholder="e.g. /media/myfolder">
-                </div>
-
-                <div class="field">
-                  <div class="ui checkbox">
-                    <input type="checkbox" name="automount" tabindex="0" class="hidden">
-                    <label>Automount</label>
-                  </div>
-                </div>
-                <br>
-                
-                <div class="ui divider"></div>
-                <p>Security Related (if any)</p>
-                <div class="field">
-                    <label>Username</label>
-                    <input type="text" name="username" placeholder="">
-                </div>
-                <div class="field">
-                    <label>Password</label>
-                    <input type="password" name="password" placeholder="">
-                </div>
-
-                <button class="ui right floated button" onclick='event.preventDefault(); $("#newfsh").slideUp("fast"); '>Close</button>
-                <button class="ui green right floated button" type="submit">Create</button>
-                <br><br>
-              </form>
-              <div class="ui divider"></div>
-        </div>
-
-        <!-- Bridge File System Handler options -->
-        <div id="bridgeFsh" style="display:none;">
-            <h3><i class="pallet icon"></i> Edit File System Handler</h3>
-            <p>Mount Local Disk or Connect Remote Disk as File System Handler (FSH)</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>
-
-    <script>
-        //Load the editing storage pool from window hash
-        var editingStoragePool = "system"
-        var otherPoolConfigMap = {};
-        if (window.location.hash.length > 1){
-            editingStoragePool = decodeURIComponent(window.location.hash.substr(1));
-        }
-        
-        //List all the current fsh inside this pool
-        $("#editingGroupName").text(editingStoragePool);
-        loadStoragePoolForGroup(editingStoragePool);
-        $("#groupfield").val(editingStoragePool);
-
-        //Start dropdown
-        $(".ui.dropdown").dropdown();
-        $(".ui.checkbox").checkbox();
-
-        initBridgingOptions();
-
-        function toggleCreateNewFileHandler(){
-            $("#bridgeFsh").slideUp("fast");
-            $("#newfsh").slideToggle("fast", function(){
-                $(window).scrollTop($("#newfsh").offset().top - 10);
-            });
-        }
-
-        function toggleBridgeFileHandler(){
-            $("#newfsh").slideUp("fast");
-            $("#bridgeFsh").slideDown("fast", function(){
-                $(window).scrollTop($("#bridgeFsh").offset().top - 10);
-            });
-        }
-
-        function PoolAlreadyListed(uuid){
-            var alreadyExisted = false;
-            $(".fsh").each(function(){
-                if ($(this).attr("uuid") == uuid){
-                    alreadyExisted = true
-                }
-            });
-            return alreadyExisted
-        }
-
-        function done(){
-            ao_module_parentCallback(true);
-            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";
-            }else if (Hierarchy == "share"){
-                diskIcon = "violet share alternate";
-            }
-
-            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){
-            $("#fshList").html("");
-            $.get("../../system/storage/pool/list?filter=" + pgname, function(data){
-                var sp = data[0];
-                var onlineFSH = [];
-                if (sp.Storages != null){
-                    sp.Storages.forEach(storage => {
-                        var color = "green";
-                        if (storage.Closed){
-                            color = "red";
-                        }
-
-                        var usableIcon = "checkmark";
-                        if (storage.Closed){
-                            usableIcon = "remove";
-                        }
-
-                        var diskIcon = getDiskIcon(storage.Hierarchy);
-                        var storagePath = "";
-                        if (storage.Filesystem == "virtual"){
-                            storagePath = "(Virtual / Emulated File System)"
-                        }else{
-                            storagePath = storage.Path;
-                        }
-                        $("#fshList").append(`<div class="ui ${color} segment fsh" uuid="${storage.UUID}">
-                            <h3><i class="${diskIcon} icon typeicon"></i> ${storage.Name} (${storage.UUID}:/)</h3>
-                            <ol class="ui list">
-                                <li value="-"><i class="folder icon"></i> Mount Point: ${storagePath}</li>
-                                <li value="-"><i class="user icon"></i> Hierarchy: ${storage.Hierarchy}</li>
-                                <li value="-" class="${!storage.ReadOnly}"> <i class="edit icon"></i> Can Write:  ${!storage.ReadOnly}</li>
-                                <li value="-" class="${!storage.Closed}"> <i class="${usableIcon} icon"></i> Usable:  ${!storage.Closed}</li>
-                            </ol>
-                            <div class="ui active inverted dimmer oprloader" style="display:none;">
-                                <div class="ui text loader">Waiting Response</div>
-                            </div>
-                            <div class="controls">
-                                <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="Remove Handler" uuid="${storage.UUID}" group="${pgname}" onclick="removeThisFSH(this);"><i class="remove icon"></i></a>
-                            </div>
-                        </div>`);
-                        onlineFSH.push(storage.UUID);
-                    });
-
-                    $(".fsh").each(function(){
-                        if (isReservedFSH($(this).attr("uuid"))){
-                            //System storage pool. Do not allow editing
-                            $(this).find(".controls").html("System Reserved")
-                            $(this).attr("class", "ui yellow segment fsh");
-                        }
-                    });
-
-                }else{
-                    $("#fshList").append(`<p><i class="remove icon"></i> No File System Handler mounted for ${pgname}</p>`);
-                }
-                $("#fshList").append('<div class="ui divider"></div>');
-                 //Get other pools that is not mounted
-                 $.get("../../system/storage/pool/listraw?target=" + pgname, function(data){
-                        var offlineFSH = [];
-                        var allFSH = [];
-                        if (data.error == undefined){
-                            data.forEach(vroot => {
-                                if (!PoolAlreadyListed(vroot.uuid)){
-                                    $("#fshList").append(`<div class="ui black segment fsh" uuid="${vroot.uuid}">
-                                        <h3><i class="disk icon"></i> ${vroot.name} (${vroot.uuid}:/)</h3>
-                                        <ol class="ui list">
-                                            <li value="-"><i class="folder icon"></i> Mount Point: ${vroot.path}</li>
-                                            <li value="-"><i class="user icon"></i> Hierarchy: ${vroot.hierarchy}</li>
-                                            <li value="-" class="${!(vroot.access == "readonly")}"> <i class="edit icon"></i> Can Write:  ${!(vroot.access == "readonly")}</li>
-                                            <li value="-"> <i class="remove icon"></i> Not Mounted</li>
-                                        </ol>
-                                        <div class="controls">
-                                            <a title="Edit Config" uuid="${vroot.uuid}" group="${pgname}" onclick="editFSH(this);"><i class="edit icon"></i></a>
-                                            <a title="Remove Handler" uuid="${vroot.uuid}" group="${pgname}" onclick="removeThisFSH(this);"><i class="remove icon"></i></a>
-                                        </div>
-                                    </div>`);
-                                    offlineFSH.push(vroot.uuid);
-                                }
-                                allFSH.push(vroot.uuid)
-                            });
-
-                            if (data.length > 0 && offlineFSH.length == 0){
-                                //All fshandlers are online
-                                $("#fshList").append(`<p><i class="checkmark icon"></i> All File System Handlers for ${pgname} are online</p>`);
-                            }
-
-                            if (data.length == 0){
-                                $("#fshList").append(`<p><i class="checkmark icon"></i>  ${pgname} has no local File System Handler</p>`);
-                            }
-                        }else{
-                            $("#fshList").append(`<p><i class="remove icon"></i> No Unmounted File System Handler for ${pgname}</p>`);
-                        }
-
-                        //List the handlers that will be removed during next boot
-                        onlineFSH.forEach(ofsh => {
-                            if (allFSH.includes(ofsh) == false){
-                                //Currently online but not in original config. aka Delete Pending or it is bridged
-                                $(".fsh").each(function(){
-                                    if ($(this).attr("uuid") == ofsh && !isReservedFSH($(this).attr("uuid"))){
-                                        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();
-                                                    }
-                                                }
-                                            }
-                                        });
-                                    }
-                                });
-                            }
-                        });
-                    }); 
-            });
-        }
-
-        function isReservedFSH(uuid){
-            uuid = uuid.trim();
-            if (uuid == "user" || uuid == "tmp" || uuid == "share"){
-                return true;
-            }else{
-                return false;
-            }
-        }
-
-        function handleHierarchyChange(newHierarchy){
-            if (newHierarchy == "backup"){
-
-                //Force readwrite mode to read only
-                $("#accPermission").find(".dropdown").dropdown("set selected", "readonly");
-                $("#accPermission").addClass("disabled");
-
-                //Show backup only divs
-                $(".backuponly").slideDown("fast");
-
-                //Render the backup id list
-                $("#backupIdList").html(``);
-                $.get("../../system/storage/pool/list?filter=" + editingStoragePool, function(data){
-                     data.forEach(usergroup => {
-                         if (usergroup.Storages != null){
-                            usergroup.Storages.forEach(storage => {
-                                $("#backupIdList").append(`<div class="item" data-value="${storage.UUID}">${storage.Name} (${storage.UUID}:/)</div>`);
-                            })
-                        }
-                     });
-                     $("#backupIdList").parent().dropdown();
-                });
-            }else{
-                //Restore readwrite mode
-                $("#accPermission").removeClass("disabled");
-
-                 //Hide backup only divs
-                 $(".backuponly").slideUp("fast");
-                 $(".backuponly").find("input").val("");
-            }
-        }
-
-        function removeThisFSH(object){
-            var uuid = $(object).attr("uuid");
-            var group  = $(object).attr("group");
-            if (confirm("Confirm removing FSH: " + uuid + ":/ ?")){
-                $.ajax({
-                    url: "../../system/storage/pool/removeHandler",
-                    data: {uuid: uuid, group: group},
-                    success: function(data){
-                        if (data.error !== undefined){
-                            alert(data.error);
-                        }else{
-                            window.location.href = "removeSuccess.html#" + JSON.stringify([group, uuid]);
-                        }
-                        
-                    }
-                });
-            }
-           
-        }
-
-        function toggleFSH(object){
-            var uuid = $(object).attr("uuid");
-            var gpname = $(object).attr("group");
-            $(object).parent().parent().find(".oprloader").show();
-            $.ajax({
-                url: "../../system/storage/pool/toggle",
-                data: {"fsh":uuid, "group": gpname},
-                success: function(data){
-                    $(object).parent().parent().find(".oprloader").hide();
-                    if (data.error !== undefined){
-                        alert(data.error);
-                    }else{
-                        loadStoragePoolForGroup(editingStoragePool);
-                    }
-
-                }
-            })
-        }
-
-        function editFSH(object){
-            var uuid = $(object).attr("uuid");
-            var gpname = $(object).attr("group");
-
-            ao_module_newfw({
-                url:"SystemAO/storage/fshedit.html#" + encodeURIComponent(JSON.stringify({uuid: uuid, group: gpname})),
-                width: 530,
-                height: 740,
-                appicon: "SystemAO/storage/img/fsh.svg",
-                title: "Edit File System Handler",
-                callback: "finishFshEdit",
-                parent: ao_module_windowID
-            });
-        }
-
-        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(){
-            //Reload storage pool
-            loadStoragePoolForGroup(editingStoragePool);
-        }
-    </script>
-</body>
-</html>