浏览代码

Updated to nightly build v2.013

+ Optimized file system abstraction unmount logic
+ Fixed bridging bug in VM / amd64 env
+ Optimized fsh edit interface for more user friendly design
Toby Chui 2 年之前
父节点
当前提交
5eb222e756

+ 1 - 1
src/main.flags.go

@@ -29,7 +29,7 @@ var subserviceBasePort = 12810            //Next subservice port
 
 // =========== SYSTEM BUILD INFORMATION ==============
 var build_version = "development"                      //System build flag, this can be either {development / production / stable}
-var internal_version = "0.2.012"                       //Internal build version, [fork_id].[major_release_no].[minor_release_no]
+var internal_version = "0.2.013"                       //Internal build version, [fork_id].[major_release_no].[minor_release_no]
 var deviceUUID string                                  //The device uuid of this host
 var deviceVendor = "IMUSLAB.INC"                       //Vendor of the system
 var deviceVendorURL = "http://imuslab.com"             //Vendor contact information

+ 1 - 0
src/mod/filesystem/abstractions/ftpfs/ftpfs.go

@@ -179,6 +179,7 @@ func (l FTPFSAbstraction) Stat(filename string) (os.FileInfo, error) {
 	return nil, arozfs.ErrNullOperation
 }
 func (l FTPFSAbstraction) Close() error {
+	time.Sleep(500 * time.Millisecond)
 	return nil
 }
 

+ 2 - 1
src/mod/filesystem/abstractions/sftpfs/sftpfs.go

@@ -202,11 +202,12 @@ func (s SFTPFileSystemAbstraction) Close() error {
 	if err != nil {
 		return err
 	}
-
+	time.Sleep(300 * time.Millisecond)
 	err = s.conn.Close()
 	if err != nil {
 		return err
 	}
+	time.Sleep(500 * time.Millisecond)
 	return nil
 }
 

+ 6 - 1
src/mod/filesystem/abstractions/smbfs/smbfs.go

