@@ -5,15 +5,17 @@ import (
55 "fmt"
66 "io"
77 "log/slog"
8+ "math"
89 "strconv"
910 "strings"
1011
1112 "github.com/Vilsol/slox"
12- "github.com/aws/aws-sdk-go/aws"
13- "github.com/aws/aws-sdk-go/aws/credentials"
14- "github.com/aws/aws-sdk-go/aws/session"
15- "github.com/aws/aws-sdk-go/service/s3"
16- "github.com/aws/aws-sdk-go/service/s3/s3manager"
13+ "github.com/aws/aws-sdk-go-v2/aws"
14+ awsconfig "github.com/aws/aws-sdk-go-v2/config"
15+ "github.com/aws/aws-sdk-go-v2/credentials"
16+ "github.com/aws/aws-sdk-go-v2/feature/s3/manager"
17+ "github.com/aws/aws-sdk-go-v2/service/s3"
18+ "github.com/aws/aws-sdk-go-v2/service/s3/types"
1719 "github.com/pkg/errors"
1820 "go.opentelemetry.io/otel"
1921 "go.opentelemetry.io/otel/attribute"
@@ -22,40 +24,38 @@ import (
2224)
2325
2426type S3 struct {
25- BaseURL string
26- S3Client * s3.S3
27- S3Session * session.Session
28- Config Config
27+ BaseURL string
28+ S3Client * s3.Client
29+ Config Config
2930}
3031
3132func initializeS3 (ctx context.Context , config Config ) * S3 {
32- s3Config := & aws.Config {
33- Credentials : credentials .NewStaticCredentials (config .Key , config .Secret , "" ),
34- Endpoint : aws .String (config .Endpoint ),
35- Region : aws .String (config .Region ),
36- S3ForcePathStyle : aws .Bool (true ),
37- }
38-
39- newSession , err := session .NewSession (s3Config )
33+ cfg , err := awsconfig .LoadDefaultConfig (
34+ ctx ,
35+ awsconfig .WithCredentialsProvider (credentials .NewStaticCredentialsProvider (config .Key , config .Secret , "" )),
36+ awsconfig .WithBaseEndpoint (config .Endpoint ),
37+ awsconfig .WithRegion (config .Region ),
38+ )
4039 if err != nil {
4140 slox .Error (ctx , "failed to create S3 session" , slog .Any ("err" , err ))
4241 return nil
4342 }
4443
45- s3Client := s3 .New (newSession )
44+ s3Client := s3 .NewFromConfig (cfg , func (options * s3.Options ) {
45+ options .UsePathStyle = true
46+ })
4647
4748 return & S3 {
48- BaseURL : config .BaseURL ,
49- S3Client : s3Client ,
50- S3Session : newSession ,
51- Config : config ,
49+ BaseURL : config .BaseURL ,
50+ S3Client : s3Client ,
51+ Config : config ,
5252 }
5353}
5454
5555func (s3o * S3 ) Get (key string ) (io.ReadCloser , error ) {
5656 cleanedKey := strings .TrimPrefix (key , "/" )
5757
58- object , err := s3o .S3Client .GetObject (& s3.GetObjectInput {
58+ object , err := s3o .S3Client .GetObject (context . TODO (), & s3.GetObjectInput {
5959 Bucket : aws .String (s3o .Config .Bucket ),
6060 Key : aws .String (cleanedKey ),
6161 })
@@ -74,9 +74,9 @@ func (s3o *S3) Put(ctx context.Context, key string, body io.ReadSeeker) (string,
7474
7575 cleanedKey := strings .TrimPrefix (key , "/" )
7676
77- uploader := s3manager .NewUploader (s3o .S3Session )
77+ uploader := manager .NewUploader (s3o .S3Client )
7878
79- _ , err := uploader .UploadWithContext (ctx , & s3manager. UploadInput {
79+ _ , err := uploader .Upload (ctx , & s3. PutObjectInput {
8080 Body : body ,
8181 Bucket : aws .String (s3o .Config .Bucket ),
8282 Key : aws .String (cleanedKey ),
@@ -102,7 +102,7 @@ func (s3o *S3) SignPut(_ string) (string, error) {
102102
103103func (s3o * S3 ) StartMultipartUpload (key string ) error {
104104 cleanedKey := strings .TrimPrefix (key , "/" )
105- upload , err := s3o .S3Client .CreateMultipartUpload (& s3.CreateMultipartUploadInput {
105+ upload , err := s3o .S3Client .CreateMultipartUpload (context . TODO (), & s3.CreateMultipartUploadInput {
106106 Bucket : aws .String (s3o .Config .Bucket ),
107107 Key : aws .String (cleanedKey ),
108108 })
@@ -115,15 +115,15 @@ func (s3o *S3) StartMultipartUpload(key string) error {
115115 return nil
116116}
117117
118- func (s3o * S3 ) UploadPart (key string , part int64 , data io.ReadSeeker ) error {
118+ func (s3o * S3 ) UploadPart (key string , part int32 , data io.ReadSeeker ) error {
119119 cleanedKey := strings .TrimPrefix (key , "/" )
120120 id := redis .GetMultipartUploadID (cleanedKey )
121121
122- response , err := s3o .S3Client .UploadPart (& s3.UploadPartInput {
122+ response , err := s3o .S3Client .UploadPart (context . TODO (), & s3.UploadPartInput {
123123 Body : data ,
124124 Bucket : aws .String (s3o .Config .Bucket ),
125125 Key : aws .String (cleanedKey ),
126- PartNumber : aws .Int64 (part ),
126+ PartNumber : aws .Int32 (part ),
127127 UploadId : aws .String (id ),
128128 })
129129 if err != nil {
@@ -139,17 +139,17 @@ func (s3o *S3) CompleteMultipartUpload(key string) error {
139139 cleanedKey := strings .TrimPrefix (key , "/" )
140140 id := redis .GetMultipartUploadID (cleanedKey )
141141 parts := redis .GetMultipartCompletedParts (cleanedKey )
142- completedParts := make ([]* s3 .CompletedPart , len (parts ))
142+ completedParts := make ([]types .CompletedPart , len (parts ))
143143
144144 for part , etag := range parts {
145- partInt , _ := strconv .ParseInt (part , 10 , 64 )
146- completedParts [partInt - 1 ] = & s3 .CompletedPart {ETag : aws .String (etag ), PartNumber : & partInt }
145+ partInt , _ := strconv .ParseInt (part , 10 , 32 )
146+ completedParts [partInt - 1 ] = types .CompletedPart {ETag : aws .String (etag ), PartNumber : aws . Int32 ( int32 ( partInt )) }
147147 }
148148
149- _ , err := s3o .S3Client .CompleteMultipartUpload (& s3.CompleteMultipartUploadInput {
149+ _ , err := s3o .S3Client .CompleteMultipartUpload (context . TODO (), & s3.CompleteMultipartUploadInput {
150150 Bucket : aws .String (s3o .Config .Bucket ),
151151 Key : aws .String (cleanedKey ),
152- MultipartUpload : & s3 .CompletedMultipartUpload {Parts : completedParts },
152+ MultipartUpload : & types .CompletedMultipartUpload {Parts : completedParts },
153153 UploadId : aws .String (id ),
154154 })
155155 if err != nil {
@@ -164,7 +164,7 @@ func (s3o *S3) CompleteMultipartUpload(key string) error {
164164func (s3o * S3 ) Rename (from string , to string ) error {
165165 cleanedKey := strings .TrimPrefix (to , "/" )
166166
167- _ , err := s3o .S3Client .CopyObject (& s3.CopyObjectInput {
167+ _ , err := s3o .S3Client .CopyObject (context . TODO (), & s3.CopyObjectInput {
168168 Bucket : aws .String (s3o .Config .Bucket ),
169169 CopySource : aws .String (s3o .Config .Bucket + from ),
170170 Key : aws .String (cleanedKey ),
@@ -181,14 +181,14 @@ func (s3o *S3) Delete(key string) error {
181181
182182 // Check up to 10 object pages
183183 for range 10 {
184- versions , err := s3o .S3Client .ListObjectVersions (& s3.ListObjectVersionsInput {
184+ versions , err := s3o .S3Client .ListObjectVersions (context . TODO (), & s3.ListObjectVersionsInput {
185185 Bucket : aws .String (s3o .Config .Bucket ),
186186 KeyMarker : aws .String (cleanedKey ),
187187 Prefix : aws .String (cleanedKey ),
188188 })
189189 if err != nil {
190190 if strings .Contains (err .Error (), "NotImplemented" ) {
191- _ , err = s3o .S3Client .DeleteObject (& s3.DeleteObjectInput {
191+ _ , err = s3o .S3Client .DeleteObject (context . TODO (), & s3.DeleteObjectInput {
192192 Bucket : aws .String (s3o .Config .Bucket ),
193193 Key : aws .String (cleanedKey ),
194194 })
@@ -202,24 +202,24 @@ func (s3o *S3) Delete(key string) error {
202202 return fmt .Errorf ("failed to list object versions: %w" , err )
203203 }
204204
205- objects := make ([]* s3 .ObjectIdentifier , len (versions .Versions )+ len (versions .DeleteMarkers ))
205+ objects := make ([]types .ObjectIdentifier , len (versions .Versions )+ len (versions .DeleteMarkers ))
206206
207207 for i , version := range versions .Versions {
208- objects [i ] = & s3 .ObjectIdentifier {
208+ objects [i ] = types .ObjectIdentifier {
209209 Key : version .Key ,
210210 VersionId : version .VersionId ,
211211 }
212212 }
213213
214214 for i , marker := range versions .DeleteMarkers {
215- objects [i + len (versions .Versions )] = & s3 .ObjectIdentifier {
215+ objects [i + len (versions .Versions )] = types .ObjectIdentifier {
216216 Key : marker .Key ,
217217 VersionId : marker .VersionId ,
218218 }
219219 }
220220
221221 if len (objects ) == 0 {
222- _ , err = s3o .S3Client .DeleteObject (& s3.DeleteObjectInput {
222+ _ , err = s3o .S3Client .DeleteObject (context . TODO (), & s3.DeleteObjectInput {
223223 Bucket : aws .String (s3o .Config .Bucket ),
224224 Key : aws .String (cleanedKey ),
225225 })
@@ -230,9 +230,9 @@ func (s3o *S3) Delete(key string) error {
230230 return nil
231231 }
232232
233- _ , err = s3o .S3Client .DeleteObjects (& s3.DeleteObjectsInput {
233+ _ , err = s3o .S3Client .DeleteObjects (context . TODO (), & s3.DeleteObjectsInput {
234234 Bucket : aws .String (s3o .Config .Bucket ),
235- Delete : & s3 .Delete {
235+ Delete : & types .Delete {
236236 Objects : objects ,
237237 },
238238 })
@@ -247,7 +247,7 @@ func (s3o *S3) Delete(key string) error {
247247func (s3o * S3 ) Meta (key string ) (* ObjectMeta , error ) {
248248 cleanedKey := strings .TrimPrefix (key , "/" )
249249
250- data , err := s3o .S3Client .HeadObject (& s3.HeadObjectInput {
250+ data , err := s3o .S3Client .HeadObject (context . TODO (), & s3.HeadObjectInput {
251251 Bucket : aws .String (s3o .Config .Bucket ),
252252 Key : aws .String (cleanedKey ),
253253 })
@@ -264,20 +264,30 @@ func (s3o *S3) Meta(key string) (*ObjectMeta, error) {
264264func (s3o * S3 ) List (prefix string ) ([]Object , error ) {
265265 out := make ([]Object , 0 )
266266
267- err := s3o .S3Client .ListObjectsPages (& s3.ListObjectsInput {
268- Bucket : aws .String (s3o .Config .Bucket ),
269- Prefix : aws .String (prefix ),
270- }, func (output * s3.ListObjectsOutput , _ bool ) bool {
271- for _ , obj := range output .Contents {
267+ var marker * string
268+ for {
269+ objects , err := s3o .S3Client .ListObjects (context .TODO (), & s3.ListObjectsInput {
270+ Bucket : aws .String (s3o .Config .Bucket ),
271+ Marker : marker ,
272+ MaxKeys : aws .Int32 (math .MaxInt32 ),
273+ Prefix : aws .String (prefix ),
274+ })
275+ if err != nil {
276+ return nil , fmt .Errorf ("failed to list objects: %w" , err )
277+ }
278+
279+ marker = objects .NextMarker
280+
281+ for _ , obj := range objects .Contents {
272282 out = append (out , Object {
273283 Key : obj .Key ,
274284 LastModified : obj .LastModified ,
275285 })
276286 }
277- return true
278- })
279- if err != nil {
280- return nil , fmt . Errorf ( "failed to list objects: %w" , err )
287+
288+ if objects . IsTruncated == nil || ! * objects . IsTruncated {
289+ break
290+ }
281291 }
282292
283293 return out , nil
0 commit comments