backup.go 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169
  1. package main
  2. import (
  3. "encoding/json"
  4. "log"
  5. "net/http"
  6. "path/filepath"
  7. "imuslab.com/arozos/mod/disk/hybridBackup"
  8. prout "imuslab.com/arozos/mod/prouter"
  9. )
  10. func backup_init() {
  11. //Register HybridBackup storage restore endpoints
  12. router := prout.NewModuleRouter(prout.RouterOption{
  13. AdminOnly: false,
  14. UserHandler: userHandler,
  15. DeniedHandler: func(w http.ResponseWriter, r *http.Request) {
  16. sendErrorResponse(w, "Permission Denied")
  17. },
  18. })
  19. //Register API endpoints
  20. router.HandleFunc("/system/backup/listRestorable", backup_listRestorable)
  21. router.HandleFunc("/system/backup/restoreFile", backup_restoreSelected)
  22. }
  23. //Restore a given file
  24. func backup_restoreSelected(w http.ResponseWriter, r *http.Request) {
  25. //Get user accessiable storage pools
  26. userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  27. if err != nil {
  28. sendErrorResponse(w, "User not logged in")
  29. return
  30. }
  31. //Get Backup disk ID from request
  32. bdid, err := mv(r, "bdid", true)
  33. if err != nil {
  34. sendErrorResponse(w, "Invalid backup disk ID given")
  35. return
  36. }
  37. //Get fsh from the id
  38. fsh, err := GetFsHandlerByUUID(bdid)
  39. if err != nil {
  40. sendErrorResponse(w, err.Error())
  41. return
  42. }
  43. //Get the relative path for the restorable file
  44. relpath, err := mv(r, "relpath", true)
  45. if err != nil {
  46. sendErrorResponse(w, "Invalid relative path given")
  47. return
  48. }
  49. //Check if the path exists in the backup disk
  50. if !fileExists(filepath.Join(fsh.Path, relpath)) {
  51. sendErrorResponse(w, "Restore source file not exists")
  52. return
  53. }
  54. //Handle restore of the file
  55. err = userinfo.HomeDirectories.HyperBackupManager.HandleRestore(fsh.UUID, relpath)
  56. if err != nil {
  57. sendErrorResponse(w, err.Error())
  58. return
  59. }
  60. type RestoreResult struct {
  61. RestoreDiskID string
  62. TargetDiskID string
  63. RestoredVirtualPath string
  64. }
  65. result := RestoreResult{
  66. RestoreDiskID: fsh.UUID,
  67. }
  68. //Get access path for this file
  69. parentDiskId, err := userinfo.HomeDirectories.HyperBackupManager.GetParentDiskIDByRestoreDiskID(fsh.UUID)
  70. if err != nil {
  71. //Unable to get parent disk ID???
  72. } else {
  73. //Get the path of the parent disk
  74. parentDiskHandler, err := GetFsHandlerByUUID(parentDiskId)
  75. if err == nil {
  76. //Join the result to create a virtual path
  77. assumedRestoreRealPath := filepath.ToSlash(filepath.Join(parentDiskHandler.Path, relpath))
  78. restoreVpath, err := userinfo.RealPathToVirtualPath(assumedRestoreRealPath)
  79. if err == nil {
  80. result.RestoredVirtualPath = restoreVpath
  81. }
  82. result.TargetDiskID = parentDiskId
  83. }
  84. }
  85. js, _ := json.Marshal(result)
  86. sendJSONResponse(w, string(js))
  87. }
  88. //Generate and return a restorable report
  89. func backup_listRestorable(w http.ResponseWriter, r *http.Request) {
  90. //Get user accessiable storage pools
  91. userinfo, err := userHandler.GetUserInfoFromRequest(w, r)
  92. if err != nil {
  93. sendErrorResponse(w, "User not logged in")
  94. return
  95. }
  96. //Get Vroot ID from request
  97. vroot, err := mv(r, "vroot", true)
  98. if err != nil {
  99. sendErrorResponse(w, "Invalid vroot given")
  100. return
  101. }
  102. //Get fsh from the id
  103. fsh, err := GetFsHandlerByUUID(vroot)
  104. if err != nil {
  105. sendErrorResponse(w, err.Error())
  106. return
  107. }
  108. userBackupManager := userinfo.HomeDirectories.HyperBackupManager
  109. //Get the user's storage pool and list restorable by the user's storage pool access
  110. restorableReport, err := userBackupManager.ListRestorable(fsh.UUID)
  111. if err != nil {
  112. sendErrorResponse(w, err.Error())
  113. return
  114. }
  115. //Get and check if the parent disk has a user Hierarcy
  116. paretnfsh, err := GetFsHandlerByUUID(restorableReport.ParentUID)
  117. if err != nil {
  118. sendErrorResponse(w, err.Error())
  119. return
  120. }
  121. result := hybridBackup.RestorableReport{
  122. ParentUID: restorableReport.ParentUID,
  123. }
  124. log.Println(paretnfsh)
  125. if paretnfsh.Hierarchy == "user" {
  126. //The file system is user based. Filter out those file that is not belong to this user
  127. for _, restorableFile := range restorableReport.RestorableFiles {
  128. fileAbsPath := filepath.Join(fsh.Path, restorableFile.RelpathOnDisk)
  129. _, err := userinfo.RealPathToVirtualPath(fileAbsPath)
  130. if err != nil {
  131. //Cannot translate this file. That means the file is not owned by this user
  132. } else {
  133. //Can translate the path.
  134. result.RestorableFiles = append(result.RestorableFiles, restorableFile)
  135. }
  136. }
  137. } else {
  138. result = restorableReport
  139. }
  140. js, _ := json.Marshal(result)
  141. sendJSONResponse(w, string(js))
  142. }