aboutsummaryrefslogtreecommitdiffstats
path: root/modules/storage
diff options
context:
space:
mode:
authorLunny Xiao <xiaolunwen@gmail.com>2020-09-08 23:45:10 +0800
committerGitHub <noreply@github.com>2020-09-08 23:45:10 +0800
commit7a5465fc56f79f5fc3c32547c89a80b7ebb24c8f (patch)
treec663ce5f0f37e13d950384fd76428c422adfb06d /modules/storage
parente4b3f35b8d68d6409a280a8e644759e10b091cb1 (diff)
downloadgitea-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.go7
-rw-r--r--modules/storage/minio.go38
-rw-r--r--modules/storage/storage.go56
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
+}