Back to Microsandbox

Images

docs/sdk/go/images.mdx

0.6.725.8 KB
Original Source

Inspect and prune the local OCI image cache: the images that sandbox creation has already pulled. Images can also be loaded into the cache from local archives and saved back out to archive files, so locally built images work without a registry. Everything is reached through the package-level Image value, or through an ImageHandle once you hold one.

go
import m "github.com/superradcompany/microsandbox/sdk/go"
<div className="msb-glance"> <p className="msb-gl"><span className="msb-dot static"></span>Functions<span className="msb-ct">7</span></p> <a className="msb-row" href="#image-get"><span className="msb-rn">Image.Get()</span><span className="msb-rg">one cached image by reference</span></a> <a className="msb-row" href="#image-list"><span className="msb-rn">Image.List()</span><span className="msb-rg">every cached image</span></a> <a className="msb-row" href="#image-inspect"><span className="msb-rn">Image.Inspect()</span><span className="msb-rg">handle + config + layers</span></a> <a className="msb-row" href="#image-remove"><span className="msb-rn">Image.Remove()</span><span className="msb-rg">delete a cached image</span></a> <a className="msb-row" href="#image-prune"><span className="msb-rn">Image.Prune()</span><span className="msb-rg">reclaim unused image data</span></a> <a className="msb-row" href="#image-load"><span className="msb-rn">Image.Load()</span><span className="msb-rg">import from archive</span></a> <a className="msb-row" href="#image-save"><span className="msb-rn">Image.Save()</span><span className="msb-rg">export to archive</span></a> <p className="msb-gl"><span className="msb-dot instance"></span>Methods · ImageHandle<span className="msb-ct">10</span></p> <a className="msb-row" href="#h-reference"><span className="msb-rn">h.Reference()</span><span className="msb-rg">image reference</span></a> <a className="msb-row" href="#h-manifestdigest"><span className="msb-rn">h.ManifestDigest()</span><span className="msb-rg">manifest digest</span></a> <a className="msb-row" href="#h-architecture"><span className="msb-rn">h.Architecture()</span><span className="msb-rg">resolved architecture</span></a> <a className="msb-row" href="#h-os"><span className="msb-rn">h.OS()</span><span className="msb-rg">resolved operating system</span></a> <a className="msb-row" href="#h-layercount"><span className="msb-rn">h.LayerCount()</span><span className="msb-rg">number of layers</span></a> <a className="msb-row" href="#h-sizebytes"><span className="msb-rn">h.SizeBytes()</span><span className="msb-rg">total size in bytes</span></a> <a className="msb-row" href="#h-createdat"><span className="msb-rn">h.CreatedAt()</span><span className="msb-rg">first-pulled time</span></a> <a className="msb-row" href="#h-lastusedat"><span className="msb-rn">h.LastUsedAt()</span><span className="msb-rg">last-referenced time</span></a> <a className="msb-row" href="#h-remove"><span className="msb-rn">h.Remove()</span><span className="msb-rg">delete this image</span></a> <a className="msb-row" href="#h-inspect"><span className="msb-rn">h.Inspect()</span><span className="msb-rg">full detail for this image</span></a> <p className="msb-gl"><span className="msb-dot type"></span>Types</p> <div className="msb-chiprow"> <a className="msb-typepill" href="#imagehandle">ImageHandle</a> <a className="msb-typepill" href="#imagedetail">ImageDetail</a> <a className="msb-typepill" href="#imageconfig">ImageConfig</a> <a className="msb-typepill" href="#imagelayer">ImageLayer</a> <a className="msb-typepill" href="#imageprunereport">ImagePruneReport</a> <a className="msb-typepill" href="#imagearchiveformat">ImageArchiveFormat</a> </div> </div> <p className="msb-label" id="typical-flow">Typical flow</p>
go
import m "github.com/superradcompany/microsandbox/sdk/go"

images, err := m.Image.List(ctx)        // 1. enumerate the cache
if err != nil {
    return err
}
for _, img := range images {
    fmt.Println(img.Reference(), img.LayerCount())
}

report, err := m.Image.Prune(ctx)       // 2. reclaim unused data
if err != nil {
    return err
}
fmt.Println(report.LayersRemoved, "layers removed")

Functions

<span className="msb-recv">Image.</span><span className="msb-hn">Get()</span>

