Skip to content

Commit 5f075cf

Browse files
committed
roachtest: create backup fixtures for azure
This commit adds support for backup fixtures on Azure blob storage buckets. Epic: CRDB-52076 Fixes: #149370
1 parent 5128b47 commit 5f075cf

File tree

4 files changed

+82
-11
lines changed

4 files changed

+82
-11
lines changed

pkg/cmd/roachtest/tests/BUILD.bazel

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -350,6 +350,7 @@ go_library(
350350
"@com_github_prometheus_common//model",
351351
"@com_github_stretchr_testify//assert",
352352
"@com_github_stretchr_testify//require",
353+
"@in_gopkg_yaml_v3//:yaml_v3",
353354
"@org_golang_google_protobuf//proto",
354355
"@org_golang_x_exp//maps",
355356
"@org_golang_x_oauth2//clientcredentials",

pkg/cmd/roachtest/tests/backup.go

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,10 @@ const (
6565
AssumeRoleGCSCredentials = "GOOGLE_CREDENTIALS_ASSUME_ROLE"
6666
AssumeRoleGCSServiceAccount = "GOOGLE_SERVICE_ACCOUNT"
6767

68+
AzureClientIDEnvVar = "AZURE_CLIENT_ID"
69+
AzureClientSecretEnvVar = "AZURE_CLIENT_SECRET"
70+
AzureTenantIDEnvVar = "AZURE_TENANT_ID"
71+
6872
// rows2TiB is the number of rows to import to load 2TB of data (when
6973
// replicated).
7074
rows2TiB = 65_104_166

pkg/cmd/roachtest/tests/backup_fixtures.go

Lines changed: 76 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
gosql "database/sql"
1111
"fmt"
1212
"net/url"
13+
"os"
1314
"path"
1415
"time"
1516

@@ -33,8 +34,21 @@ import (
3334
"github.com/cockroachdb/cockroach/pkg/util/timeutil"
3435
"github.com/cockroachdb/errors"
3536
"github.com/stretchr/testify/require"
37+
"gopkg.in/yaml.v3"
3638
)
3739

40+
// At the moment, Azure VMs do not have managed identities set up yet.
41+
// Therefore, in order to use implicit authentication, we need to put a
42+
// credentials file on each VM and point the
43+
// `COCKROACH_AZURE_APPLICATION_CREDENTIALS_FILE` environment variable at the
44+
// file.
45+
// Currently, the only set of credentials that have write access to the storage
46+
// buckets are the Teamcity credentials, so the Azure fixture roachtests cannot
47+
// be run locally until those managed identities are set up.
48+
// TODO (kev-cao): Once managed identities are set up, we can remove this file
49+
// and rely on the managed identity to authenticate with Azure Blob Storage.
50+
const azureCredentialsFilePath = "/home/ubuntu/azure-credentials.yaml"
51+
3852
type BackupFixture interface {
3953
Kind() string
4054
// The database that is backed up.
@@ -159,13 +173,20 @@ type backupDriver struct {
159173
}
160174

161175
func (bd *backupDriver) prepareCluster(ctx context.Context) {
162-
bd.c.Start(ctx, bd.t.L(), option.NewStartOpts(option.NoBackupSchedule), install.MakeClusterSettings(install.ClusterSettingsOption{
163-
// Large imports can run into a death spiral where splits fail because
164-
// there is a snapshot backlog, which makes the snapshot backlog worse
165-
// because add sst causes ranges to fall behind and need recovery snapshots
166-
// to catch up.
167-
"kv.snapshot_rebalance.max_rate": "256 MiB",
168-
}))
176+
bd.c.Start(
177+
ctx, bd.t.L(), option.NewStartOpts(option.NoBackupSchedule),
178+
install.MakeClusterSettings(
179+
install.ClusterSettingsOption{
180+
// Large imports can run into a death spiral where splits fail because
181+
// there is a snapshot backlog, which makes the snapshot backlog worse
182+
// because add sst causes ranges to fall behind and need recovery snapshots
183+
// to catch up.
184+
"kv.snapshot_rebalance.max_rate": "256 MiB",
185+
},
186+
install.EnvOption{
187+
fmt.Sprintf("COCKROACH_AZURE_APPLICATION_CREDENTIALS_FILE=%s", azureCredentialsFilePath),
188+
},
189+
))
169190
}
170191

171192
func (bd *backupDriver) initWorkload(ctx context.Context) {
@@ -513,6 +534,12 @@ func GetFixtureRegistry(ctx context.Context, t test.Test, cloud spec.Cloud) *blo
513534
Host: "cockroach-fixtures-us-east-2",
514535
RawQuery: "AUTH=implicit",
515536
}
537+
case spec.Azure:
538+
uri = url.URL{
539+
Scheme: "azure-blob",
540+
Host: "cockroachdb-fixtures-eastus",
541+
RawQuery: "AUTH=implicit&AZURE_ACCOUNT_NAME=roachtest",
542+
}
516543
case spec.GCE, spec.Local:
517544
account, err := vm.Providers["gce"].FindActiveAccount(t.L())
518545
require.NoError(t, err)
@@ -544,7 +571,7 @@ func registerBackupFixtures(r registry.Registry) {
544571
}),
545572
timeout: 30 * time.Minute,
546573
suites: registry.Suites(registry.Nightly),
547-
clouds: []spec.Cloud{spec.AWS, spec.GCE, spec.Local},
574+
clouds: []spec.Cloud{spec.AWS, spec.Azure, spec.GCE, spec.Local},
548575
},
549576
{
550577
fixture: SmallFixture,
@@ -555,7 +582,7 @@ func registerBackupFixtures(r registry.Registry) {
555582
// fixture on top of the allocated 2 hours for the test.
556583
timeout: 3 * time.Hour,
557584
suites: registry.Suites(registry.Nightly),
558-
clouds: []spec.Cloud{spec.AWS, spec.GCE},
585+
clouds: []spec.Cloud{spec.AWS, spec.Azure, spec.GCE},
559586
},
560587
{
561588
fixture: MediumFixture,
@@ -566,7 +593,7 @@ func registerBackupFixtures(r registry.Registry) {
566593
}),
567594
timeout: 12 * time.Hour,
568595
suites: registry.Suites(registry.Weekly),
569-
clouds: []spec.Cloud{spec.AWS, spec.GCE},
596+
clouds: []spec.Cloud{spec.AWS, spec.Azure, spec.GCE},
570597
// The fixture takes an estimated 3.5 hours to fingerprint, so we skip it.
571598
skipFingerprint: true,
572599
},
@@ -604,6 +631,7 @@ func registerBackupFixtures(r registry.Registry) {
604631
Suites: bf.suites,
605632
Skip: bf.skip,
606633
Run: func(ctx context.Context, t test.Test, c cluster.Cluster) {
634+
require.NoError(t, maybePutAzureCredentialsFile(ctx, c, azureCredentialsFilePath))
607635
registry := GetFixtureRegistry(ctx, t, c.Cloud())
608636

609637
handle, err := registry.Create(ctx, bf.fixture.Name, t.L())
@@ -638,6 +666,44 @@ func registerBackupFixtures(r registry.Registry) {
638666
}
639667
}
640668

669+
func maybePutAzureCredentialsFile(ctx context.Context, c cluster.Cluster, path string) error {
670+
if c.Cloud() != spec.Azure {
671+
return nil
672+
}
673+
674+
type azureCreds struct {
675+
TenantID string `yaml:"azure_tenant_id"`
676+
ClientID string `yaml:"azure_client_id"`
677+
ClientSecret string `yaml:"azure_client_secret"`
678+
}
679+
680+
azureEnvVars := []string{AzureTenantIDEnvVar, AzureClientIDEnvVar, AzureClientSecretEnvVar}
681+
azureEnvValues := make(map[string]string)
682+
for _, envVar := range azureEnvVars {
683+
val := os.Getenv(envVar)
684+
if val == "" {
685+
return errors.Newf("environment variable %s is not set", envVar)
686+
}
687+
azureEnvValues[envVar] = val
688+
}
689+
690+
creds := azureCreds{
691+
TenantID: azureEnvValues[AzureTenantIDEnvVar],
692+
ClientID: azureEnvValues[AzureClientIDEnvVar],
693+
ClientSecret: azureEnvValues[AzureClientSecretEnvVar],
694+
}
695+
696+
credsYaml, err := yaml.Marshal(creds)
697+
if err != nil {
698+
return errors.Wrapf(err, "failed to marshal Azure credentials to YAML")
699+
}
700+
701+
return errors.Wrap(
702+
c.PutString(ctx, string(credsYaml), path, 0700),
703+
"failed to put Azure credentials file in cluster",
704+
)
705+
}
706+
641707
func registerBlobFixtureGC(r registry.Registry) {
642708
r.Add(registry.TestSpec{
643709
Name: "blobfixture/gc",

pkg/roachprod/blobfixture/registry.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,7 @@ type Registry struct {
5757
// for all fixture data and metadata. See the comment on the uri field for the
5858
// structure of a fixture directory.
5959
func NewRegistry(ctx context.Context, uri url.URL) (*Registry, error) {
60-
supportedSchemes := map[string]bool{"gs": true, "s3": true, "azure": true}
60+
supportedSchemes := map[string]bool{"gs": true, "s3": true, "azure-blob": true}
6161
if !supportedSchemes[uri.Scheme] {
6262
return nil, errors.Errorf("unsupported scheme %q", uri.Scheme)
6363
}

0 commit comments

Comments
 (0)