Repository: pingcap/tidb
File: pkg/objstore/ossstore/store.go (Go)

Code before:
	// not specified explicitly and the bucket is in the same region with the
	// client.
	if len(qs.Endpoint) != 0 {
		ossCfg = ossCfg.WithEndpoint(qs.Endpoint)
	}
	var (
		ecsRegionID   string
		credRefresher *credentialRefresher
	)
	if qs.AccessKey != "" && qs.SecretAccessKey != "" {
		ossCfg = ossCfg.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(qs.AccessKey, qs.SecretAccessKey, qs.SessionToken))
	} else {
		var provider providers.CredentialsProvider = providers.NewDefaultCredentialsProvider()
		cred, err := provider.GetCredentials()
		if err != nil {
			return nil, errors.Annotatef(err, "failed to get credentials from default provider")
		}
		// the default provider concatenates the provider names with `/`, see
		// https://github.com/aliyun/credentials-go/blob/7d2a3e68402630904f518531e80b370b3649c6a1/credentials/providers/default.go#L101
		if strings.Contains(cred.ProviderName, ecsRAMRoleProviderName) {
			httpCli := &http.Client{}
			ecsRegionID, err = httputil.GetText(httpCli, regionIDMetaURL)
			if err != nil {
				return nil, errors.Annotatef(err, "failed to get region ID from ECS metadata service")
			}
		}
		if qs.RoleArn != "" {
			var err2 error
			provider, err2 = providers.NewRAMRoleARNCredentialsProviderBuilder().
				WithCredentialsProvider(provider).
				WithRoleArn(qs.RoleArn).
				WithExternalId(qs.ExternalId).
				WithHttpOptions(&providers.HttpOptions{
					ReadTimeout:    int(30 * time.Second.Milliseconds()),
					ConnectTimeout: int(30 * time.Second.Milliseconds()),
				}).
				Build()
			if err2 != nil {
				return nil, errors.Trace(err2)
			}
		}
		credRefresher = newCredentialRefresher(provider, logger)
		if err := credRefresher.refreshOnce(); err != nil {
			return nil, errors.Annotatef(err, "failed to get initial OSS credentials")
		}
		ossCfg = ossCfg.WithCredentialsProvider(credRefresher)
	}

	if opts.AccessRecording != nil {
		ossOptFns = append(ossOptFns, func(o *oss.Options) {
			// nolint:bodyclose

Review comment (bug):
When running with ECS RAM role credentials but the metadata service is unavailable or unreachable (e.g., testing locally with assumed credentials), this will cause the entire storage initialization to fail. Consider making the region detection non-fatal and falling back to using the public endpoint when the metadata service is unavailable, while logging a warning.
```suggestion
				// When ECS metadata is unavailable (e.g., local testing with assumed ECS RAM role),
				// do not fail initialization; log a warning and fall back to the default/public endpoint.
				logger.Warn("failed to get region ID from ECS metadata service, falling back to default configuration", zap.Error(err))
```

Code after:
	// not specified explicitly and the bucket is in the same region with the
	// client.
	if len(qs.Endpoint) != 0 {
		ossCfg = ossCfg.WithEndpoint(qs.Endpoint)
	}
	var (
		ecsRegionID   string
		credRefresher *credentialRefresher
	)
	if qs.AccessKey != "" && qs.SecretAccessKey != "" {
		ossCfg = ossCfg.WithCredentialsProvider(credentials.NewStaticCredentialsProvider(qs.AccessKey, qs.SecretAccessKey, qs.SessionToken))
	} else {
		var provider providers.CredentialsProvider = providers.NewDefaultCredentialsProvider()
		cred, err := provider.GetCredentials()
		if err != nil {
			return nil, errors.Annotatef(err, "failed to get credentials from default provider")
		}
		// the default provider concatenates the provider names with `/`, see
		// https://github.com/aliyun/credentials-go/blob/7d2a3e68402630904f518531e80b370b3649c6a1/credentials/providers/default.go#L101
		if strings.Contains(cred.ProviderName, ecsRAMRoleProviderName) {
			httpCli := httputil.NewClient(nil)
			ecsRegionID, err = httputil.GetText(httpCli, regionIDMetaURL)
			if err != nil {
				// shouldn't happen normally, we just successfully got ECS RAM
				// role credentials from the metadata service.
				return nil, errors.Annotatef(err, "failed to get region ID from ECS metadata service")
			}
		}
		if qs.RoleArn != "" {
			var err2 error
			provider, err2 = providers.NewRAMRoleARNCredentialsProviderBuilder().
				WithCredentialsProvider(provider).
				WithRoleArn(qs.RoleArn).
				WithExternalId(qs.ExternalId).
				WithHttpOptions(&providers.HttpOptions{
					ReadTimeout:    int(30 * time.Second.Milliseconds()),
					ConnectTimeout: int(30 * time.Second.Milliseconds()),
				}).
				Build()
			if err2 != nil {
				return nil, errors.Trace(err2)
			}
		}
		credRefresher = newCredentialRefresher(provider, logger)
		if err := credRefresher.refreshOnce(); err != nil {
			return nil, errors.Annotatef(err, "failed to get initial OSS credentials")
		}
		ossCfg = ossCfg.WithCredentialsProvider(credRefresher)
	}

	if opts.AccessRecording != nil {