go
func (imageFactory) Get(ctx context.Context, reference string) (*ImageHandle, error)
<Accordion title="Example">
go
img, err := m.Image.Get(ctx, "python:3.12")
if err != nil {
    return err
}
fmt.Println(img.ManifestDigest())
</Accordion>

Fetch one cached image by reference. Returns ErrImageNotFound when no image with that reference is present in the local cache.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the lookup.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>reference</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Image reference, e.g. <code>"python:3.12"</code>.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imagehandle">*ImageHandle</a></div> <div className="msb-param-desc">Metadata handle for the cached image.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc"><code>ErrImageNotFound</code> when the reference is not cached.</div> </div> </div>

<span className="msb-recv">Image.</span><span className="msb-hn">List()</span>

go
func (imageFactory) List(ctx context.Context) ([]*ImageHandle, error)
<Accordion title="Example">
go
images, err := m.Image.List(ctx)
if err != nil {
    return err
}
for _, img := range images {
    fmt.Println(img.Reference(), img.LayerCount())
}
</Accordion>

Return every cached image, ordered by creation time (newest first).

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the listing.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imagehandle">[]*ImageHandle</a></div> <div className="msb-param-desc">All cached image handles, newest first.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Non-nil on failure.</div> </div> </div>

<span className="msb-recv">Image.</span><span className="msb-hn">Inspect()</span>

go
func (imageFactory) Inspect(ctx context.Context, reference string) (*ImageDetail, error)
<Accordion title="Example">
go
detail, err := m.Image.Inspect(ctx, "python:3.12")
if err != nil {
    return err
}
fmt.Println(detail.Config.Entrypoint, len(detail.Layers), "layers")
</Accordion>

Return the full detail for a cached image: the ImageHandle plus the parsed OCI config and the layer list.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the inspection.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>reference</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Image reference, e.g. <code>"python:3.12"</code>.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imagedetail">*ImageDetail</a></div> <div className="msb-param-desc">Handle, OCI config, and layers.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc"><code>ErrImageNotFound</code> when the reference is not cached.</div> </div> </div>

<span className="msb-recv">Image.</span><span className="msb-hn">Remove()</span>

go
func (imageFactory) Remove(ctx context.Context, reference string, force bool) error
<Accordion title="Example">
go
if err := m.Image.Remove(ctx, "old:tag", false); err != nil {
    return err
}
</Accordion>

Delete a cached image. When force is false, sandboxes that still reference the image cause the call to fail with ErrImageInUse.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the removal.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>reference</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Image reference to delete.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>force</code><span className="msb-type">bool</span></div> <div className="msb-param-desc">When <code>true</code>, remove even if sandboxes still reference it.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc"><code>ErrImageInUse</code> when in use and <code>force</code> is false.</div> </div> </div>

<span className="msb-recv">Image.</span><span className="msb-hn">Prune()</span>

go
func (imageFactory) Prune(ctx context.Context) (*ImagePruneReport, error)
<Accordion title="Example">
go
report, err := m.Image.Prune(ctx)
if err != nil {
    return err
}
fmt.Println(report.LayersRemoved, "layers removed")
</Accordion>

Remove cached image data that is not used by any sandbox or indexed snapshot. Returns a report tallying the image refs, manifests, layers, fsmeta files, and VMDK files removed, plus bytes reclaimed.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the prune.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imageprunereport">*ImagePruneReport</a></div> <div className="msb-param-desc">Summary of what was reclaimed.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Non-nil on failure.</div> </div> </div> <Accordion title="Example">
go
report, err := m.Image.Prune(ctx)
if err != nil {
    return err
}
fmt.Println(report.LayersRemoved, "layers removed")
</Accordion>

<span className="msb-recv">Image.</span><span className="msb-hn">Load()</span>

<div className="msb-tags"><span className="msb-tag is-static">function</span></div>
go
func (imageFactory) Load(ctx context.Context, inputPath string, tags ...string) ([]*ImageHandle, error)

