assetfetch

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 14, 2026 License: Apache-2.0 Imports: 20 Imported by: 0

Documentation

Overview

Package assetfetch holds the checks every object-store plugin applies when it serves AssetProvider.FetchAsset, whatever its storage backend:

  • CheckObjectName refuses an object stored under a snapshot or tag location, before anything is read.
  • Stager.Fetch downloads into a directory private to the plugin, within its capacity, enforces max_bytes while copying, verifies the sha256, and only then replaces the caller's file.

A plugin parses its own URI scheme into an object name and an opener, and leaves the rest to this package. Errors are gRPC statuses with the codes objectstore.v1 documents for FetchAsset.

Index

Constants

View Source
const MaxURIBytes = 2048

MaxURIBytes bounds asset_uri, as the SandboxConfig CRD bounds AssetFile.url, so the checks below stay cheap whatever a SandboxConfig names.

Variables

This section is empty.

Functions

func CheckObjectName

func CheckObjectName(uri, base, object string) error

CheckObjectName requires object, the name of the object uri points at within its bucket or container, to be in canonical form and not stored under a snapshot or tag location. base is uri up to the object name (e.g. gs://<bucket>); the error names the snapshot location as base/<prefix>.

Snapshot files, manifests and tags are never assets, however their sha256 came to be known, so this returns PermissionDenied for them. Every <root> a snapshot location may have is matched, so the check holds whatever key prefix the plugin stores snapshots under.

func ParseURI

func ParseURI(uri string) (*url.URL, error)

ParseURI parses an asset URI of at most MaxURIBytes that carries no user info, query or fragment and is not opaque. Its errors do not quote the URI, since user info or a query may carry credentials; once it succeeds, the URI may be named in messages.

Types

type OpenFunc

type OpenFunc func(ctx context.Context) (rc io.ReadCloser, size int64, err error)

OpenFunc opens the asset for reading and returns its size in bytes as the storage reported it, or a negative size if it reported none. Fetch may call it twice, if it has to wait for staging space.

type Stager

type Stager struct {
	// contains filtered or unexported fields
}

Stager downloads assets into a staging directory private to the plugin and copies each to the caller's file only once its size and sha256 check out. The caller can therefore never read bytes it did not pin, such as a snapshot's.

Downloads in flight never hold more than the staging capacity. Each opens its object first, so a missing object or one larger than max_bytes or the capacity fails without waiting for space. It then reserves the object's size, or as much as max_bytes allows if the storage did not report one, and waits until that much is free, with the object closed meanwhile.

func NewStager

func NewStager(root, stagingDir string, capacity int64) (*Stager, error)

NewStager returns a Stager that writes caller files only below root and stages downloads in stagingDir, which must not be below root, holding at most capacity bytes there at once.

stagingDir is private to the plugin, so NewStager removes the downloads a previous run of the plugin left there; they would otherwise use up its capacity.

func (*Stager) Fetch

func (s *Stager) Fetch(ctx context.Context, req *objectstorev1.FetchAssetRequest, uri string, open OpenFunc, toStatus func(error) error) error

Fetch checks req's sha256, max_bytes and write_path, downloads the asset open returns into the staging directory and, if it is at most max_bytes long and hashes to sha256, replaces the existing file at write_path with it. uri is req's asset URI once it is safe to quote (see ParseURI). toStatus maps every other error, from open, the download or a local file, to a gRPC status; it must keep a context error's code.

The file at write_path keeps its old content on any error: the asset is written to a new file in the same directory, which is then swapped into place. Callers must therefore open write_path after Fetch returns; a descriptor opened before reads the old file.

The caller checks the URI (ParseURI, CheckObjectName) first, so a refused request reads nothing.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL