oci

package module
v0.1.0 Latest Latest
Warning

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

Go to latest
Published: Jun 22, 2026 License: BSD-3-Clause Imports: 20 Imported by: 0

README

go-filesystems/oci

oci

Go Reference CI

Pure-Go, read-only OCI / Docker image filesystem for the go-filesystems family. It overlays an image's tar layers — honouring whiteouts, opaque directories, hardlinks and symlinks — and serves the merged rootfs through go-filesystems/interface. No container runtime, no cgo.

Why

A container image is a filesystem: an ordered stack of tar layers that overlay into a rootfs. This driver reads that rootfs natively — to mkfs it into an ext4 image, serve it read-only over virtio-fs, or inspect it — without pulling in containerd, a runtime, or any C toolchain.

Install

go get github.com/go-filesystems/oci

Usage

import "github.com/go-filesystems/oci"

// From an OCI image layout directory…
fsys, err := oci.OpenLayout("path/to/oci-layout")
// …or a `docker save` / OCI archive tarball:
//   fsys, err := oci.OpenTarball("image.tar")
if err != nil {
    return err
}
defer fsys.Close()

data, err := fsys.ReadFile("/etc/os-release")
entries, err := fsys.ListDir("/usr/bin")
st, err := fsys.Stat("/bin/sh")
target, err := fsys.ReadLink("/bin/sh") // if it is a symlink

fsys satisfies filesystem.Filesystem. For a multi-arch index, select a manifest with OpenSelect/OpenDescriptor; to read from a custom blob store, implement BlobSource and call Open.

The image is read only: WriteFile, MkDir, DeleteFile, DeleteDir and Rename return ErrReadOnly.

Layer compression

gzip and uncompressed layers are built in (stdlib only). Other codecs are opt-in with no extra dependency — register them yourself:

oci.RegisterDecompressor(oci.MediaTypeLayerTarZstd, func(r io.Reader) (io.Reader, error) {
    return zstd.NewReader(r) // your pure-Go zstd of choice
})

License

BSD-3-Clause © the go-filesystems/oci authors.

Documentation

Overview

Package oci presents an OCI/Docker image as a read-only github.com/go-filesystems/interface Filesystem by overlaying the image's tar layers with overlayfs semantics. It is pure Go (CGO_ENABLED=0) and pulls no third-party dependencies for its core: gzip and plain layers are handled by the standard library, and any other compression (e.g. zstd) is supported through an injectable Decompressor registry.

Index

Constants

View Source
const (
	// Uncompressed tar layers.
	MediaTypeLayerTar       = "application/vnd.oci.image.layer.v1.tar"
	MediaTypeDockerLayerTar = "application/vnd.docker.image.rootfs.diff.tar"

	// gzip-compressed tar layers.
	MediaTypeLayerTarGzip       = "application/vnd.oci.image.layer.v1.tar+gzip"
	MediaTypeDockerLayerTarGzip = "application/vnd.docker.image.rootfs.diff.tar.gzip"

	// zstd-compressed tar layers (no built-in decompressor; register one).
	MediaTypeLayerTarZstd = "application/vnd.oci.image.layer.v1.tar+zstd"

	// Manifest / index media types we resolve.
	MediaTypeImageManifest      = "application/vnd.oci.image.manifest.v1+json"
	MediaTypeImageIndex         = "application/vnd.oci.image.index.v1+json"
	MediaTypeDockerManifest     = "application/vnd.docker.distribution.manifest.v2+json"
	MediaTypeDockerManifestList = "application/vnd.docker.distribution.manifest.list.v2+json"
	MediaTypeImageConfig        = "application/vnd.oci.image.config.v1+json"
	MediaTypeDockerImageConfig  = "application/vnd.docker.container.image.v1+json"
)

Built-in OCI / Docker layer media types.

View Source
const (
	FileTypeUnknown uint8 = iota
	FileTypeRegular
	FileTypeDir
	FileTypeSymlink
	FileTypeHardlink
	FileTypeChar
	FileTypeBlock
	FileTypeFifo
)

FileType constants returned by DirEntry.FileType() and node.ftype. The go-filesystems/interface package does not define these, so we define a local mapping that mirrors the POSIX d_type / tar typeflag taxonomy.

Variables

View Source
var ErrReadOnly = errors.New("oci: read-only filesystem")

ErrReadOnly is returned by every mutating method of FS. An OCI image filesystem is immutable: it is a read-only overlay of the image's layers.

Functions

func RegisterDecompressor

func RegisterDecompressor(mediaType string, d Decompressor)

RegisterDecompressor registers d for the given layer media type, replacing any previous registration. Pass a media type such as MediaTypeLayerTarZstd to enable zstd without a core dependency.

