Skip to content

Commit

Permalink
command/cp: allow overriding bucket region (#270)
Browse files Browse the repository at this point in the history
Resolves #262
  • Loading branch information
kemege authored Jul 7, 2021
1 parent 5495dd4 commit b4c91bd
Show file tree
Hide file tree
Showing 3 changed files with 50 additions and 12 deletions.
27 changes: 27 additions & 0 deletions command/cp.go
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,14 @@ var copyCommandFlags = []cli.Flag{
Name: "acl",
Usage: "set acl for target: defines granted accesses and their types on different accounts/groups",
},
&cli.StringFlag{
Name: "source-region",
Usage: "set the region of source bucket; the region of the source bucket will be automatically discovered if --source-region is not specified",
},
&cli.StringFlag{
Name: "destination-region",
Usage: "set the region of destination bucket: the region of the destination bucket will be automatically discovered if --destination-region is not specified",
},
}

var copyCommand = &cli.Command{
Expand Down Expand Up @@ -167,6 +175,9 @@ var copyCommand = &cli.Command{
encryptionMethod: c.String("sse"),
encryptionKeyID: c.String("sse-kms-key-id"),
acl: c.String("acl"),
// region settings
srcRegion: c.String("source-region"),
dstRegion: c.String("destination-region"),

storageOpts: NewStorageOpts(c),
}.Run(c.Context)
Expand All @@ -193,6 +204,10 @@ type Copy struct {
encryptionKeyID string
acl string

// region settings
srcRegion string
dstRegion string

// s3 options
concurrency int
partSize int64
Expand All @@ -219,6 +234,10 @@ func (c Copy) Run(ctx context.Context) error {
return err
}

// override source region if set
if c.srcRegion != "" {
c.storageOpts.SetRegion(c.srcRegion)
}
client, err := storage.NewClient(ctx, srcurl, c.storageOpts)
if err != nil {
printError(c.fullCommand, c.op, err)
Expand Down Expand Up @@ -430,6 +449,10 @@ func (c Copy) doUpload(ctx context.Context, srcurl *url.URL, dsturl *url.URL) er
return err
}

// override destination region if set
if c.dstRegion != "" {
c.storageOpts.SetRegion(c.dstRegion)
}
dstClient, err := storage.NewRemoteClient(ctx, dsturl, c.storageOpts)
if err != nil {
return err
Expand Down Expand Up @@ -473,6 +496,10 @@ func (c Copy) doUpload(ctx context.Context, srcurl *url.URL, dsturl *url.URL) er
}

func (c Copy) doCopy(ctx context.Context, srcurl, dsturl *url.URL) error {
// override destination region if set
if c.dstRegion != "" {
c.storageOpts.SetRegion(c.dstRegion)
}
dstClient, err := storage.NewClient(ctx, dsturl, c.storageOpts)
if err != nil {
return err
Expand Down
9 changes: 7 additions & 2 deletions storage/s3.go
Original file line number Diff line number Diff line change
Expand Up @@ -696,8 +696,13 @@ func (sc *SessionCache) newSession(ctx context.Context, opts Options) (*session.
// get region of the bucket and create session accordingly. if the region
// is not provided, it means we want region-independent session
// for operations such as listing buckets, making a new bucket etc.
if err := setSessionRegion(ctx, sess, opts.bucket); err != nil {
return nil, err
// only get bucket region when it is not specified.
if opts.region != "" {
sess.Config.Region = aws.String(opts.region)
} else {
if err := setSessionRegion(ctx, sess, opts.bucket); err != nil {
return nil, err
}
}

sc.sessions[opts] = sess
Expand Down
26 changes: 16 additions & 10 deletions storage/storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,12 +48,13 @@ func NewLocalClient(opts Options) *Filesystem {

func NewRemoteClient(ctx context.Context, url *url.URL, opts Options) (*S3, error) {
newOpts := Options{
MaxRetries: opts.MaxRetries,
Endpoint: opts.Endpoint,
NoVerifySSL: opts.NoVerifySSL,
DryRun: opts.DryRun,
MaxRetries: opts.MaxRetries,
Endpoint: opts.Endpoint,
NoVerifySSL: opts.NoVerifySSL,
DryRun: opts.DryRun,
NoSignRequest: opts.NoSignRequest,
bucket: url.Bucket,
bucket: url.Bucket,
region: opts.region,
}
return newS3Storage(ctx, newOpts)
}
Expand All @@ -67,12 +68,17 @@ func NewClient(ctx context.Context, url *url.URL, opts Options) (Storage, error)

// Options stores configuration for storage.
type Options struct {
MaxRetries int
Endpoint string
NoVerifySSL bool
DryRun bool
MaxRetries int
Endpoint string
NoVerifySSL bool
DryRun bool
NoSignRequest bool
bucket string
bucket string
region string
}

func (o *Options) SetRegion(region string) {
o.region = region
}

// Object is a generic type which contains metadata for storage items.
Expand Down

0 comments on commit b4c91bd

Please sign in to comment.