Skip to content

Commit 4225edb

Browse files
authored
chore(copyblobv2): use get+putblob (#16)
* chore(copyblobv2): use get+putblob
1 parent 3105590 commit 4225edb

File tree

1 file changed

+60
-0
lines changed

1 file changed

+60
-0
lines changed

internal/backend_s3.go

Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,9 @@
1515
package internal
1616

1717
import (
18+
"bytes"
19+
"io"
20+
1821
. "github.com/StatCan/goofys/api/common"
1922

2023
"fmt"
@@ -638,7 +641,64 @@ func (s *S3Backend) copyObjectMultipart(size int64, from string, to string, mpuI
638641
return
639642
}
640643

644+
// CopyBlobV2 that does not use CopyObject since netapp does not support it
645+
// https://docs.netapp.com/us-en/ontap/s3-multiprotocol/index.html#s3-actions-and-functionality-not-currently-supported-by-s3-nas-buckets
646+
647+
func (s *S3Backend) CopyBlobV2(param *CopyBlobInput) (*CopyBlobOutput, error) {
648+
s3Log.Debug("Entering CopyBlobV2. This is a temporary measure until CopyObject is supported by netapp s3 nas buckets")
649+
if param.Size == nil || param.ETag == nil || (param.Metadata == nil || param.StorageClass == nil) {
650+
params := &HeadBlobInput{Key: param.Source}
651+
resp, err := s.HeadBlob(params)
652+
if err != nil {
653+
return nil, err
654+
}
655+
if param.Metadata == nil {
656+
param.Metadata = resp.Metadata
657+
}
658+
}
659+
660+
// Use Get and PutBlob implementations over copy object
661+
getParams := &GetBlobInput{
662+
Key: param.Source,
663+
}
664+
getResp, err := s.GetBlob(getParams)
665+
if err != nil {
666+
return nil, err
667+
}
668+
669+
// Ensure we close the body when done
670+
defer getResp.Body.Close()
671+
672+
// Read the entire content into memory...Is there a better way to do this
673+
content, err := io.ReadAll(getResp.Body)
674+
if err != nil {
675+
return nil, err
676+
}
677+
// Create a ReadSeeker from the content
678+
contentReader := bytes.NewReader(content)
679+
680+
putParams := &PutBlobInput{
681+
Key: param.Destination,
682+
Body: contentReader,
683+
ContentType: getResp.ContentType,
684+
Metadata: param.Metadata, // can this be getResp.Metadata over param.Metadata?
685+
//param.Metadata,
686+
// dont need size or dirblob
687+
}
688+
689+
putResp, err := s.PutBlob(putParams)
690+
if err != nil {
691+
return nil, err
692+
}
693+
s3Log.Debug("Exiting CopyBlobV2")
694+
return &CopyBlobOutput{putResp.RequestId}, nil
695+
}
696+
641697
func (s *S3Backend) CopyBlob(param *CopyBlobInput) (*CopyBlobOutput, error) {
698+
// Change to use CopyBlobV2, done here because changing references to `CopyBlob` requires more change than I'd like
699+
// When CopyObject is supported we just remove CopyBlobV2 and this return statement
700+
return s.CopyBlobV2(param)
701+
642702
metadataDirective := s3.MetadataDirectiveCopy
643703
if param.Metadata != nil {
644704
metadataDirective = s3.MetadataDirectiveReplace

0 commit comments

Comments
 (0)