Skip to content

fix(fs): support Azure Central US with cloud routing regressions - #76

Merged
srstack merged 5 commits into
mainfrom
codex/azure-region-support
Oct 15, 2026
Merged

srstack merged 5 commits into
mainfrom
codex/azure-region-support

Conversation

@siddontang

Copy link
Copy Markdown
Contributor

ti fs --region azure-centralus ... currently fails during local region validation even though the Azure deployment is available. Add Azure Central US placement and its built-in Filesystem endpoint so the normal CLI workflow can reach the service.

  • Keep region parsing, installers, credentials, telemetry, and CLI documentation consistent with azure-centralus.
  • Add regression coverage for canonical region round trips, unsupported Azure regions, built-in GCP/Azure endpoint routing, token-only access, inherited DRIVE9_* isolation, stored credentials under an AWS-default profile, and Azure telemetry acceptance.
  • Check whether macOS permits reading the real WebDAV test fixture before testing readiness. Skip only an independently confirmed OS permission denial; keep readiness and other fixture failures as test failures.

Validation:

  • make test passes; this Mac skips the real WebDAV fixture when the OS denies access.
  • make e2e passes, including both GCP and Azure binary routing cases.
  • go mod tidy leaves go.mod and go.sum unchanged; formatting and whitespace checks pass.
  • Live Azure: 15/15 checks passed through the modified ti fs, including 16 MiB multipart upload, SHA-256 download verification, range reads, recursive copies, and temporary-resource deletion. The repository's live inventory lifecycle also passed.
  • GCP: 15/15 cloud checks passed before this patch; the new binary and credential-routing regressions cover its existing built-in region.

@pingcap-cla-assistant

pingcap-cla-assistant Bot commented Oct 14, 2026 •

Copy link
Copy Markdown

CLA assistant check
All committers have signed the CLA.

@siddontang

Copy link
Copy Markdown
Contributor Author

PTAL @qiffang

@srstack srstack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewed all 19 changed files across both commits. CI test is green (gofmt, go mod tidy, make test, make e2e, make build). I also applied the patch to a worktree locally: go test ./... passes, the new TestFSCloudRegionsUseBuiltInEndpoints (gcp + azure) and the installer tests pass, and I ran the DB probe below against the freshly built binary. The macOS-only WebDAV test cannot be exercised on my Linux host, so that part is verified by reading only.

Overall the Filesystem-side change is correct and well covered. I would like one decision on the MAJOR item before this merges.

[MAJOR] azure-centralus is now accepted by Starter/DB local validation

region.supported is shared by DB and FS: ResolveFS uses it (internal/api/endpoints/endpoints.go:136) and so does ResolveStarter (:100). Adding azure to supported (internal/config/region/region.go:50) therefore widens DB placement validation too.

Measured on the patched binary:

$ ti db create-db-cluster --db-cluster-type starter --db-cluster-name demo --region azure-centralus --dry-run
"region": { "name": "regions/azure-centralus" }   # local validation passed, EXIT=0

$ ti ... --region azure-eastus --dry-run
ti [ERROR]: unsupported region "eastus" for cloud provider "azure"; supported regions: centralus   # EXIT=2

README:60 ("Regions supporting TiDB Cloud Starter"), the Starter table in docs/priciples.md:69-80, and the published service matrix in ai/ti/reference/ti-regions-security-and-limitations.md all omit Azure (they also omit GCP). That matrix encodes "Starter supported / Filesystem not supported", so azure-centralus would be the first Filesystem-only case and is currently indistinguishable from a Starter-capable region at the CLI boundary.

To be fair, the drift predates this PR (gcp-us-east1 is in supported but not in the Starter docs), so this is not newly introduced. But Azure makes it permanent. Please pick one and state it in the PR description:

  1. Filesystem-only (preferred if there is no evidence that Starter has Azure Central US): split validation, e.g. a region.ValidateFilesystem used by ResolveFS and ParsePlacementCode, keeping region.Validate for ResolveStarter. DB commands then fail locally with a clear unsupported-region error while ti configure still accepts azure.
  2. If Starter really does support it, sync README:60, the Starter table in docs/priciples.md, the AGENTS.md placement table, and the published docs matrix.

[MINOR] No cross-check test between the built-in manifest and the region table

validateFSManifest (endpoints.go:253) only checks non-empty fields and duplicates; it never verifies that CloudProvider + TiDBRegion round-trip to RegionCode, and TestResolveFSUsesBuiltInRegionMapping iterates a hand-written table rather than the manifest itself. So adding a manifest entry without a matching region entry, or a typo (the v0.2.6 gcp-us-east-1 -> gcp-us-east1 class of bug), fails no test. Suggest a test that walks builtInFSRegionManifest().Regions, asserts CanonicalCode(CloudProvider, TiDBRegion) == RegionCode, and asserts each entry resolves through ResolveFS.

[MINOR] Telemetry backend must ship before or with the CLI