Import images from a local archive — a docker save tarball or an OCI Image Layout archive — into the cache, so locally built images can be used without a registry. Variadic tags apply extra references to the first image in the archive.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the import.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>inputPath</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Path to the archive file.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>tags</code><span className="msb-type">...string</span></div> <div className="msb-param-desc">Extra references applied to the first image in the archive.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imagehandle">[]*ImageHandle</a></div> <div className="msb-param-desc">One handle for every image reference imported.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Non-nil on failure.</div> </div> </div> <Accordion title="Example">
go
// docker save my-image:latest -o my-image.tar
images, err := m.Image.Load(ctx, "my-image.tar", "app:local")
if err != nil {
    return err
}
for _, img := range images {
    fmt.Println(img.Reference())
}
</Accordion>

<span className="msb-recv">Image.</span><span className="msb-hn">Save()</span>

<div className="msb-tags"><span className="msb-tag is-static">function</span></div>
go
func (imageFactory) Save(ctx context.Context, references []string, outputPath string, format ImageArchiveFormat) error

Export one or more cached images to an archive file at outputPath. ImageArchiveDocker (the default; "" behaves the same) writes an archive loadable with docker load; ImageArchiveOCI writes an OCI Image Layout archive. Returns ErrImageNotFound when any reference is missing from the local cache.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the export.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>references</code><span className="msb-type">[]string</span></div> <div className="msb-param-desc">Image references to export, e.g. <code>"python:3.12"</code>.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>outputPath</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Path of the archive file to write.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>format</code><a className="msb-type" href="#imagearchiveformat">ImageArchiveFormat</a></div> <div className="msb-param-desc"><code>ImageArchiveDocker</code> (default; <code>""</code> behaves the same) or <code>ImageArchiveOCI</code>.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc"><code>ErrImageNotFound</code> when any reference is not cached.</div> </div> </div> <Accordion title="Example">
go
err := m.Image.Save(ctx, []string{"python:3.12"}, "python.tar", m.ImageArchiveDocker)
if err != nil {
    return err
}
</Accordion>

Methods

Instance methods on *ImageHandle, the metadata reference returned by Image.Get and Image.List. The accessors are pure reads of cached metadata; only Remove and Inspect take a context and reach the runtime.

<span className="msb-recv">h.</span><span className="msb-hn">Reference()</span>

go
func (h *ImageHandle) Reference() string

The image reference, e.g. "docker.io/library/python:3.12".

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">string</span></div> <div className="msb-param-desc">Image reference.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">ManifestDigest()</span>

go
func (h *ImageHandle) ManifestDigest() string

The content-addressable manifest digest, or empty when unknown.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">string</span></div> <div className="msb-param-desc">Manifest digest, or empty.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">Architecture()</span>

go
func (h *ImageHandle) Architecture() string

The architecture resolved during the pull, or empty.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">string</span></div> <div className="msb-param-desc">Architecture, or empty.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">OS()</span>

go
func (h *ImageHandle) OS() string

The operating system resolved during the pull, or empty.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">string</span></div> <div className="msb-param-desc">Operating system, or empty.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">LayerCount()</span>

go
func (h *ImageHandle) LayerCount() uint

The number of layers in the image.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">uint</span></div> <div className="msb-param-desc">Layer count.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">SizeBytes()</span>

go
func (h *ImageHandle) SizeBytes() *int64

The total image size in bytes, or nil when unknown.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">*int64</span></div> <div className="msb-param-desc">Total size in bytes, or <code>nil</code>.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">CreatedAt()</span>

go
func (h *ImageHandle) CreatedAt() time.Time

When this image was first pulled. Returns the zero time.Time when unknown.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">time.Time</span></div> <div className="msb-param-desc">First-pulled time, or the zero value.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">LastUsedAt()</span>

go
func (h *ImageHandle) LastUsedAt() time.Time

When this image was last referenced. Returns the zero time.Time when unknown.

<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">time.Time</span></div> <div className="msb-param-desc">Last-referenced time, or the zero value.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">Remove()</span>

go
func (h *ImageHandle) Remove(ctx context.Context, force bool) error
<Accordion title="Example">
go
img, err := m.Image.Get(ctx, "old:tag")
if err != nil {
    return err
}
if err := img.Remove(ctx, false); err != nil {
    return err
}
</Accordion>

Delete this image. Equivalent to Image.Remove(ctx, h.Reference(), force). When force is false, sandboxes that still reference the image cause the call to fail with ErrImageInUse.

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the removal.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>force</code><span className="msb-type">bool</span></div> <div className="msb-param-desc">When <code>true</code>, remove even if sandboxes still reference it.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc"><code>ErrImageInUse</code> when in use and <code>force</code> is false.</div> </div> </div>

