You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

228 lines
5.5 KiB

5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
5 years ago
  1. package filer_pb
  2. import (
  3. "context"
  4. "errors"
  5. "fmt"
  6. "io"
  7. "math"
  8. "os"
  9. "time"
  10. "github.com/chrislusf/seaweedfs/weed/glog"
  11. "github.com/chrislusf/seaweedfs/weed/util"
  12. )
  13. var (
  14. OS_UID = uint32(os.Getuid())
  15. OS_GID = uint32(os.Getgid())
  16. )
  17. type FilerClient interface {
  18. WithFilerClient(fn func(SeaweedFilerClient) error) error
  19. AdjustedUrl(hostAndPort string) string
  20. }
  21. func GetEntry(filerClient FilerClient, fullFilePath util.FullPath) (entry *Entry, err error) {
  22. dir, name := fullFilePath.DirAndName()
  23. err = filerClient.WithFilerClient(func(client SeaweedFilerClient) error {
  24. request := &LookupDirectoryEntryRequest{
  25. Directory: dir,
  26. Name: name,
  27. }
  28. // glog.V(3).Infof("read %s request: %v", fullFilePath, request)
  29. resp, err := LookupEntry(client, request)
  30. if err != nil {
  31. if err == ErrNotFound {
  32. return nil
  33. }
  34. glog.V(3).Infof("read %s %v: %v", fullFilePath, resp, err)
  35. return err
  36. }
  37. if resp.Entry == nil {
  38. // glog.V(3).Infof("read %s entry: %v", fullFilePath, entry)
  39. return nil
  40. }
  41. entry = resp.Entry
  42. return nil
  43. })
  44. return
  45. }
  46. func ReadDirAllEntries(filerClient FilerClient, fullDirPath util.FullPath, prefix string, fn func(entry *Entry, isLast bool)) (err error) {
  47. return doList(filerClient, fullDirPath, prefix, fn, "", false, math.MaxUint32)
  48. }
  49. func List(filerClient FilerClient, parentDirectoryPath, prefix string, fn func(entry *Entry, isLast bool), startFrom string, inclusive bool, limit uint32) (err error) {
  50. return doList(filerClient, util.FullPath(parentDirectoryPath), prefix, fn, startFrom, inclusive, limit)
  51. }
  52. func doList(filerClient FilerClient, fullDirPath util.FullPath, prefix string, fn func(entry *Entry, isLast bool), startFrom string, inclusive bool, limit uint32) (err error) {
  53. err = filerClient.WithFilerClient(func(client SeaweedFilerClient) error {
  54. request := &ListEntriesRequest{
  55. Directory: string(fullDirPath),
  56. Prefix: prefix,
  57. StartFromFileName: startFrom,
  58. Limit: limit,
  59. InclusiveStartFrom: inclusive,
  60. }
  61. glog.V(3).Infof("read directory: %v", request)
  62. stream, err := client.ListEntries(context.Background(), request)
  63. if err != nil {
  64. return fmt.Errorf("list %s: %v", fullDirPath, err)
  65. }
  66. var prevEntry *Entry
  67. for {
  68. resp, recvErr := stream.Recv()
  69. if recvErr != nil {
  70. if recvErr == io.EOF {
  71. if prevEntry != nil {
  72. fn(prevEntry, true)
  73. }
  74. break
  75. } else {
  76. return recvErr
  77. }
  78. }
  79. if prevEntry != nil {
  80. fn(prevEntry, false)
  81. }
  82. prevEntry = resp.Entry
  83. }
  84. return nil
  85. })
  86. return
  87. }
  88. func Exists(filerClient FilerClient, parentDirectoryPath string, entryName string, isDirectory bool) (exists bool, err error) {
  89. err = filerClient.WithFilerClient(func(client SeaweedFilerClient) error {
  90. request := &LookupDirectoryEntryRequest{
  91. Directory: parentDirectoryPath,
  92. Name: entryName,
  93. }
  94. glog.V(4).Infof("exists entry %v/%v: %v", parentDirectoryPath, entryName, request)
  95. resp, err := LookupEntry(client, request)
  96. if err != nil {
  97. if err == ErrNotFound {
  98. exists = false
  99. return nil
  100. }
  101. glog.V(0).Infof("exists entry %v: %v", request, err)
  102. return fmt.Errorf("exists entry %s/%s: %v", parentDirectoryPath, entryName, err)
  103. }
  104. exists = resp.Entry.IsDirectory == isDirectory
  105. return nil
  106. })
  107. return
  108. }
  109. func Mkdir(filerClient FilerClient, parentDirectoryPath string, dirName string, fn func(entry *Entry)) error {
  110. return filerClient.WithFilerClient(func(client SeaweedFilerClient) error {
  111. entry := &Entry{
  112. Name: dirName,
  113. IsDirectory: true,
  114. Attributes: &FuseAttributes{
  115. Mtime: time.Now().Unix(),
  116. Crtime: time.Now().Unix(),
  117. FileMode: uint32(0777 | os.ModeDir),
  118. Uid: OS_UID,
  119. Gid: OS_GID,
  120. },
  121. }
  122. if fn != nil {
  123. fn(entry)
  124. }
  125. request := &CreateEntryRequest{
  126. Directory: parentDirectoryPath,
  127. Entry: entry,
  128. }
  129. glog.V(1).Infof("mkdir: %v", request)
  130. if err := CreateEntry(client, request); err != nil {
  131. glog.V(0).Infof("mkdir %v: %v", request, err)
  132. return fmt.Errorf("mkdir %s/%s: %v", parentDirectoryPath, dirName, err)
  133. }
  134. return nil
  135. })
  136. }
  137. func MkFile(filerClient FilerClient, parentDirectoryPath string, fileName string, chunks []*FileChunk) error {
  138. return filerClient.WithFilerClient(func(client SeaweedFilerClient) error {
  139. entry := &Entry{
  140. Name: fileName,
  141. IsDirectory: false,
  142. Attributes: &FuseAttributes{
  143. Mtime: time.Now().Unix(),
  144. Crtime: time.Now().Unix(),
  145. FileMode: uint32(0770),
  146. Uid: OS_UID,
  147. Gid: OS_GID,
  148. },
  149. Chunks: chunks,
  150. }
  151. request := &CreateEntryRequest{
  152. Directory: parentDirectoryPath,
  153. Entry: entry,
  154. }
  155. glog.V(1).Infof("create file: %s/%s", parentDirectoryPath, fileName)
  156. if err := CreateEntry(client, request); err != nil {
  157. glog.V(0).Infof("create file %v:%v", request, err)
  158. return fmt.Errorf("create file %s/%s: %v", parentDirectoryPath, fileName, err)
  159. }
  160. return nil
  161. })
  162. }
  163. func Remove(filerClient FilerClient, parentDirectoryPath string, name string, isDeleteData, isRecursive, ignoreRecursiveErr bool) error {
  164. return filerClient.WithFilerClient(func(client SeaweedFilerClient) error {
  165. if resp, err := client.DeleteEntry(context.Background(), &DeleteEntryRequest{
  166. Directory: parentDirectoryPath,
  167. Name: name,
  168. IsDeleteData: isDeleteData,
  169. IsRecursive: isRecursive,
  170. IgnoreRecursiveError: ignoreRecursiveErr,
  171. }); err != nil {
  172. return err
  173. } else {
  174. if resp.Error != "" {
  175. return errors.New(resp.Error)
  176. }
  177. }
  178. return nil
  179. })
  180. }