git.sr.ht/~pingoo/stdx@v0.0.0-20240218134121-094174641f6e/storage/minio/minio.go (about) 1 package minio 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "net/http" 8 "path/filepath" 9 10 "github.com/minio/minio-go/v7" 11 "github.com/minio/minio-go/v7/pkg/credentials" 12 ) 13 14 type MinioStorage struct { 15 basePath string 16 minioClient *minio.Client 17 bucket string 18 } 19 20 type Config struct { 21 AccessKeyID string 22 SecretAccessKey string 23 Endpoint string 24 Region string 25 BaseDirectory string 26 Bucket string 27 HttpClient *http.Client 28 } 29 30 func NewMinioStorage(config Config) (*MinioStorage, error) { 31 clientOptions := &minio.Options{ 32 Creds: credentials.NewStaticV4(config.AccessKeyID, config.SecretAccessKey, ""), 33 Secure: true, 34 } 35 if config.HttpClient != nil { 36 clientOptions.Transport = config.HttpClient.Transport 37 } 38 39 minioClient, err := minio.New(config.Endpoint, clientOptions) 40 if err != nil { 41 err = fmt.Errorf("miniostorage: building minio client: %w", err) 42 return nil, err 43 } 44 45 return &MinioStorage{ 46 basePath: config.BaseDirectory, 47 minioClient: minioClient, 48 bucket: config.Bucket, 49 }, nil 50 } 51 52 func (storage *MinioStorage) BasePath() string { 53 return storage.basePath 54 } 55 56 func (storage *MinioStorage) CopyObject(ctx context.Context, from string, to string) error { 57 from = filepath.Join(storage.basePath, from) 58 to = filepath.Join(storage.basePath, from) 59 60 fromOptions := minio.CopySrcOptions{ 61 Bucket: storage.bucket, 62 Object: from, 63 } 64 toOptions := minio.CopyDestOptions{ 65 Bucket: storage.bucket, 66 Object: to, 67 } 68 _, err := storage.minioClient.CopyObject(ctx, toOptions, fromOptions) 69 70 if err != nil { 71 return err 72 } 73 74 return nil 75 } 76 77 func (storage *MinioStorage) DeleteObject(ctx context.Context, key string) error { 78 objectKey := filepath.Join(storage.basePath, key) 79 80 err := storage.minioClient.RemoveObject(ctx, storage.bucket, objectKey, minio.RemoveObjectOptions{}) 81 if err != nil { 82 return err 83 } 84 85 return nil 86 } 87 88 func (storage *MinioStorage) GetObject(ctx context.Context, key string) (io.ReadCloser, error) { 89 objectKey := filepath.Join(storage.basePath, key) 90 91 object, err := storage.minioClient.GetObject(ctx, storage.bucket, objectKey, minio.GetObjectOptions{}) 92 if err != nil { 93 return nil, err 94 } 95 96 return object, nil 97 } 98 99 func (storage *MinioStorage) GetObjectSize(ctx context.Context, key string) (int64, error) { 100 objectKey := filepath.Join(storage.basePath, key) 101 102 info, err := storage.minioClient.StatObject(ctx, storage.bucket, objectKey, minio.GetObjectOptions{}) 103 if err != nil { 104 return 0, err 105 } 106 107 return info.Size, nil 108 } 109 110 // func (storage *S3Storage) GetPresignedUploadUrl(ctx context.Context, key string, size uint64) (string, error) { 111 // objectKey := filepath.Join(storage.basePath, key) 112 113 // req, _ := storage.s3Client.PutObjectRequest(&s3.PutObjectInput{ 114 // Bucket: aws.String(storage.bucket), 115 // Key: aws.String(objectKey), 116 // ContentLength: aws.Int64(int64(size)), 117 // }) 118 119 // url, err := req.Presign(2 * time.Hour) 120 // if err != nil { 121 // return "", err 122 // } 123 124 // return url, nil 125 // } 126 127 func (storage *MinioStorage) PutObject(ctx context.Context, key string, contentType string, size int64, object io.Reader) error { 128 objectKey := filepath.Join(storage.basePath, key) 129 130 _, err := storage.minioClient.PutObject(ctx, storage.bucket, objectKey, object, size, minio.PutObjectOptions{ 131 ContentType: contentType, 132 }) 133 if err != nil { 134 return err 135 } 136 137 return nil 138 } 139 140 func (storage *MinioStorage) DeleteObjectsWithPrefix(ctx context.Context, prefix string) (err error) { 141 s3Prefix := filepath.Join(storage.basePath, prefix) 142 143 objectsChan := storage.minioClient.ListObjects(ctx, storage.bucket, minio.ListObjectsOptions{ 144 Prefix: s3Prefix, 145 }) 146 147 removeObjectsErrors := storage.minioClient.RemoveObjects(ctx, storage.bucket, objectsChan, minio.RemoveObjectsOptions{}) 148 149 for removeObjectsError := range removeObjectsErrors { 150 if removeObjectsError.Err != nil { 151 err = removeObjectsError.Err 152 return 153 } 154 } 155 156 return 157 }