<span className="msb-recv">h.</span><span className="msb-hn">Inspect()</span>

go
func (h *ImageHandle) Inspect(ctx context.Context) (*ImageDetail, error)
<Accordion title="Example">
go
img, err := m.Image.Get(ctx, "python:3.12")
if err != nil {
    return err
}
detail, err := img.Inspect(ctx)
if err != nil {
    return err
}
fmt.Println(detail.Config.WorkingDir)
</Accordion>

Return the full detail for this image. Equivalent to Image.Inspect(ctx, h.Reference()).

<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>ctx</code><span className="msb-type">context.Context</span></div> <div className="msb-param-desc">Cancels the inspection.</div> </div> </div> <p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><a className="msb-type" href="#imagedetail">*ImageDetail</a></div> <div className="msb-param-desc">Handle, OCI config, and layers.</div> </div> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">error</span></div> <div className="msb-param-desc">Non-nil on failure.</div> </div> </div>

Types

ImageHandle

<p className="msb-backref">Returned by <a href="#image-get">Image.Get()</a> · <a href="#image-list">Image.List()</a></p>

A lightweight metadata reference to a cached OCI image. Fields are unexported; read them through the accessor methods below. Embedded in ImageDetail.

MethodReturnsDescription
Reference()stringImage reference
ManifestDigest()stringContent-addressable manifest digest, or empty
Architecture()stringResolved architecture, or empty
OS()stringResolved operating system, or empty
LayerCount()uintNumber of layers
SizeBytes()*int64Total size in bytes, or nil when unknown
CreatedAt()time.TimeFirst-pulled time, or the zero value
LastUsedAt()time.TimeLast-referenced time, or the zero value
Remove(ctx, force)errorDelete this image
Inspect(ctx)(*ImageDetail, error)Fetch full detail for this image

ImageDetail

<p className="msb-backref">Returned by <a href="#image-inspect">Image.Inspect()</a> · <a href="#h-inspect">Inspect()</a></p>

Bundles an ImageHandle (embedded, so all its accessors are promoted) with the parsed OCI config and layer list.

go
type ImageDetail struct {
    *ImageHandle
    Config *ImageConfig
    Layers []ImageLayer
}
FieldTypeDescription
*ImageHandle*ImageHandleEmbedded metadata handle (accessors promoted)
Config*ImageConfigParsed OCI config block
Layers[]ImageLayerLayers in manifest order

ImageConfig

<p className="msb-backref">Used by <a href="#imagedetail">ImageDetail.Config</a></p>

The parsed OCI config block.

FieldTypeDescription
DigeststringConfig blob digest
Env[]stringEnvironment variables (KEY=VALUE)
Cmd[]stringDefault command
Entrypoint[]stringEntrypoint
WorkingDirstringWorking directory
UserstringDefault user
Labelsmap[string]stringOCI labels
StopSignalstringStop signal

ImageLayer

<p className="msb-backref">Used by <a href="#imagedetail">ImageDetail.Layers</a></p>

One layer of an image manifest.

FieldTypeDescription
DiffIDstringUncompressed layer diff ID
BlobDigeststringCompressed blob digest
MediaTypestringLayer media type
CompressedSizeBytes*int64Compressed size in bytes, or nil
ErofsSizeBytes*int64EROFS size in bytes, or nil
Positionint32Index in the layer stack

ImagePruneReport

<p className="msb-backref">Returned by <a href="#image-prune">Image.Prune()</a></p>

Summarizes the artifacts removed by Image.Prune.

FieldTypeDescription
ImageRefsRemoveduint32Image references removed
ManifestsRemoveduint32Manifests removed
LayersRemoveduint32Layers removed
FsmetaRemoveduint32Fsmeta files removed
VMDKRemoveduint32VMDK files removed
BytesReclaimed*uint64Bytes reclaimed, or nil when unknown

ImageArchiveFormat

<div className="msb-tags"><span className="msb-tag is-type">type</span></div> <p className="msb-backref">Used by <a href="#image-save">Image.Save()</a></p>

Selects the archive layout written by Image.Save.

go
type ImageArchiveFormat string
ConstantValueDescription
ImageArchiveDocker"docker"docker save compatible archive, loadable with docker load (the default; the empty string means the same)
ImageArchiveOCI"oci"OCI Image Layout archive