Skip to content

Commit c53873e

Browse files
committed
all: oss: ListObjects should treat prefix as a dir
See: - helm/chartmuseum#1082 - helm/chartmuseum#794 Signed-off-by: scnace <[email protected]>
1 parent 50864e2 commit c53873e

File tree

11 files changed

+78
-94
lines changed

11 files changed

+78
-94
lines changed

alibaba.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,6 @@ func NewAlibabaCloudOSSBackend(bucket string, prefix string, endpoint string, ss
5353
}
5454

5555
client, err := oss.New(endpoint, accessKeyId, accessKeySecret)
56-
5756
if err != nil {
5857
panic("Failed to create OSS client: " + err.Error())
5958
}
@@ -76,7 +75,7 @@ func NewAlibabaCloudOSSBackend(bucket string, prefix string, endpoint string, ss
7675
func (b AlibabaCloudOSSBackend) ListObjects(prefix string) ([]Object, error) {
7776
var objects []Object
7877

79-
prefix = pathutil.Join(b.Prefix, prefix)
78+
prefix = pathutil.Join(b.Prefix, normalizePath(prefix))
8079
ossPrefix := oss.Prefix(prefix)
8180
marker := oss.Marker("")
8281
for {
@@ -113,7 +112,6 @@ func (b AlibabaCloudOSSBackend) GetObject(path string) (Object, error) {
113112
var content []byte
114113
key := pathutil.Join(b.Prefix, path)
115114
body, err := b.Bucket.GetObject(key)
116-
117115
if err != nil {
118116
return object, err
119117
}

amazon.go

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,13 @@ package storage
1818

1919
import (
2020
"bytes"
21+
"crypto/tls"
2122
"io/ioutil"
22-
pathutil "path"
23-
"strings"
2423
"net/http"
25-
"crypto/tls"
2624
"os"
25+
pathutil "path"
26+
"strings"
27+
2728
"github.com/aws/aws-sdk-go/aws"
2829
"github.com/aws/aws-sdk-go/aws/credentials"
2930
"github.com/aws/aws-sdk-go/aws/session"
@@ -133,7 +134,7 @@ func NewAmazonS3BackendWithCredentials(bucket string, prefix string, region stri
133134
// ListObjects lists all objects in Amazon S3 bucket, at prefix
134135
func (b AmazonS3Backend) ListObjects(prefix string) ([]Object, error) {
135136
var objects []Object
136-
prefix = pathutil.Join(b.Prefix, prefix)
137+
prefix = pathutil.Join(b.Prefix, normalizePath(prefix))
137138
s3Input := &s3.ListObjectsInput{
138139
Bucket: aws.String(b.Bucket),
139140
Prefix: aws.String(prefix),

baidu.go

Lines changed: 38 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,6 @@ func NewBaiDuBOSBackend(bucket string, prefix string, endpoint string) *BaiduBOS
5252
}
5353

5454
client, err := bos.NewClient(accessKeyId, accessKeySecret, endpoint)
55-
5655
if err != nil {
5756
panic("Failed to create BOS client: " + err.Error())
5857
}
@@ -67,44 +66,44 @@ func NewBaiDuBOSBackend(bucket string, prefix string, endpoint string) *BaiduBOS
6766

6867
// ListObjects lists all objects in Baidu Cloud BOS bucket, at prefix
6968
func (b BaiduBOSBackend) ListObjects(prefix string) ([]Object, error) {
70-
var objects []Object
71-
72-
prefix = pathutil.Join(b.Prefix, prefix)
73-
listObjectsArgs := &api.ListObjectsArgs{
74-
Prefix: prefix,
75-
Marker: "",
76-
MaxKeys: 1000,
77-
}
78-
for {
79-
lor, err := b.Client.ListObjects(b.Bucket, listObjectsArgs)
80-
if err != nil {
81-
return objects, err
82-
}
83-
84-
for _, obj := range lor.Contents {
85-
path := removePrefixFromObjectPath(prefix, obj.Key)
86-
if objectPathIsInvalid(path) {
87-
continue
88-
}
89-
lastModified, err := time.Parse(time.RFC3339, obj.LastModified)
90-
if err != nil {
91-
continue
92-
}
93-
object := Object{
94-
Path: path,
95-
Content: []byte{},
96-
LastModified: lastModified,
97-
}
98-
objects = append(objects, object)
99-
}
100-
if !lor.IsTruncated {
101-
break
102-
}
103-
listObjectsArgs.Prefix = lor.Prefix
104-
listObjectsArgs.Marker = lor.NextMarker
105-
}
106-
107-
return objects, nil
69+
var objects []Object
70+
71+
prefix = pathutil.Join(b.Prefix, normalizePath(prefix))
72+
listObjectsArgs := &api.ListObjectsArgs{
73+
Prefix: prefix,
74+
Marker: "",
75+
MaxKeys: 1000,
76+
}
77+
for {
78+
lor, err := b.Client.ListObjects(b.Bucket, listObjectsArgs)
79+
if err != nil {
80+
return objects, err
81+
}
82+
83+
for _, obj := range lor.Contents {
84+
path := removePrefixFromObjectPath(prefix, obj.Key)
85+
if objectPathIsInvalid(path) {
86+
continue
87+
}
88+
lastModified, err := time.Parse(time.RFC3339, obj.LastModified)
89+
if err != nil {
90+
continue
91+
}
92+
object := Object{
93+
Path: path,
94+
Content: []byte{},
95+
LastModified: lastModified,
96+
}
97+
objects = append(objects, object)
98+
}
99+
if !lor.IsTruncated {
100+
break
101+
}
102+
listObjectsArgs.Prefix = lor.Prefix
103+
listObjectsArgs.Marker = lor.NextMarker
104+
}
105+
106+
return objects, nil
108107
}
109108

110109
// GetObject retrieves an object from Baidu Cloud BOS bucket, at prefix

etcd.go

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -2,24 +2,25 @@ package storage
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
pathutil "path"
78
"strconv"
89
"strings"
910
"sync"
1011
"time"
1112

12-
clientv3 "go.etcd.io/etcd/client/v3"
1313
"go.etcd.io/etcd/client/pkg/v3/transport"
14+
clientv3 "go.etcd.io/etcd/client/v3"
1415
)
1516

1617
const DefaultPrefix = "/chart_backend_bucket"
1718

1819
var (
1920
DefileDialTimeOut = "5s"
2021
TimeStampKey = "timestamp"
21-
ErrNotExistEndpoints = fmt.Errorf("endpoints cannot connect !")
22-
ErrNotExist = fmt.Errorf("not exist!")
22+
ErrNotExistEndpoints = errors.New("endpoints cannot connect !")
23+
ErrNotExist = errors.New("not exist!")
2324
)
2425

2526
type etcdOpts struct {
@@ -38,7 +39,7 @@ type etcdStorage struct {
3839
mu sync.RWMutex
3940
}
4041

41-
//connection cut off
42+
// connection cut off
4243
func isServerErr(err error) bool {
4344
if err != nil {
4445
if err == context.Canceled {
@@ -52,11 +53,9 @@ func isServerErr(err error) bool {
5253
return false
5354
}
5455

55-
//prapare {basepath} dir
56+
// prapare {basepath} dir
5657
func (e *etcdStorage) probe() error {
57-
var (
58-
err error
59-
)
58+
var err error
6059
ctx, cancel := context.WithCancel(e.ctx)
6160
_, err = e.c.Put(ctx, e.base, "")
6261
cancel()
@@ -100,13 +99,10 @@ func (e *etcdStorage) delTimeStamp(path string) error {
10099
return err
101100
}
102101

103-
//
104102
func (e *etcdStorage) ListObjects(prefix string) ([]Object, error) {
105-
var (
106-
objs []Object
107-
)
103+
var objs []Object
108104
ctx, cancel := context.WithTimeout(e.ctx, e.opts.dialtimeout)
109-
newpath := pathutil.Join(e.base, prefix)
105+
newpath := pathutil.Join(e.base, normalizePath(prefix))
110106
resps, err := e.c.Get(ctx, newpath, clientv3.WithPrefix())
111107
cancel()
112108
if err != nil {
@@ -118,7 +114,7 @@ func (e *etcdStorage) ListObjects(prefix string) ([]Object, error) {
118114
if objectPathIsInvalid(path) {
119115
continue
120116
}
121-
//TODO need optimizate
117+
// TODO need optimizate
122118
if strings.HasSuffix(path, TimeStampKey) {
123119
continue
124120
}
@@ -134,13 +130,10 @@ func (e *etcdStorage) ListObjects(prefix string) ([]Object, error) {
134130
}
135131
}
136132
return objs, nil
137-
138133
}
139134

140135
func (e *etcdStorage) GetObject(path string) (Object, error) {
141-
var (
142-
modifytime time.Time
143-
)
136+
var modifytime time.Time
144137
ctx, cancel := context.WithTimeout(e.ctx, e.opts.dialtimeout)
145138
newpath := pathutil.Join(e.base, path)
146139
resps, err := e.c.Get(ctx, newpath)
@@ -164,9 +157,7 @@ func (e *etcdStorage) GetObject(path string) (Object, error) {
164157
}
165158

166159
func (e *etcdStorage) PutObject(path string, content []byte) error {
167-
var (
168-
updatetime = time.Now()
169-
)
160+
updatetime := time.Now()
170161
ctx, cancel := context.WithTimeout(e.ctx, e.opts.dialtimeout)
171162
newpath := pathutil.Join(e.base, path)
172163
_, err := e.c.Put(ctx, newpath, string(content))
@@ -191,9 +182,7 @@ func (e *etcdStorage) DeleteObject(path string) error {
191182
}
192183

193184
func parseConf(endpoints string, cafile, certfile, keyfile string, dialtime time.Duration) clientv3.Config {
194-
var (
195-
es []string
196-
)
185+
var es []string
197186
if endpoints == "" {
198187
panic(ErrNotExistEndpoints)
199188
}
@@ -215,9 +204,7 @@ func parseConf(endpoints string, cafile, certfile, keyfile string, dialtime time
215204
}
216205

217206
func NewEtcdCSBackend(endpoints string, cafile, certfile, keyfile string, prefix string) Backend {
218-
var (
219-
basepath string
220-
)
207+
var basepath string
221208
DialTimeOut, _ := time.ParseDuration(DefileDialTimeOut)
222209
cli, err := clientv3.New(parseConf(endpoints, cafile, certfile, keyfile, DialTimeOut))
223210
if err != nil {
@@ -249,5 +236,4 @@ func NewEtcdCSBackend(endpoints string, cafile, certfile, keyfile string, prefix
249236
panic(err)
250237
}
251238
return e
252-
253239
}

google.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ func NewGoogleCSBackend(bucket string, prefix string) *GoogleCSBackend {
5252
// ListObjects lists all objects in Google Cloud Storage bucket, at prefix
5353
func (b GoogleCSBackend) ListObjects(prefix string) ([]Object, error) {
5454
var objects []Object
55-
prefix = pathutil.Join(b.Prefix, prefix)
55+
prefix = pathutil.Join(b.Prefix, normalizePath(prefix))
5656
listQuery := &storage.Query{
5757
Prefix: prefix,
5858
}

microsoft.go

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,11 +19,10 @@ package storage
1919
import (
2020
"errors"
2121
"io/ioutil"
22+
"os"
2223
pathutil "path"
2324
"time"
2425

25-
"os"
26-
2726
microsoft_storage "github.com/Azure/azure-sdk-for-go/storage"
2827
)
2928

@@ -39,7 +38,6 @@ type MicrosoftBlobBackend struct {
3938

4039
// NewMicrosoftBlobBackend creates a new instance of MicrosoftBlobBackend
4140
func NewMicrosoftBlobBackend(container string, prefix string) *MicrosoftBlobBackend {
42-
4341
// From the Azure portal, get your storage account name and key and set environment variables.
4442
accountName, accountKey := os.Getenv("AZURE_STORAGE_ACCOUNT"), os.Getenv("AZURE_STORAGE_ACCESS_KEY")
4543
var serviceBaseURL, apiVersion string
@@ -78,7 +76,7 @@ func (b MicrosoftBlobBackend) ListObjects(prefix string) ([]Object, error) {
7876
}
7977

8078
var params microsoft_storage.ListBlobsParameters
81-
prefix = pathutil.Join(b.Prefix, prefix)
79+
prefix = pathutil.Join(b.Prefix, normalizePath(prefix))
8280
params.Prefix = prefix
8381

8482
for {

openstack.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -224,7 +224,7 @@ func NewOpenstackOSBackendV1Auth(container string, prefix string, caCert string)
224224
func (b OpenstackOSBackend) ListObjects(prefix string) ([]Object, error) {
225225
var objects []Object
226226

227-
prefix = pathutil.Join(b.Prefix, prefix)
227+
prefix = pathutil.Join(b.Prefix, normalizePath(prefix))
228228
opts := &osObjects.ListOpts{
229229
Full: true,
230230
Prefix: prefix,

oracle.go

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ type OracleCSBackend struct {
4343

4444
// NewOracleCSBackend creates a new instance of OracleCSBackend
4545
func NewOracleCSBackend(bucket string, prefix string, region string, compartmentId string) *OracleCSBackend {
46-
4746
var config common.ConfigurationProvider
4847
var err error
4948

@@ -102,7 +101,6 @@ func NewOracleCSBackend(bucket string, prefix string, region string, compartment
102101
}
103102

104103
func createBucket(ctx context.Context, c objectstorage.ObjectStorageClient, namespace string, bucket string, compartmentId string) (string, error) {
105-
106104
// Create the bucket
107105
request := objectstorage.CreateBucketRequest{
108106
NamespaceName: &namespace,
@@ -115,7 +113,6 @@ func createBucket(ctx context.Context, c objectstorage.ObjectStorageClient, name
115113
_, err := c.CreateBucket(ctx, request)
116114

117115
return bucket, err
118-
119116
}
120117

121118
func getNamespace(ctx context.Context, c objectstorage.ObjectStorageClient) (string, error) {
@@ -131,7 +128,7 @@ func getNamespace(ctx context.Context, c objectstorage.ObjectStorageClient) (str
131128
// ListObjects lists all objects in OCI Object Storage bucket, at prefix
132129
func (b OracleCSBackend) ListObjects(prefix string) ([]Object, error) {
133130
var objects []Object
134-
prefix = pathutil.Join(b.Prefix, prefix)
131+
prefix = pathutil.Join(b.Prefix, normalizePath(prefix))
135132

136133
request := objectstorage.ListObjectsRequest{
137134
NamespaceName: &b.Namespace,
@@ -181,14 +178,12 @@ func (b OracleCSBackend) GetObject(path string) (Object, error) {
181178
}
182179

183180
rc, err := b.Client.GetObject(b.Context, request)
184-
185181
if err != nil {
186182
return object, err
187183
}
188184

189185
object.LastModified = rc.LastModified.Time
190186
content, err := ioutil.ReadAll(rc.Content)
191-
192187
if err != nil {
193188
return object, err
194189
}
@@ -198,7 +193,6 @@ func (b OracleCSBackend) GetObject(path string) (Object, error) {
198193

199194
// PutObject uploads an object to OCI Object Storage bucket, at prefix
200195
func (b OracleCSBackend) PutObject(path string, content []byte) error {
201-
202196
objectname := pathutil.Join(b.Prefix, path)
203197
metadata := make(map[string]string)
204198
contentLen := int64(binary.Size(content))
@@ -219,7 +213,6 @@ func (b OracleCSBackend) PutObject(path string, content []byte) error {
219213

220214
// DeleteObject removes an object from OCI Object Storage bucket, at prefix
221215
func (b OracleCSBackend) DeleteObject(path string) error {
222-
223216
objectname := pathutil.Join(b.Prefix, path)
224217

225218
request := objectstorage.DeleteObjectRequest{

storage.go

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -97,6 +97,13 @@ func cleanPrefix(prefix string) string {
9797
return strings.Trim(prefix, "/")
9898
}
9999

100+
func normalizePath(path string) string {
101+
if path != "" && !strings.HasSuffix(path, "/") {
102+
path += "/"
103+
}
104+
return path
105+
}
106+
100107
func removePrefixFromObjectPath(prefix string, path string) string {
101108
if prefix == "" {
102109
return path

0 commit comments

Comments
 (0)