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  }