@@ -38,6 +38,11 @@ type ServerMessageBlockFileSystemAbstraction struct {
 
 func NewServerMessageBlockFileSystemAbstraction(uuid string, hierarchy string, ipaddr string, rootShare string, username string, password string) (ServerMessageBlockFileSystemAbstraction, error) {
 	log.Println("[SMB-FS] Connecting to " + uuid + ":/ (" + ipaddr + ")")
+	//Patch the ip address if port not found
+	if !strings.Contains(ipaddr, ":") {
+		log.Println("[SMB-FS] Port not set. Using default SMB port (:445)")
+		ipaddr = ipaddr + ":445" //Default port for SMB
+	}
 	nd := net.Dialer{Timeout: 10 * time.Second}
 	conn, err := nd.Dial("tcp", ipaddr)
 	if err != nil {
@@ -168,7 +173,7 @@ func (a ServerMessageBlockFileSystemAbstraction) Close() error {
 	time.Sleep(300 * time.Millisecond)
 	conn := *(a.conn)
 	conn.Close()
-
+	time.Sleep(500 * time.Millisecond)
 	return nil
 }
 

+ 1 - 0
src/mod/filesystem/abstractions/webdavfs/webdavfs.go

@@ -239,6 +239,7 @@ func (e WebDAVFileSystem) Walk(rootpath string, walkFn filepath.WalkFunc) error
 }
 
 func (e WebDAVFileSystem) Close() error {
+	time.Sleep(500 * time.Millisecond)
 	return nil
 }
 

+ 16 - 0
src/mod/storage/bridge/bridge.go

@@ -106,6 +106,22 @@ func (r *Record) IsBridgedFSH(FSHUUID string, groupOwner string) (bool, error) {
 	return false, nil
 }
 
+//Get a list of group owners that have this fsh uuid as "bridged" fs
+func (r *Record) GetBridgedGroups(FSHUUID string) []string {
+	results := []string{}
+	currentConfigs, err := r.ReadConfig()
+	if err != nil {
+		return results
+	}
+
+	for _, config := range currentConfigs {
+		if config.FSHUUID == FSHUUID {
+			results = append(results, config.SPOwner)
+		}
+	}
+	return results
+}
+
 // Write FSHConfig to disk
 func (r *Record) WriteConfig(config []*BridgeConfig) error {
 	js, _ := json.MarshalIndent(config, "", " ")

+ 3 - 2
src/mod/storage/storage.go

@@ -130,7 +130,8 @@ func (s *StoragePool) DetachFsHandler(uuid string) {
 func (s *StoragePool) Close() {
 	//For each storage pool, close it
 	for _, fsh := range s.Storages {
-		fsh.Close()
+		if !fsh.Closed {
+			fsh.Close()
+		}
 	}
-
 }

+ 37 - 0
src/storage.bridge.go

@@ -70,6 +70,42 @@ func BridgeStoragePoolForGroup(group string) {
 	}
 }
 
+//Debridge all bridged FSH from this group, origin (i.e. not bridged) fsh will be skipped
+func DebridgeAllFSHandlerFromGroup(group string) error {
+	targetSp, err := GetStoragePoolByOwner(group)
+	if err != nil {
+		return err
+	}
+
+	originFsh := []*fs.FileSystemHandler{}
+	for _, fsh := range targetSp.Storages {
+		isBridged, err := bridgeManager.IsBridgedFSH(fsh.UUID, group)
+		if err != nil {
+			return err
+		}
+
+		if !isBridged {
+			//Append the fsh that is not bridged into the origin list
+			originFsh = append(originFsh, fsh)
+		} else {
+			systemWideLogger.PrintAndLog("Storage", fsh.UUID+":/ de-bridged from "+group+" Storage Pool", nil)
+		}
+	}
+
+	targetPg := permissionHandler.GetPermissionGroupByName(group)
+	if targetPg == nil {
+		return errors.New("permission group not exists")
+	}
+
+	newSp, err := storage.NewStoragePool(originFsh, group)
+	if err != nil {
+		return err
+	}
+
+	targetPg.StoragePool = newSp
+	return nil
+}
+
 //Bridge a FSH to a given Storage Pool
 func BridgeFSHandlerToGroup(fsh *fs.FileSystemHandler, sp *storage.StoragePool) error {
 	//Check if the fsh already exists in the basepool
@@ -82,6 +118,7 @@ func BridgeFSHandlerToGroup(fsh *fs.FileSystemHandler, sp *storage.StoragePool)
 	return nil
 }
 
+//Debridge a fsh from a given group by fsh ID
 func DebridgeFSHandlerFromGroup(fshUUID string, sp *storage.StoragePool) error {
 	isBridged, err := bridgeManager.IsBridgedFSH(fshUUID, sp.Owner)
 	if err != nil || !isBridged {

+ 27 - 1
src/storage.pool.go

@@ -417,7 +417,16 @@ func HandleStoragePoolReload(w http.ResponseWriter, r *http.Request) {
 			//Pool should be exists. Close it
 			pg := permissionHandler.GetPermissionGroupByName(pool)
 
-			pg.StoragePool.Close()
+			//Record a list of uuids that reloaded, use for later checking for bridge remount
+			reloadedFshUUIDs := []string{}
+			for _, fsh := range pg.StoragePool.Storages {
+				//Close the fsh if it is not a bridged one
+				isBridged, _ := bridgeManager.IsBridgedFSH(fsh.UUID, pg.Name)
+				if !isBridged && !fsh.Closed {
+					fsh.Close()
+					reloadedFshUUIDs = append(reloadedFshUUIDs, fsh.UUID)
+				}
+			}
 
 			//Create an empty pool for this permission group
 			newEmptyPool := storage.StoragePool{}
@@ -427,6 +436,23 @@ func HandleStoragePoolReload(w http.ResponseWriter, r *http.Request) {
 			//If there is no handler in config, the empty one will be kept
 			LoadStoragePoolForGroup(pg)
 			BridgeStoragePoolForGroup(pg.Name)
+
+			//Get all the groups that have bridged the reloaded fshs
+			rebridgePendingMap := map[string]bool{}
+			for _, fshuuid := range reloadedFshUUIDs {
+				pgs := bridgeManager.GetBridgedGroups(fshuuid)
+				for _, pg := range pgs {
+					rebridgePendingMap[pg] = true
+				}
+			}
+
+			//Debridge and rebridge all the related storage pools
+			for pg, _ := range rebridgePendingMap {
+				DebridgeAllFSHandlerFromGroup(pg)
+				time.Sleep(100 * time.Millisecond)
+				BridgeStoragePoolForGroup(pg)
+			}
+
 		}
 	}
 

+ 0 - 0
src/system/ao.db.lock


+ 0 - 0
src/system/auth/authlog.db.lock


+ 0 - 6
src/web/SystemAO/file_system/file_explorer.html

@@ -1919,12 +1919,6 @@
                     protocol = "ws://";
                 }
 
-                if (path == "share:/"){
-                    //Share root do not contains any actual folder. Fallback to file based rendering
-                    startFallbackThumbnailLoader();
-                    return
-                }
-
                 var port = window.location.port;
                 if (window.location.port == ""){
                     if (location.protocol !== 'https:') {

+ 3 - 3
src/web/SystemAO/info/overview.html

@@ -103,15 +103,15 @@
             accumulateOperationTime();
         });
 
+        initHostInfo();
         initUserInfo();
         initStorageInfo();
         initHomepageState();
-        initHostInfo();
     });
 
     function initHostInfo(){
-        $.get("../../system/info/getArOZInfo", function(data){
-            $("#icon").attr('src', data.VendorIcon);
+        $.get("../../system/info/getArOZInfo?icon=true", function(data){
+            $("#icon").attr('src', 'data:image/png;base64,' + data.VendorIcon);
             $("#hostname").text(data.HostName);
             $("#version").text(data.BuildVersion);
         });

+ 42 - 15
src/web/SystemAO/storage/fshedit.html

@@ -101,7 +101,7 @@
             </div>
             <div class="field">
                 <label>Path</label>
-                <input type="text" name="path" placeholder="e.g. /media/mydrive">
+                <input type="text" name="path" placeholder="e.g. /media/mydrive" onchange="checkPathProtocol(this);">
             </div>
             <div class="field">
                 <label>Access Permission</label>
@@ -132,20 +132,20 @@
             <div class="field">
                 <label>Filesystem Type</label>
                 <div id="fstype" class="ui selection dropdown">
-                <input type="hidden" name="filesystem" value="ntfs" onchange="handleFileSystemTypeChange(this.value);">
-                <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 class="item" data-value="webdav">WebDAV</div>
-                    <div class="item" data-value="smb">SMB</div>
-                    <div class="item" data-value="ftp">FTP</div>
-                    <div class="item" data-value="sftp">SFTP</div>
-                </div>
+                    <input type="hidden" name="filesystem" value="ntfs" onchange="handleFileSystemTypeChange(this.value);">
+                    <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 class="item" data-value="webdav">WebDAV</div>
+                        <div class="item" data-value="smb">SMB</div>
+                        <div class="item" data-value="ftp">FTP</div>
+                        <div class="item" data-value="sftp">SFTP</div>
+                    </div>
                 </div>
             </div>
             <div class="localfs">
@@ -268,6 +268,33 @@
             }
         }
 
+        function checkPathProtocol(object){
+            var newPath = $(object).val();
+            if (newPath.startsWith("http://") || newPath.startsWith("https://")){
+                //WebDAV
+                $("#fstype").dropdown("set selected", "webdav");
+                newPath = newPath.replace("http://", "");
+                newPath = newPath.replace("https://", "");
+                $(object).val(newPath);
+            }else if (newPath.startsWith("ftp://")){
+                //FTP
+                $("#fstype").dropdown("set selected", "ftp");
+                newPath = newPath.replace("ftp://", "");
+                $(object).val(newPath);
+            }else if (newPath.startsWith("sftp://")){
+                //SFTP
+                $("#fstype").dropdown("set selected", "sftp");
+                newPath = newPath.replace("sftp://", "");
+                $(object).val(newPath);
+            }else if (newPath.startsWith("\\\\")){
+                //SMB, Copy directly from Windows
+                $("#fstype").dropdown("set selected", "smb");
+                newPath = newPath.replace("\\\\", "");
+                newPath = newPath.split("\\").join("/");
+                $(object).val(newPath);
+            }
+        }
+
         function handleHierarchyChange(object){
             var newHierarcy = $(object).find("input").val();
             //Force access mode to readonly if backup mode