diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2020-09-08 23:45:10 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2020-09-08 23:45:10 +0800 |
commit | 7a5465fc56f79f5fc3c32547c89a80b7ebb24c8f (patch) | |
tree | c663ce5f0f37e13d950384fd76428c422adfb06d /modules/storage | |
parent | e4b3f35b8d68d6409a280a8e644759e10b091cb1 (diff) | |
download | gitea-7a5465fc56f79f5fc3c32547c89a80b7ebb24c8f.tar.gz gitea-7a5465fc56f79f5fc3c32547c89a80b7ebb24c8f.zip |
LFS support to be stored on minio (#12518)
* LFS support to be stored on minio
* Fix test
* Fix lint
* Fix lint
* Fix check
* Fix test
* Update documents and add migration for LFS
* Fix some bugs
Diffstat (limited to 'modules/storage')
-rw-r--r-- | modules/storage/local.go | 7 | ||||
-rw-r--r-- | modules/storage/minio.go | 38 | ||||
-rw-r--r-- | modules/storage/storage.go | 56 |
3 files changed, 98 insertions, 3 deletions
diff --git a/modules/storage/local.go b/modules/storage/local.go index 4c830211d9..a937a831f1 100644 --- a/modules/storage/local.go +++ b/modules/storage/local.go @@ -34,7 +34,7 @@ func NewLocalStorage(bucket string) (*LocalStorage, error) { } // Open a file -func (l *LocalStorage) Open(path string) (io.ReadCloser, error) { +func (l *LocalStorage) Open(path string) (Object, error) { return os.Open(filepath.Join(l.dir, path)) } @@ -58,6 +58,11 @@ func (l *LocalStorage) Save(path string, r io.Reader) (int64, error) { return io.Copy(f, r) } +// Stat returns the info of the file +func (l *LocalStorage) Stat(path string) (ObjectInfo, error) { + return os.Stat(filepath.Join(l.dir, path)) +} + // Delete delete a file func (l *LocalStorage) Delete(path string) error { p := filepath.Join(l.dir, path) diff --git a/modules/storage/minio.go b/modules/storage/minio.go index 77d24e6b73..30751755f3 100644 --- a/modules/storage/minio.go +++ b/modules/storage/minio.go @@ -8,6 +8,7 @@ import ( "context" "io" "net/url" + "os" "path" "strings" "time" @@ -62,7 +63,7 @@ func (m *MinioStorage) buildMinioPath(p string) string { } // Open open a file -func (m *MinioStorage) Open(path string) (io.ReadCloser, error) { +func (m *MinioStorage) Open(path string) (Object, error) { var opts = minio.GetObjectOptions{} object, err := m.client.GetObject(m.ctx, m.bucket, m.buildMinioPath(path), opts) if err != nil { @@ -87,6 +88,41 @@ func (m *MinioStorage) Save(path string, r io.Reader) (int64, error) { return uploadInfo.Size, nil } +type minioFileInfo struct { + minio.ObjectInfo +} + +func (m minioFileInfo) Name() string { + return m.ObjectInfo.Key +} + +func (m minioFileInfo) Size() int64 { + return m.ObjectInfo.Size +} + +func (m minioFileInfo) ModTime() time.Time { + return m.LastModified +} + +// Stat returns the stat information of the object +func (m *MinioStorage) Stat(path string) (ObjectInfo, error) { + info, err := m.client.StatObject( + m.ctx, + m.bucket, + m.buildMinioPath(path), + minio.StatObjectOptions{}, + ) + if err != nil { + if errResp, ok := err.(minio.ErrorResponse); ok { + if errResp.Code == "NoSuchKey" { + return nil, os.ErrNotExist + } + } + return nil, err + } + return &minioFileInfo{info}, nil +} + // Delete delete a file func (m *MinioStorage) Delete(path string) error { return m.client.RemoveObject(m.ctx, m.bucket, m.buildMinioPath(path), minio.RemoveObjectOptions{}) diff --git a/modules/storage/storage.go b/modules/storage/storage.go index 8528ebc5cb..e355d2459f 100644 --- a/modules/storage/storage.go +++ b/modules/storage/storage.go @@ -10,6 +10,7 @@ import ( "fmt" "io" "net/url" + "time" "code.gitea.io/gitea/modules/setting" ) @@ -19,10 +20,24 @@ var ( ErrURLNotSupported = errors.New("url method not supported") ) +// Object represents the object on the storage +type Object interface { + io.ReadCloser + io.Seeker +} + +// ObjectInfo represents the object info on the storage +type ObjectInfo interface { + Name() string + Size() int64 + ModTime() time.Time +} + // ObjectStorage represents an object storage to handle a bucket and files type ObjectStorage interface { + Open(path string) (Object, error) Save(path string, r io.Reader) (int64, error) - Open(path string) (io.ReadCloser, error) + Stat(path string) (ObjectInfo, error) Delete(path string) error URL(path, name string) (*url.URL, error) } @@ -41,10 +56,21 @@ func Copy(dstStorage ObjectStorage, dstPath string, srcStorage ObjectStorage, sr var ( // Attachments represents attachments storage Attachments ObjectStorage + + // LFS represents lfs storage + LFS ObjectStorage ) // Init init the stoarge func Init() error { + if err := initAttachments(); err != nil { + return err + } + + return initLFS() +} + +func initAttachments() error { var err error switch setting.Attachment.StoreType { case "local": @@ -71,3 +97,31 @@ func Init() error { return nil } + +func initLFS() error { + var err error + switch setting.LFS.StoreType { + case "local": + LFS, err = NewLocalStorage(setting.LFS.ContentPath) + case "minio": + minio := setting.LFS.Minio + LFS, err = NewMinioStorage( + context.Background(), + minio.Endpoint, + minio.AccessKeyID, + minio.SecretAccessKey, + minio.Bucket, + minio.Location, + minio.BasePath, + minio.UseSSL, + ) + default: + return fmt.Errorf("Unsupported LFS store type: %s", setting.LFS.StoreType) + } + + if err != nil { + return err + } + + return nil +} |