The new enum lives in internal/telemetrybackend/event.go (allowedRegions at :75, the oneOf(cloud_provider, ...) at :210), which is the separately deployed ti-telemetry-backend. The column is an unconstrained VARCHAR(32), so no migration is needed, but if the backend is not deployed first, Azure events are rejected as invalid cloud_provider / region_code and dropped (best-effort, no user impact). Please note the ordering in the PR description or release steps.

[MINOR] Published docs not updated

AGENTS.md requires syncing the English ti pages under docs/pingcap-docs/docs/ for user-visible changes, and this PR has no gitlink update. I checked ai/ti/reference/ti-regions-security-and-limitations.md at both the pinned submodule SHA and the current release-8.5 head: its region matrix lists only AWS x5 + Alibaba x1 (GCP is missing too). Either open the companion pingcap/docs change plus submodule bump, or state explicitly that docs ship separately.

[MINOR] mountready_test.go skip is broader than needed (commit 2)

The added os.ReadDir(mp) permission check sits before the two readiness assertions, so an EACCES on macOS skips the whole test. But defaultMountPointActive uses os.Stat + statfs (internal/fs/mountready_darwin.go:15) and needs no directory read permission, and per the comment above the test, catching the "any readable directory counts as ready" regression is exactly its purpose. Prefer tolerating the permission denial only on the final os.ReadDir(mp) assertion and keeping the readiness assertions running. Unrelated to Azure; fine to keep here if noted.

[NIT]

  • internal/config/region/region_test.go:35 still uses the literal {"azure", "eastus"} although ProviderAzure now exists. The case's meaning changed from "unknown provider" to "known provider, unknown region", and the added {"unsupported", "centralus"} preserves the old coverage - good.
  • The installer "Config regions" line (scripts/install.sh:280, scripts/install.ps1:117) now includes gcp-us-east1, azure-centralus, which matches README:107/108 (an improvement), but that label previously meant the Starter list. Consider renaming it to "Supported placement regions" so it does not imply Starter support.

What looks good

  • The routing path is correct end to end: the manifest matches on cloud_provider/tidb_region -> azure-centralus -> https://azure-centralus.drive9.ai; fsEndpoint puts the native code in RegionCode and the canonical code in RegionName, and create-file-system persists endpoint.RegionName (canonical) locally, consistent with credential validation, mount locators, and DRIVE9_REGION_CODE.
  • TestFSCloudRegionsUseBuiltInEndpoints is a strong test: pointing TI_TEST_FS_MANIFEST_URL at an unreachable address while leaving TI_ALLOW_TEST_ENDPOINTS empty proves the built-in mapping is used, and it also asserts that inherited DRIVE9_* values are stripped and that token-only access persists nothing.
  • The fscred case covering "stored credential region wins over profile placement without mutating the profile", the CanonicalCode round-trip addition in TestParsePlacementCode, and the telemetry tests on both sides are all good.

Residual risk: live acceptance was manual (15/15 per the description) and e2e/live_test.go has no Azure case. Since the region is now built in, consider running make live-e2e-fs with an Azure profile as release acceptance.

@srstack

srstack commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Pushed 4b7faa3 on top of this branch to resolve the [MAJOR] review item: azure-centralus is no longer accepted by TiDB Cloud Starter placement validation.

  • internal/config/region: azure-centralus stays in supported, so ParsePlacementCode, CanonicalCode, ti configure, profiles, and stored credentials keep working, but the placement is now marked in a filesystemOnly set. Validate (Starter) rejects it with placement "azure-centralus" serves TiDB Cloud Filesystem only, not TiDB Cloud Starter, and the new region.ValidateFilesystem accepts it for Filesystem resolution.
  • internal/api/endpoints: ResolveFS validates through ValidateFilesystem.
  • README, docs/priciples.md, and AGENTS.md document the Filesystem-only rule.
  • The azure case moved out of the Starter placement table, and Starter-rejection coverage was added in internal/config/region, internal/api/endpoints, and internal/cli.

Behavior after the change:

command result
ti fs ... --region azure-centralus routes to https://azure-centralus.drive9.ai (unchanged)
ti db ... --region azure-centralus exit 2, placement "azure-centralus" serves TiDB Cloud Filesystem only, not TiDB Cloud Starter, no request sent
ti configure --region-code azure-centralus accepted

Verified on this branch: gofmt -l clean, go mod tidy leaves go.mod/go.sum unchanged, go test ./... passes, the Filesystem and installer e2e tests pass, and the binary probes above reproduce. CI re-runs on this push.

gcp-us-east1 keeps its current behavior; applying the same model to it is a one-line addition to filesystemOnly if you want that too.

