123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- package main
- import (
- "encoding/json"
- "net/http"
- "path/filepath"
- "imuslab.com/arozos/mod/disk/hybridBackup"
- prout "imuslab.com/arozos/mod/prouter"
- )
- func backup_init() {
- //Register HybridBackup storage restore endpoints
- router := prout.NewModuleRouter(prout.RouterOption{
- AdminOnly: false,
- UserHandler: userHandler,
- DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
- sendErrorResponse(w, "Permission Denied")
- },
- })
- //Register API endpoints
- router.HandleFunc("/system/backup/listRestorable", backup_listRestorable)
- router.HandleFunc("/system/backup/restoreFile", backup_restoreSelected)
- router.HandleFunc("/system/backup/snapshotSummary", backup_renderSnapshotSummary)
- }
- //Generate a snapshot summary for vroot
- func backup_renderSnapshotSummary(w http.ResponseWriter, r *http.Request) {
- //Get user accessiable storage pools
- userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
- if err != nil {
- sendErrorResponse(w, "User not logged in")
- return
- }
- //Get Backup disk ID from request
- bdid, err := mv(r, "bdid", true)
- if err != nil {
- sendErrorResponse(w, "Invalid backup disk ID given")
- return
- }
- //Get target snapshot name from request
- snapshot, err := mv(r, "snapshot", true)
- if err != nil {
- sendErrorResponse(w, "Invalid snapshot name given")
- return
- }
- //Get fsh from the id
- fsh, err := GetFsHandlerByUUID(bdid)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- //Get parent disk hierarcy
- parentDiskID, err := userinfo.HomeDirectories.HyperBackupManager.GetParentDiskIDByRestoreDiskID(fsh.UUID)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- parentFsh, err := GetFsHandlerByUUID(parentDiskID)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- //Get task by the backup disk id
- task, err := userinfo.HomeDirectories.HyperBackupManager.GetTaskByBackupDiskID(fsh.UUID)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- if task.Mode == "version" {
- //Generate snapshot summary
- var summary *hybridBackup.SnapshotSummary
- if parentFsh.Hierarchy == "user" {
- s, err := task.GenerateSnapshotSummary(snapshot, &userinfo.Username)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- summary = s
- } else {
- s, err := task.GenerateSnapshotSummary(snapshot, nil)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- summary = s
- }
- js, _ := json.Marshal(summary)
- sendJSONResponse(w, string(js))
- } else {
- sendErrorResponse(w, "Unable to genreate snapshot summary: Backup mode is not snapshot")
- return
- }
- }
- //Restore a given file
- func backup_restoreSelected(w http.ResponseWriter, r *http.Request) {
- //Get user accessiable storage pools
- userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
- if err != nil {
- sendErrorResponse(w, "User not logged in")
- return
- }
- //Get Backup disk ID from request
- bdid, err := mv(r, "bdid", true)
- if err != nil {
- sendErrorResponse(w, "Invalid backup disk ID given")
- return
- }
- //Get fsh from the id
- fsh, err := GetFsHandlerByUUID(bdid)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- //Get the relative path for the restorable file
- relpath, err := mv(r, "relpath", true)
- if err != nil {
- sendErrorResponse(w, "Invalid relative path given")
- return
- }
- //Handle restore of the file
- err = userinfo.HomeDirectories.HyperBackupManager.HandleRestore(fsh.UUID, relpath, &userinfo.Username)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- type RestoreResult struct {
- RestoreDiskID string
- TargetDiskID string
- RestoredVirtualPath string
- }
- result := RestoreResult{
- RestoreDiskID: fsh.UUID,
- }
- //Get access path for this file
- parentDiskId, err := userinfo.HomeDirectories.HyperBackupManager.GetParentDiskIDByRestoreDiskID(fsh.UUID)
- if err != nil {
- //Unable to get parent disk ID???
- } else {
- //Get the path of the parent disk
- parentDiskHandler, err := GetFsHandlerByUUID(parentDiskId)
- if err == nil {
- //Join the result to create a virtual path
- assumedRestoreRealPath := filepath.ToSlash(filepath.Join(parentDiskHandler.Path, relpath))
- restoreVpath, err := userinfo.RealPathToVirtualPath(assumedRestoreRealPath)
- if err == nil {
- result.RestoredVirtualPath = restoreVpath
- }
- result.TargetDiskID = parentDiskId
- }
- }
- js, _ := json.Marshal(result)
- sendJSONResponse(w, string(js))
- }
- //Generate and return a restorable report
- func backup_listRestorable(w http.ResponseWriter, r *http.Request) {
- //Get user accessiable storage pools
- userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
- if err != nil {
- sendErrorResponse(w, "User not logged in")
- return
- }
- //Get Vroot ID from request
- vroot, err := mv(r, "vroot", true)
- if err != nil {
- sendErrorResponse(w, "Invalid vroot given")
- return
- }
- //Get fsh from the id
- fsh, err := GetFsHandlerByUUID(vroot)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- userBackupManager := userinfo.HomeDirectories.HyperBackupManager
- //Get the user's storage pool and list restorable by the user's storage pool access
- restorableReport, err := userBackupManager.ListRestorable(fsh.UUID)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- //Get and check if the parent disk has a user Hierarcy
- paretnfsh, err := GetFsHandlerByUUID(restorableReport.ParentUID)
- if err != nil {
- sendErrorResponse(w, err.Error())
- return
- }
- result := hybridBackup.RestorableReport{
- ParentUID: restorableReport.ParentUID,
- RestorableFiles: []*hybridBackup.RestorableFile{},
- }
- if paretnfsh.Hierarchy == "user" {
- //The file system is user based. Filter out those file that is not belong to this user
- for _, restorableFile := range restorableReport.RestorableFiles {
- if restorableFile.IsSnapshot {
- //Is snapshot. Always allow access
- result.RestorableFiles = append(result.RestorableFiles, restorableFile)
- } else {
- //Is file
- fileAbsPath := filepath.Join(fsh.Path, restorableFile.RelpathOnDisk)
- _, err := userinfo.RealPathToVirtualPath(fileAbsPath)
- if err != nil {
- //Cannot translate this file. That means the file is not owned by this user
- } else {
- //Can translate the path.
- result.RestorableFiles = append(result.RestorableFiles, restorableFile)
- }
- }
- }
- } else {
- result = restorableReport
- }
- js, _ := json.Marshal(result)
- sendJSONResponse(w, string(js))
- }
|