Skip to content

Commit 7aa9a3c

Browse files
lance6716ti-chi-bot
authored andcommitted
This is an automated cherry-pick of pingcap#60402
Signed-off-by: ti-chi-bot <[email protected]>
1 parent b957a04 commit 7aa9a3c

File tree

2 files changed

+65
-0
lines changed

2 files changed

+65
-0
lines changed

br/pkg/storage/gcs.go

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,40 @@ type GCSStorage struct {
112112
handles []*storage.BucketHandle
113113
clients []*storage.Client
114114
clientCancel context.CancelFunc
115+
<<<<<<< HEAD
116+
=======
117+
}
118+
119+
// CopyFrom implements Copier.
120+
func (s *GCSStorage) CopyFrom(ctx context.Context, e ExternalStorage, spec CopySpec) error {
121+
es, ok := e.(*GCSStorage)
122+
if !ok {
123+
return errors.Annotatef(berrors.ErrStorageInvalidConfig, "GCSStorage.CopyFrom supports only GCSStorage, get %T", e)
124+
}
125+
dstName := s.objectName(spec.To)
126+
srcName := es.objectName(spec.From)
127+
// A note here:
128+
// https://cloud.google.com/storage/docs/json_api/v1/objects/rewrite
129+
// It seems extra configuration is needed when doing cross-region copying.
130+
copier := s.GetBucketHandle().Object(dstName).CopierFrom(es.GetBucketHandle().Object(srcName))
131+
_, err := copier.Run(ctx)
132+
if err != nil {
133+
return errors.Annotatef(
134+
err,
135+
"failed to copy %s/%s to %s/%s",
136+
es.gcs.Bucket,
137+
srcName,
138+
s.gcs.Bucket,
139+
dstName,
140+
)
141+
}
142+
143+
return nil
144+
}
145+
146+
func (s *GCSStorage) MarkStrongConsistency() {
147+
// See https://cloud.google.com/storage/docs/consistency#strongly_consistent_operations
148+
>>>>>>> 7424255fef7 (external store: use separate ctx for GCS clients (#60402))
115149
}
116150

117151
// GetBucketHandle gets the handle to the GCS API on the bucket.

br/pkg/storage/gcs_test.go

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ import (
1111
"io"
1212
"net/http"
1313
"net/http/httptest"
14+
<<<<<<< HEAD
15+
=======
16+
"net/url"
17+
>>>>>>> 7424255fef7 (external store: use separate ctx for GCS clients (#60402))
1418
"os"
1519
"testing"
1620
"time"
@@ -599,3 +603,30 @@ func TestCtxUsage(t *testing.T) {
599603
// before the fix, it's context canceled error
600604
require.ErrorContains(t, err, "invalid_request")
601605
}
606+
607+
func TestCtxUsage(t *testing.T) {
608+
httpSvr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
609+
defer httpSvr.Close()
610+
611+
ctx := context.Background()
612+
gcs := &backuppb.GCS{
613+
Endpoint: httpSvr.URL,
614+
Bucket: "test",
615+
Prefix: "prefix",
616+
StorageClass: "NEARLINE",
617+
PredefinedAcl: "private",
618+
CredentialsBlob: fmt.Sprintf(`
619+
{
620+
"type":"external_account",
621+
"audience":"//iam.googleapis.com/projects/1234567890123/locations/global/workloadIdentityPools/my-pool/providers/my-provider",
622+
"subject_token_type":"urn:ietf:params:oauth:token-type:access_token",
623+
"credential_source":{"url":"%s"}
624+
}`, httpSvr.URL),
625+
}
626+
stg, err := NewGCSStorage(ctx, gcs, &ExternalStorageOptions{})
627+
require.NoError(t, err)
628+
629+
_, err = stg.FileExists(ctx, "key")
630+
// before the fix, it's context canceled error
631+
require.ErrorContains(t, err, "invalid_request")
632+
}

0 commit comments

Comments
 (0)