(The same policy was opened as #77 against main; closing it as superseded now that this branch carries the change.)

@ti-chi-bot ti-chi-bot Bot added size/XL and removed size/L labels Oct 15, 2026

@srstack srstack left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

4b7faa3 addresses the placement-validation concern from my earlier review:

  • azure-centralus is now a Filesystem-only placement: region.Validate (Starter) rejects it, region.ValidateFilesystem accepts it, and ResolveFS uses the Filesystem path.
  • ti db ... --region azure-centralus fails locally with exit code 2 and an explicit Filesystem-only error instead of sending regions/azure-centralus to the Starter API, while ti fs routing is unchanged.
  • ParsePlacementCode/CanonicalCode still accept the placement, so --region, ti configure, profiles, and stored credentials keep working.
  • Starter-rejection coverage was added in internal/config/region, internal/api/endpoints, and internal/cli, and the azure case moved out of the Starter placement table.

CI test is green on the new commit. Two non-blocking follow-ups remain: roll out the ti-telemetry-backend enum change before or with the CLI release, and update the published regions page (separate docs repo/submodule), which currently lists neither GCP nor Azure. gcp-us-east1 was intentionally left unchanged.

@srstack

srstack commented Oct 15, 2026

Copy link
Copy Markdown
Contributor

Pushed 718455f: gcp-us-east1 is now handled by the same Filesystem-only rule as azure-centralus.

gcp-us-east1 was in the shared placement table without being marked Filesystem-only, so ti db ... --region gcp-us-east1 still passed local placement validation even though the v0.2.5 release note and the published docs limit TiDB Cloud Starter to AWS and Alibaba Cloud. It is now in filesystemOnly alongside azure-centralus:

$ ti --region gcp-us-east1 db create-db-cluster --db-cluster-type starter --db-cluster-name demo --dry-run
ti [ERROR]: placement "gcp-us-east1" serves TiDB Cloud Filesystem only, not TiDB Cloud Starter   # exit 2

$ ti --region gcp-us-east1 fs create-file-system --dry-run   # exit 0, still routes to https://gcp-us-east1.drive9.ai

$ ti --region aws-us-east-1 db create-db-cluster ... --dry-run   # exit 0, unchanged
  • README, docs/priciples.md, and AGENTS.md now list both Filesystem-only placements.
  • region_test.go, endpoints_test.go, and the CLI test cover gcp and azure rejection; the gcp/azure Filesystem routing e2e (TestFSCloudRegionsUseBuiltInEndpoints) still passes.
  • Verified locally: gofmt clean, go mod tidy leaves go.mod/go.sum unchanged, go test ./... passes, targeted e2e passes.

siddontang and others added 5 commits October 15, 2026 21:33
Signed-off-by: siddon <siddontang@gmail.com>
Signed-off-by: siddon <siddontang@gmail.com>
`region.supported` is shared by TiDB Cloud Starter and Filesystem
resolution, so adding azure-centralus there also let `ti db` commands
accept the placement locally and send `regions/azure-centralus` to the
Starter API, which the product documentation does not list as a Starter
placement.

Mark the placement as Filesystem-only instead. `region.Validate` (Starter)
now rejects it with `placement "azure-centralus" serves TiDB Cloud
Filesystem only, not TiDB Cloud Starter`, while the new
`region.ValidateFilesystem` accepts it and `ResolveFS` validates through
that function. `ParsePlacementCode` and `CanonicalCode` keep accepting
every known placement, so `--region`, `ti configure`, profiles, and stored
credentials are unaffected.

- README, docs/priciples.md, and AGENTS.md document the rule.
- Tests cover the Filesystem-only rejection in internal/config/region,
  internal/api/endpoints, and internal/cli, and move the azure placement
  out of the Starter placement table.

`gcp-us-east1` keeps its current behavior; applying the same model to it is
a one-line addition to `filesystemOnly`.
Empty commit to force a fresh mergeability evaluation after the CLA status
turned green and the reviewing account switched to APPROVED. No content
change.
`gcp-us-east1` serves TiDB Cloud Filesystem only. The v0.2.5 release note
and the product documentation already limit TiDB Cloud Starter to the AWS
and Alibaba Cloud placements, but the shared placement table still let
`ti db` commands accept the placement locally and send
`regions/gcp-us-east1` to the Starter API.

Add it to `filesystemOnly` so `region.Validate` rejects it with
`placement "gcp-us-east1" serves TiDB Cloud Filesystem only, not TiDB
Cloud Starter`, while `region.ValidateFilesystem` keeps routing `ti fs`
to the built-in endpoint. README, docs/priciples.md, and AGENTS.md now
list both Filesystem-only placements, and the Starter rejection tests
cover gcp and azure.
@srstack
srstack force-pushed the codex/azure-region-support branch from 718455f to afa9a89 Compare October 15, 2026 13:33
@srstack
srstack merged commit 6fc2df3 into main Oct 15, 2026
2 checks passed
@srstack
srstack deleted the codex/azure-region-support branch October 15, 2026 13:33
@srstack srstack mentioned this pull request Oct 15, 2026
3 of 4 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants