1
1
package lfs
2
2
3
3
import (
4
+ "context"
4
5
"crypto/sha256"
5
6
"encoding/hex"
6
7
"errors"
7
8
"io"
8
- "os"
9
9
"path/filepath"
10
10
11
11
"code.gitea.io/gitea/models"
12
+ "code.gitea.io/gitea/modules/setting"
13
+
14
+ "gocloud.dev/blob"
12
15
)
13
16
14
17
var (
@@ -24,43 +27,45 @@ type ContentStore struct {
24
27
// Get takes a Meta object and retrieves the content from the store, returning
25
28
// it as an io.Reader. If fromByte > 0, the reader starts from that byte
26
29
func (s * ContentStore ) Get (meta * models.LFSMetaObject , fromByte int64 ) (io.ReadCloser , error ) {
27
- path := filepath .Join (s .BasePath , transformKey (meta .Oid ))
28
-
29
- f , err := os .Open (path )
30
+ ctx := context .Background ()
31
+ bucket , err := blob .OpenBucket (ctx , setting .FileStorage .Bucket )
30
32
if err != nil {
31
33
return nil , err
32
34
}
33
- if fromByte > 0 {
34
- _ , err = f .Seek (fromByte , os .SEEK_CUR )
35
+ bucket = blob .PrefixedBucket (bucket , s .BasePath + "/" )
36
+
37
+ reader , err := bucket .NewRangeReader (ctx , transformKey (meta .Oid ), fromByte , meta .Size - fromByte , nil )
38
+ if err != nil {
39
+ return nil , err
35
40
}
36
- return f , err
41
+
42
+ return reader , nil
37
43
}
38
44
39
45
// Put takes a Meta object and an io.Reader and writes the content to the store.
40
46
func (s * ContentStore ) Put (meta * models.LFSMetaObject , r io.Reader ) error {
41
- path := filepath .Join (s .BasePath , transformKey (meta .Oid ))
42
- tmpPath := path + ".tmp"
43
-
44
- dir := filepath .Dir (path )
45
- if err := os .MkdirAll (dir , 0750 ); err != nil {
47
+ ctx := context .Background ()
48
+ bucket , err := blob .OpenBucket (ctx , setting .FileStorage .Bucket )
49
+ if err != nil {
46
50
return err
47
51
}
48
52
49
- file , err := os .OpenFile (tmpPath , os .O_CREATE | os .O_WRONLY | os .O_EXCL , 0640 )
53
+ bucket = blob .PrefixedBucket (bucket , s .BasePath + "/" )
54
+ defer bucket .Close ()
55
+
56
+ writer , err := bucket .NewWriter (ctx , transformKey (meta .Oid ), nil )
50
57
if err != nil {
51
58
return err
52
59
}
53
- defer os . Remove ( tmpPath )
60
+ defer writer . Close ( )
54
61
55
62
hash := sha256 .New ()
56
- hw := io .MultiWriter (hash , file )
63
+ hw := io .MultiWriter (hash , writer )
57
64
58
65
written , err := io .Copy (hw , r )
59
66
if err != nil {
60
- file .Close ()
61
67
return err
62
68
}
63
- file .Close ()
64
69
65
70
if written != meta .Size {
66
71
return errSizeMismatch
@@ -71,28 +76,44 @@ func (s *ContentStore) Put(meta *models.LFSMetaObject, r io.Reader) error {
71
76
return errHashMismatch
72
77
}
73
78
74
- return os . Rename ( tmpPath , path )
79
+ return nil
75
80
}
76
81
77
82
// Exists returns true if the object exists in the content store.
78
83
func (s * ContentStore ) Exists (meta * models.LFSMetaObject ) bool {
79
- path := filepath .Join (s .BasePath , transformKey (meta .Oid ))
80
- if _ , err := os .Stat (path ); os .IsNotExist (err ) {
84
+ ctx := context .Background ()
85
+ bucket , err := blob .OpenBucket (ctx , setting .FileStorage .Bucket )
86
+ if err != nil {
81
87
return false
82
88
}
83
- return true
89
+
90
+ bucket = blob .PrefixedBucket (bucket , s .BasePath + "/" )
91
+ defer bucket .Close ()
92
+
93
+ exist , _ := bucket .Exists (ctx , transformKey (meta .Oid ))
94
+
95
+ return exist
84
96
}
85
97
86
98
// Verify returns true if the object exists in the content store and size is correct.
87
99
func (s * ContentStore ) Verify (meta * models.LFSMetaObject ) (bool , error ) {
88
- path := filepath .Join (s .BasePath , transformKey (meta .Oid ))
100
+ ctx := context .Background ()
101
+ bucket , err := blob .OpenBucket (ctx , setting .FileStorage .Bucket )
102
+ if err != nil {
103
+ return false , err
104
+ }
105
+ bucket = blob .PrefixedBucket (bucket , s .BasePath + "/" )
106
+ defer bucket .Close ()
89
107
90
- fi , err := os .Stat (path )
91
- if os .IsNotExist (err ) || err == nil && fi .Size () != meta .Size {
92
- return false , nil
93
- } else if err != nil {
108
+ reader , err := bucket .NewReader (ctx , transformKey (meta .Oid ), nil )
109
+ if err != nil {
94
110
return false , err
95
111
}
112
+ defer reader .Close ()
113
+
114
+ if reader .Size () != meta .Size {
115
+ return false , nil
116
+ }
96
117
97
118
return true , nil
98
119
}
0 commit comments