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.

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