Skip to content

/vsigs/: add GS_GENERATION option to read a specific object version#14947

Draft
alexberndt wants to merge 1 commit into
OSGeo:masterfrom
alexberndt:vsigs-generation
Draft

/vsigs/: add GS_GENERATION option to read a specific object version#14947
alexberndt wants to merge 1 commit into
OSGeo:masterfrom
alexberndt:vsigs-generation

Conversation

@alexberndt

@alexberndt alexberndt commented Jul 13, 2026

Copy link
Copy Markdown

What this does

Adds an opt-in GS_GENERATION configuration option to the /vsigs/ virtual file system, letting callers read a specific (possibly non-current) object generation from a GCS bucket with Object Versioning enabled, instead of always reading the live object.

When set, the generation is forwarded as a real generation=<n> query parameter on requests, which the GCS XML API honours. It is typically set as a path-specific option, since a generation is per-object:

gdal.SetPathSpecificOption("/vsigs/my-bucket/img.tif", "GS_GENERATION", "1712345678901234")

Motivation

Reproducible reads / data lineage: reading the exact bytes a job consumed even after the live object has been overwritten. Useful for ML and data pipelines where an input path is mutable but historical versions are retained via Object Versioning. Closes #14946.

Previously neither a #generation fragment nor a ?generation= query string worked: VSIGSHandleHelper stores the whole bucket/object string as the key and URL-encodes it as a whole, so an appended query string was folded into the object name rather than sent as a real query parameter.

Notes for review

  • The OAuth2 bearer-token auth path (the common case) needs only the query-parameter forwarding.
  • For HMAC signing (GS_SECRET_ACCESS_KEY), the generation is also added to the string-to-sign's canonical resource. This branch carries a TODO in code:
    • I have not verified it against a real HMAC-signed request, so a second pair ofeyes there is welcome. Happy to split it out or gate it if preferred.
  • A non-numeric value is rejected at handle construction.

Testing

  • New autotests in autotest/gcore/vsigs.py: one asserts the request carries ?generation=<n>, one asserts an invalid value is rejected.
  • Full gcore/vsigs.py suite passes locally (31 passed, 3 skipped), no regression to the existing read / signing tests.
  • pre-commit (clang-format, black, isort, flake8) passes on the changed files.

GCS assigns a generation number to every object write; with Object
Versioning enabled, non-current generations are retained and
individually addressable. Until now /vsigs/ always read the live
object, and neither a "#generation" fragment nor a "?generation="
query string worked: the object key is URL-encoded as a whole, so an
appended query string was folded into the object name rather than sent
as a real query parameter.

Add an opt-in, path-specific GS_GENERATION config option, forwarded as
a real "generation=<n>" query parameter on requests so a specific
(possibly non-current) version is read. The OAuth2 bearer-token auth
path needs only the forwarding; for HMAC signing the generation is
also added to the canonical resource (flagged in-code as not yet
verified against a real signed request). A non-numeric value is
rejected at handle construction.

Includes autotests asserting the query parameter reaches the request
and that an invalid value is rejected, plus documentation of the new
option.

Refs OSGeo#14946
@alexberndt alexberndt marked this pull request as draft July 13, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

/vsigs/: support reading a specific object generation (GCS object versioning)

1 participant