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.

131 lines
3.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
  1. package s3_backend
  2. import (
  3. "fmt"
  4. "os"
  5. "strings"
  6. "time"
  7. "github.com/aws/aws-sdk-go/service/s3"
  8. "github.com/aws/aws-sdk-go/service/s3/s3iface"
  9. "github.com/chrislusf/seaweedfs/weed/glog"
  10. "github.com/chrislusf/seaweedfs/weed/storage/backend"
  11. "github.com/chrislusf/seaweedfs/weed/util"
  12. )
  13. func init() {
  14. backend.BackendStorageFactories["s3"] = &S3BackendFactory{}
  15. }
  16. type S3BackendFactory struct {
  17. }
  18. func (factory *S3BackendFactory) StorageType() backend.StorageType {
  19. return backend.StorageType("s3")
  20. }
  21. func (factory *S3BackendFactory) BuildStorage(configuration util.Configuration, id string) (backend.BackendStorage, error) {
  22. return newS3BackendStorage(configuration, id)
  23. }
  24. type S3BackendStorage struct {
  25. id string
  26. conn s3iface.S3API
  27. region string
  28. bucket string
  29. }
  30. func newS3BackendStorage(configuration util.Configuration, id string) (s *S3BackendStorage, err error) {
  31. s = &S3BackendStorage{}
  32. s.id = id
  33. s.conn, err = createSession(
  34. configuration.GetString("aws_access_key_id"),
  35. configuration.GetString("aws_secret_access_key"),
  36. configuration.GetString("region"))
  37. s.region = configuration.GetString("region")
  38. s.bucket = configuration.GetString("bucket")
  39. glog.V(0).Infof("created s3 backend storage %s for region %s bucket %s", s.Name(), s.region, s.bucket)
  40. return
  41. }
  42. func (s *S3BackendStorage) Name() string {
  43. return "s3." + s.id
  44. }
  45. func (s *S3BackendStorage) NewStorageFile(key string) backend.BackendStorageFile {
  46. if strings.HasPrefix(key, "/") {
  47. key = key[1:]
  48. }
  49. f := &S3BackendStorageFile{
  50. backendStorage: s,
  51. key: key,
  52. }
  53. return f
  54. }
  55. type S3BackendStorageFile struct {
  56. backendStorage *S3BackendStorage
  57. key string
  58. }
  59. func (s3backendStorageFile S3BackendStorageFile) ReadAt(p []byte, off int64) (n int, err error) {
  60. bytesRange := fmt.Sprintf("bytes=%d-%d", off, off+int64(len(p))-1)
  61. getObjectOutput, getObjectErr := s3backendStorageFile.backendStorage.conn.GetObject(&s3.GetObjectInput{
  62. Bucket: &s3backendStorageFile.backendStorage.bucket,
  63. Key: &s3backendStorageFile.key,
  64. Range: &bytesRange,
  65. })
  66. if getObjectErr != nil {
  67. return 0, fmt.Errorf("bucket %s GetObject %s: %v",
  68. s3backendStorageFile.backendStorage.bucket, s3backendStorageFile.key, getObjectErr)
  69. }
  70. defer getObjectOutput.Body.Close()
  71. return getObjectOutput.Body.Read(p)
  72. }
  73. func (s3backendStorageFile S3BackendStorageFile) WriteAt(p []byte, off int64) (n int, err error) {
  74. panic("implement me")
  75. }
  76. func (s3backendStorageFile S3BackendStorageFile) Truncate(off int64) error {
  77. panic("implement me")
  78. }
  79. func (s3backendStorageFile S3BackendStorageFile) Close() error {
  80. return nil
  81. }
  82. func (s3backendStorageFile S3BackendStorageFile) GetStat() (datSize int64, modTime time.Time, err error) {
  83. headObjectOutput, headObjectErr := s3backendStorageFile.backendStorage.conn.HeadObject(&s3.HeadObjectInput{
  84. Bucket: &s3backendStorageFile.backendStorage.bucket,
  85. Key: &s3backendStorageFile.key,
  86. })
  87. if headObjectErr != nil {
  88. return 0, time.Now(), fmt.Errorf("bucket %s HeadObject %s: %v",
  89. s3backendStorageFile.backendStorage.bucket, s3backendStorageFile.key, headObjectErr)
  90. }
  91. datSize = int64(*headObjectOutput.ContentLength)
  92. modTime = *headObjectOutput.LastModified
  93. return
  94. }
  95. func (s3backendStorageFile S3BackendStorageFile) String() string {
  96. return s3backendStorageFile.key
  97. }
  98. func (s3backendStorageFile *S3BackendStorageFile) GetName() string {
  99. return "s3"
  100. }
  101. func (s3backendStorageFile S3BackendStorageFile) Instantiate(src *os.File) error {
  102. panic("implement me")
  103. }