Types

type BlobSource

type BlobSource interface {
	// Blob returns a reader for the blob identified by digest. The caller
	// must Close the returned reader. An error wrapping fs.ErrNotExist is
	// returned when the digest is unknown.
	Blob(digest string) (io.ReadCloser, error)
}

BlobSource provides content-addressed access to an image's blobs (manifests, configs and layers) by their digest string (e.g. "sha256:abc...").

func OCILayout

func OCILayout(dir string) BlobSource

OCILayout returns a BlobSource backed by an OCI image layout directory, i.e. a directory containing an "oci-layout" marker, "index.json" and a "blobs/<alg>/<hex>" content store.

func Tarball

func Tarball(p string) (BlobSource, error)

Tarball returns a BlobSource backed by a `docker save` / OCI archive tar file on disk.

func TarballFS

func TarballFS(fsys fs.FS) (BlobSource, error)

TarballFS returns a BlobSource backed by an archive tar exposed through an fs.FS. The archive is expected at the path "image.tar"; if absent, the first (and only) regular file is used. Most callers should prefer Tarball.

type Decompressor

type Decompressor func(r io.Reader) (io.Reader, error)

Decompressor wraps a raw layer blob reader and returns a reader that yields the decompressed tar stream. Implementations must not assume ownership of r; closing the underlying blob is the caller's responsibility.

type FS

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

FS is a read-only github.com/go-filesystems/interface Filesystem view over an OCI/Docker image's merged layer tree.

ReadFile strategy: file contents are buffered into the in-memory merged tree at Open time (each regular file's bytes are read once while its owning layer is decompressed). This keeps ReadFile a pure in-memory lookup, makes hardlink resolution trivial (both names share the target's buffered bytes), and avoids holding blob file handles open after Open returns. The trade-off is memory proportional to the uncompressed image size; for the disk-image-as-filesystem use cases this driver targets that is acceptable and matches how the sibling drivers buffer their trees.

func Open

func Open(src BlobSource) (*FS, error)

Open resolves the single image addressed by src (the first manifest in the index, or a multi-arch index's first matching manifest) and returns a read-only FS over its merged layers. To select a specific manifest from a multi-arch index, pass a Selector via OpenSelect.

func OpenDescriptor

func OpenDescriptor(src BlobSource, top descriptor, sel Selector) (*FS, error)

OpenDescriptor opens an image given an explicit top-level descriptor, allowing use of a bare BlobSource that does not embed index discovery.

func OpenLayout

func OpenLayout(dir string) (*FS, error)

OpenLayout is a convenience wrapper: OpenLayout(dir) == Open(OCILayout(dir)).

func OpenSelect

func OpenSelect(src BlobSource, sel Selector) (*FS, error)

OpenSelect is like Open but selects a manifest from a multi-arch index by digest or platform.

func OpenTarball

func OpenTarball(p string) (*FS, error)

OpenTarball is a convenience wrapper around Tarball.

func (*FS) Close

func (f *FS) Close() error

Close releases the filesystem. It is idempotent; a second call returns nil.

func (*FS) DeleteDir

func (f *FS) DeleteDir(path string) error

DeleteDir always returns ErrReadOnly.

func (*FS) DeleteFile

func (f *FS) DeleteFile(path string) error

DeleteFile always returns ErrReadOnly.

func (*FS) ListDir

func (f *FS) ListDir(path string) ([]filesystem.DirEntry, error)

ListDir returns the entries of the directory at path, sorted by name.

func (*FS) MkDir

func (f *FS) MkDir(path string, perm os.FileMode) error

MkDir always returns ErrReadOnly.

func (*FS) ReadFile

func (f *FS) ReadFile(path string) ([]byte, error)

ReadFile returns the contents of the regular file (or hardlink to one) at path.

func (f *FS) ReadLink(path string) (string, error)

ReadLink returns the target of the symbolic link at path.

func (*FS) Rename

func (f *FS) Rename(oldPath, newPath string) error

Rename always returns ErrReadOnly.

func (*FS) Stat

func (f *FS) Stat(path string) (filesystem.Stat, error)

Stat returns metadata for path. Mode packs the POSIX type bits with the permission bits.

func (*FS) WriteFile

func (f *FS) WriteFile(path string, data []byte, perm os.FileMode) error

WriteFile always returns ErrReadOnly.

type Selector

type Selector struct {
	// Digest, if non-empty, selects the manifest descriptor whose digest
	// matches exactly.
	Digest string
	// OS / Architecture / Variant, if set, select by platform. Empty fields
	// are treated as wildcards.
	OS           string
	Architecture string
	Variant      string
}

Selector picks one manifest from a multi-manifest index.

Jump to

Keyboard shortcuts

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