docs/sdk/go/volumes.mdx
Create and manage named persistent volumes, read and write their data directly on the host, and attach them (or bind mounts, tmpfs, and disk images) to sandboxes. See Volumes for usage examples and patterns.
<div className="msb-glance"> <p className="msb-gl"><span className="msb-dot static"></span>Functions<span className="msb-ct">4</span></p> <a className="msb-row" href="#createvolume"><span className="msb-rn">CreateVolume()</span><span className="msb-rg">create a named volume</span></a> <a className="msb-row" href="#getvolume"><span className="msb-rn">GetVolume()</span><span className="msb-rg">look up one by name</span></a> <a className="msb-row" href="#listvolumes"><span className="msb-rn">ListVolumes()</span><span className="msb-rg">all volumes on the host</span></a> <a className="msb-row" href="#removevolume"><span className="msb-rn">RemoveVolume()</span><span className="msb-rg">delete one by name</span></a> <p className="msb-gl"><span className="msb-dot instance"></span>Methods · Volume<span className="msb-ct">4</span></p> <a className="msb-row" href="#v-name"><span className="msb-rn">v.Name()</span><span className="msb-rg">volume name</span></a> <a className="msb-row" href="#v-path"><span className="msb-rn">v.Path()</span><span className="msb-rg">host data directory path</span></a> <a className="msb-row" href="#v-fs"><span className="msb-rn">v.FS()</span><span className="msb-rg">host-side file access</span></a> <a className="msb-row" href="#v-remove"><span className="msb-rn">v.Remove()</span><span className="msb-rg">delete this volume</span></a> <p className="msb-gl"><span className="msb-dot instance"></span>Methods · VolumeHandle<span className="msb-ct">12</span></p> <a className="msb-row" href="#h-name"><span className="msb-rn">h.Name()</span><span className="msb-rg">volume name</span></a> <a className="msb-row" href="#h-path"><span className="msb-rn">h.Path()</span><span className="msb-rg">host data directory path</span></a> <a className="msb-row" href="#h-kind"><span className="msb-rn">h.Kind()</span><span className="msb-rg">dir or disk backing</span></a> <a className="msb-row" href="#h-quotamib"><span className="msb-rn">h.QuotaMiB()</span><span className="msb-rg">quota in MiB, or nil</span></a> <a className="msb-row" href="#h-usedbytes"><span className="msb-rn">h.UsedBytes()</span><span className="msb-rg">space used in bytes</span></a> <a className="msb-row" href="#h-capacitybytes"><span className="msb-rn">h.CapacityBytes()</span><span className="msb-rg">disk capacity in bytes</span></a> <a className="msb-row" href="#h-diskformat"><span className="msb-rn">h.DiskFormat()</span><span className="msb-rg">disk image format</span></a> <a className="msb-row" href="#h-diskfstype"><span className="msb-rn">h.DiskFstype()</span><span className="msb-rg">inner filesystem type</span></a> <a className="msb-row" href="#h-labels"><span className="msb-rn">h.Labels()</span><span className="msb-rg">metadata labels</span></a> <a className="msb-row" href="#h-createdat"><span className="msb-rn">h.CreatedAt()</span><span className="msb-rg">creation timestamp</span></a> <a className="msb-row" href="#h-fs"><span className="msb-rn">h.FS()</span><span className="msb-rg">host-side file access</span></a> <a className="msb-row" href="#h-remove"><span className="msb-rn">h.Remove()</span><span className="msb-rg">delete this volume</span></a> <p className="msb-gl"><span className="msb-dot instance"></span>Methods · VolumeFs<span className="msb-ct">9</span></p> <a className="msb-row" href="#vfs-root"><span className="msb-rn">vfs.Root()</span><span className="msb-rg">absolute root path</span></a> <a className="msb-row" href="#vfs-read"><span className="msb-rn">vfs.Read()</span><span className="msb-rg">read file bytes</span></a> <a className="msb-row" href="#vfs-readstring"><span className="msb-rn">vfs.ReadString()</span><span className="msb-rg">read file as string</span></a> <a className="msb-row" href="#vfs-write"><span className="msb-rn">vfs.Write()</span><span className="msb-rg">write bytes to a file</span></a> <a className="msb-row" href="#vfs-writestring"><span className="msb-rn">vfs.WriteString()</span><span className="msb-rg">write a string</span></a> <a className="msb-row" href="#vfs-mkdir"><span className="msb-rn">vfs.Mkdir()</span><span className="msb-rg">create directory tree</span></a> <a className="msb-row" href="#vfs-remove"><span className="msb-rn">vfs.Remove()</span><span className="msb-rg">delete file or empty dir</span></a> <a className="msb-row" href="#vfs-removeall"><span className="msb-rn">vfs.RemoveAll()</span><span className="msb-rg">recursive delete</span></a> <a className="msb-row" href="#vfs-exists"><span className="msb-rn">vfs.Exists()</span><span className="msb-rg">check for existence</span></a> <p className="msb-gl"><span className="msb-dot builder"></span>Options<span className="msb-ct">9</span></p> <div className="msb-chiprow"> <a className="msb-chip" href="#withvolumekind">WithVolumeKind()</a> <a className="msb-chip" href="#withvolumesize">WithVolumeSize()</a> <a className="msb-chip" href="#withvolumequota">WithVolumeQuota()</a> <a className="msb-chip" href="#withvolumelabels">WithVolumeLabels()</a> <a className="msb-chip" href="#mount-bind">Mount.Bind()</a> <a className="msb-chip" href="#mount-named">Mount.Named()</a> <a className="msb-chip" href="#mount-namedwith">Mount.NamedWith()</a> <a className="msb-chip" href="#mount-tmpfs">Mount.Tmpfs()</a> <a className="msb-chip" href="#mount-disk">Mount.Disk()</a> </div> <p className="msb-gl"><span className="msb-dot type"></span>Types</p> <div className="msb-chiprow"> <a className="msb-typepill" href="#volume">Volume</a> <a className="msb-typepill" href="#volumehandle">VolumeHandle</a> <a className="msb-typepill" href="#volumefs">VolumeFs</a> <a className="msb-typepill" href="#errpathescape">ErrPathEscape</a> <a className="msb-typepill" href="#volumeconfig">VolumeConfig</a> <a className="msb-typepill" href="#volumeoption">VolumeOption</a> <a className="msb-typepill" href="#volumekind">VolumeKind</a> <a className="msb-typepill" href="#mountconfig">MountConfig</a> <a className="msb-typepill" href="#mountkind">MountKind</a> <a className="msb-typepill" href="#mountoptions">MountOptions</a> <a className="msb-typepill" href="#namedvolumeoptions">NamedVolumeOptions</a> <a className="msb-typepill" href="#tmpfsoptions">TmpfsOptions</a> <a className="msb-typepill" href="#diskoptions">DiskOptions</a> </div> </div> <p className="msb-label" id="typical-flow">Typical flow</p>import m "github.com/superradcompany/microsandbox/sdk/go"
vol, err := m.CreateVolume(ctx, "my-data", // 1. create a named volume
m.WithVolumeQuota(64),
m.WithVolumeLabels(map[string]string{"env": "prod"}),
)
vfs := vol.FS() // 2. seed it from the host
err = vfs.WriteString("seed.txt", "hello")
sb, err := m.CreateSandbox(ctx, "worker", // 3. attach it to a sandbox
m.WithImage("alpine"),
m.WithMounts(map[string]m.MountConfig{
"/data": m.Mount.Named("my-data", m.MountOptions{}),
}),
)
Named volumes are managed by microsandbox and stored by default under ~/.microsandbox/volumes/<name>/. They persist independently of any sandbox. There is no Rust-side resource to release: Remove deletes the on-disk state and the DB record.
func CreateVolume(ctx context.Context, name string, opts ...VolumeOption) (*Volume, error)
Create a named volume and return a populated *Volume with its name and host path. Configure the kind, quota, disk size, and labels with option functions. Returns ErrVolumeAlreadyExists if a volume with the given name already exists.
vol, err := m.CreateVolume(ctx, "docker-data",
m.WithVolumeKind(m.VolumeKindDisk),
m.WithVolumeSize(20*1024),
)
func GetVolume(ctx context.Context, name string) (*VolumeHandle, error)
Look up a volume by name and return its metadata. Returns ErrVolumeNotFound if no such volume exists.
h, err := m.GetVolume(ctx, "my-data")
fmt.Println(h.Path(), h.UsedBytes())
func ListVolumes(ctx context.Context) ([]*VolumeHandle, error)
Return metadata for every named volume on the host.
<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="#volumehandle">[]*VolumeHandle</a></div> <div className="msb-param-desc">All volume metadata handles.</div> </div> </div> <Accordion title="Example">vols, err := m.ListVolumes(ctx)
for _, h := range vols {
fmt.Printf("%s — %s\n", h.Name(), h.Kind())
}
func RemoveVolume(ctx context.Context, name string) error
Delete a volume by name. All sandboxes referencing the volume must be stopped 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 removal.</div> </div> <div className="msb-param"> <div className="msb-param-key"><code>name</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Volume name.</div> </div> </div> <Accordion title="Example">err := m.RemoveVolume(ctx, "my-data")
A Volume is returned by CreateVolume and carries the volume's name and host path.
func (v *Volume) Name() string
Return the volume's name.
func (v *Volume) Path() string
Return the host filesystem path of the volume's data directory.
func (v *Volume) FS() *VolumeFs
Return a *VolumeFs for direct host-side file operations on this volume.
vfs := vol.FS()
err := vfs.WriteString("seed.txt", "hello")
func (v *Volume) Remove(ctx context.Context) error
Delete this volume. All sandboxes using it must be stopped. Equivalent to RemoveVolume(ctx, v.Name()).
err := vol.Remove(ctx)
A VolumeHandle is the metadata reference returned by GetVolume and ListVolumes.
func (h *VolumeHandle) Name() string
Return the volume name.
func (h *VolumeHandle) Path() string
Return the host filesystem path of the volume's data directory.
func (h *VolumeHandle) Kind() VolumeKind
Return the volume storage kind: VolumeKindDir or VolumeKindDisk.
func (h *VolumeHandle) QuotaMiB() *uint32
Return the quota in MiB, or nil if unlimited.
func (h *VolumeHandle) UsedBytes() uint64
Return the amount of space used by the volume, in bytes.
func (h *VolumeHandle) CapacityBytes() *uint64
Return the disk capacity in bytes for disk volumes, or nil for directory volumes.
func (h *VolumeHandle) DiskFormat() *string
Return the disk image format for disk volumes, or nil for directory volumes.
func (h *VolumeHandle) DiskFstype() *string
Return the inner filesystem type for disk volumes, or nil for directory volumes.
func (h *VolumeHandle) Labels() map[string]string
Return the labels attached to this volume.
func (h *VolumeHandle) CreatedAt() time.Time
Return the creation timestamp, or the zero time.Time value if unknown.
func (h *VolumeHandle) FS() *VolumeFs
Return a *VolumeFs for direct host-side file operations on this volume.
func (h *VolumeHandle) Remove(ctx context.Context) error
Delete this volume. All sandboxes using it must be stopped. Equivalent to RemoveVolume(ctx, h.Name()).
Host-side filesystem operations on a named volume's data directory. Obtain via Volume.FS() or VolumeHandle.FS(). These operations run directly on the host filesystem: no running sandbox is required and no agent protocol is involved.
All path arguments are relative to the volume root. Paths that would escape the root via .., absolute components, or stray symlink chains are rejected with ErrPathEscape.
vfs := vol.FS()
if err := vfs.WriteString("seed.txt", "hello"); err != nil {
return err
}
content, err := vfs.ReadString("seed.txt")
func (fs *VolumeFs) Root() string
Return the absolute host path of the volume's data directory.
func (fs *VolumeFs) Read(relPath string) ([]byte, error)
Read the contents of a file relative to the volume root.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>relPath</code><span className="msb-type">string</span></div> <div className="msb-param-desc">Path relative to the volume root.</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">[]byte</span></div> <div className="msb-param-desc">File contents.</div> </div> </div>func (fs *VolumeFs) ReadString(relPath string) (string, error)
Read a file and return its contents as a UTF-8 string.
func (fs *VolumeFs) Write(relPath string, data []byte) error
Write data to a file, creating or truncating it. Created files use mode 0o644.
func (fs *VolumeFs) WriteString(relPath, content string) error
Write a string to a file. Created files use mode 0o644.
func (fs *VolumeFs) Mkdir(relPath string) error
Create a directory and all missing parents (mode 0o755).
func (fs *VolumeFs) Remove(relPath string) error
Delete a single file or empty directory.
func (fs *VolumeFs) RemoveAll(relPath string) error
Delete a path and any children it contains (recursive).
func (fs *VolumeFs) Exists(relPath string) (bool, error)
Report whether a file or directory exists at the given path.
<p className="msb-label">Returns</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><span className="msb-type">bool</span></div> <div className="msb-param-desc"><code>true</code> if a file or directory exists at the path.</div> </div> </div>Functional options passed to CreateVolume, plus the Mount factory helpers that attach a volume, bind mount, tmpfs, or disk image to a sandbox via WithMounts.
func WithVolumeKind(kind VolumeKind) VolumeOption
Select the volume kind. Valid values are VolumeKindDir (default) and VolumeKindDisk.
func WithVolumeSize(mebibytes uint32) VolumeOption
Set disk volume capacity in MiB. Required when the kind is VolumeKindDisk.
func WithVolumeQuota(mebibytes uint32) VolumeOption
Set the recorded quota in MiB for directory volumes. Zero means unlimited.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>mebibytes</code><span className="msb-type">uint32</span></div> <div className="msb-param-desc">Quota in MiB; zero means unlimited.</div> </div> </div>func WithVolumeLabels(labels map[string]string) VolumeOption
Attach key-value labels to the volume. When called repeatedly, the maps merge; later keys overwrite earlier ones.
<p className="msb-label">Parameters</p> <div className="msb-params"> <div className="msb-param"> <div className="msb-param-key"><code>labels</code><span className="msb-type">map[string]string</span></div> <div className="msb-param-desc">Metadata labels to attach.</div> </div> </div>func (mountFactory) Bind(hostPath string, opts MountOptions) MountConfig
Bind-mount a host directory into the sandbox. Changes in the guest are reflected on the host and vice versa. Returns a MountConfig for use with WithMounts.
"/host": m.Mount.Bind("/var/data", m.MountOptions{Readonly: true})
func (mountFactory) Named(name string, opts MountOptions) MountConfig
Mount an existing named persistent volume. The volume must already exist (create it with CreateVolume). Returns a MountConfig.
"/data": m.Mount.Named("my-data", m.MountOptions{})
func (mountFactory) NamedWith(name string, opts MountOptions, namedOpts NamedVolumeOptions) MountConfig
Mount a named persistent volume with explicit sandbox-time existence behavior. NamedVolumeOptions.Mode accepts "existing" (default), "create", or "ensure-exists". Mode: "create" fails when the named volume already exists. Mode: "ensure-exists" creates the volume if it is missing and reuses a compatible existing volume; it errors when the existing volume has a different kind, quota, or capacity than requested, and never mutates existing volume metadata.
sb, err := m.CreateSandbox(ctx, "worker",
m.WithImage("python"),
m.WithMounts(map[string]m.MountConfig{
"/cache": m.Mount.NamedWith("pip-cache", m.MountOptions{}, m.NamedVolumeOptions{
Mode: "ensure-exists",
}),
"/var/lib/docker": m.Mount.NamedWith("docker-data", m.MountOptions{}, m.NamedVolumeOptions{
Mode: "ensure-exists",
Kind: "disk",
SizeMiB: 20 * 1024,
}),
}),
)
func (mountFactory) Tmpfs(opts TmpfsOptions) MountConfig
Mount an ephemeral in-memory filesystem. Contents are discarded when the sandbox stops. Returns a MountConfig.
"/scratch": m.Mount.Tmpfs(m.TmpfsOptions{SizeMiB: 128})
func (mountFactory) Disk(hostPath string, opts DiskOptions) MountConfig
Mount a host disk image as a virtio-blk device. Supports raw, qcow2, and vmdk formats. Returns a MountConfig.
"/img": m.Mount.Disk("./data.qcow2", m.DiskOptions{
Format: "qcow2",
Fstype: "ext4",
Readonly: true,
})
A named persistent volume carrying its host-side path. Returned by CreateVolume. Lookups via GetVolume and ListVolumes yield richer VolumeHandle values instead.
| Method | Returns | Description |
|---|---|---|
Name() | string | Volume name |
Path() | string | Host filesystem path of the data directory |
FS() | *VolumeFs | Host-side filesystem accessor |
Remove(ctx) | error | Delete this volume (all sandboxes using it must be stopped) |
Metadata reference for a named volume. Obtain via GetVolume or ListVolumes.
| Method | Returns | Description |
|---|---|---|
Name() | string | Volume name |
Path() | string | Host filesystem path of the data directory |
Kind() | VolumeKind | Volume kind: VolumeKindDir or VolumeKindDisk |
QuotaMiB() | *uint32 | Quota in MiB, or nil if unlimited |
UsedBytes() | uint64 | Current disk usage in bytes |
CapacityBytes() | *uint64 | Disk capacity in bytes, or nil |
DiskFormat() | *string | Disk image format, or nil |
DiskFstype() | *string | Disk filesystem type, or nil |
Labels() | map[string]string | Metadata labels |
CreatedAt() | time.Time | Creation timestamp, zero value if unknown |
FS() | *VolumeFs | Host-side filesystem accessor |
Remove(ctx) | error | Delete this volume |
Host-side filesystem operations on a volume's data directory. Obtain via Volume.FS() or VolumeHandle.FS(). All path arguments are relative to the volume root; escaping paths are rejected with ErrPathEscape.
| Method | Returns | Description |
|---|---|---|
Root() | string | Absolute host path of the data directory |
Read(relPath) | ([]byte, error) | Read file bytes |
ReadString(relPath) | (string, error) | Read file as a UTF-8 string |
Write(relPath, data) | error | Write bytes, creating or truncating |
WriteString(relPath, content) | error | Write a string |
Mkdir(relPath) | error | Create a directory tree |
Remove(relPath) | error | Delete a file or empty directory |
RemoveAll(relPath) | error | Recursive delete |
Exists(relPath) | (bool, error) | Check for existence |
var ErrPathEscape = errors.New("microsandbox: path escapes volume root")
Returned by every VolumeFs method when relPath is absolute, contains a .. sequence that resolves outside the volume root, or otherwise escapes the volume's directory after filepath.Clean.
if _, err := vfs.Read("../etc/passwd"); errors.Is(err, m.ErrPathEscape) {
log.Println("nice try")
}
The config struct populated by VolumeOption functions. Most callers go through CreateVolume(ctx, name, opts...); VolumeConfig is exported for callers that prefer to construct one directly.
| Field | Type | Description |
|---|---|---|
QuotaMiB | uint32 | Maximum storage size in MiB (zero = unlimited) |
Kind | VolumeKind | Volume kind (VolumeKindDir by default) |
SizeMiB | uint32 | Disk capacity in MiB for VolumeKindDisk |
Labels | map[string]string | Metadata labels |
type VolumeOption func(*VolumeConfig)
A functional option for CreateVolume. Constructed by the WithVolume* helpers.
type VolumeKind string
Describes the storage backing for a named volume.
<p className="msb-backref">Used by <a href="#volumeconfig">VolumeConfig</a> · <a href="#withvolumekind">WithVolumeKind()</a> · <a href="#h-kind">VolumeHandle.Kind()</a></p>| Constant | Value | Description |
|---|---|---|
VolumeKindDir | "dir" | Directory-backed named volume |
VolumeKindDisk | "disk" | Raw ext4 disk-backed named volume |
Discriminated mount configuration produced by the Mount factory helpers and passed to WithMounts. Construct it with the factory rather than by hand: the factory sets the internal kind discriminator and enforces the mutually-exclusive flavours. Inspect the flavour via Kind().
| Field | Type | Description |
|---|---|---|
Bind | string | Host path for bind mounts |
Named | string | Volume name for named mounts |
NamedMode | string | Provisioning mode for named mounts ("existing", "create", "ensure-exists") |
NamedKind | string | Kind for provisioned named mounts ("dir" or "disk") |
QuotaMiB | uint32 | Quota in MiB for provisioned directory volumes |
Tmpfs | bool | Set for tmpfs mounts |
Disk | string | Host path for disk images |
Format | string | Disk format |
Fstype | string | Inner filesystem type |
Readonly | bool | Whether the mount is read-only |
Noexec | bool | Whether direct execution from the mount is disabled |
Nosuid | bool | Whether setuid/setgid elevation from files on the mount is ignored |
Nodev | bool | Whether device files on the mount are ignored |
SizeMiB | uint32 | Size limit for tmpfs / capacity for provisioned disk volumes |
StatVirtualization | StatVirtualization | Per-mount stat-virtualization policy (bind / named only) |
HostPermissions | HostPermissions | Per-mount host-permission propagation policy (bind / named only) |
| Method | Returns | Description |
|---|---|---|
Kind() | MountKind | Which mount flavour this is |
type MountKind uint8
Discriminates between the four mount flavours. Inspect via mount.Kind().
| Constant | Description |
|---|---|
MountKindBind | Host bind mount |
MountKindNamed | Named persistent volume |
MountKindTmpfs | In-memory tmpfs |
MountKindDisk | Host disk image |
Tuning struct for Mount.Bind, Mount.Named, and Mount.NamedWith. StatVirtualization and HostPermissions are virtiofs-only and rejected at build time if combined with a tmpfs or disk-image mount; their zero values preserve the conservative defaults (strict, private).
| Field | Type | Description |
|---|---|---|
Readonly | bool | Mount as read-only; virtiofs-backed mounts also reject writes in the host filesystem server |
Noexec | bool | Prevent direct execution from the mount |
Nosuid | bool | Ignore setuid and setgid privilege elevation from files on the mount |
Nodev | bool | Ignore device files on the mount |
StatVirtualization | StatVirtualization | Per-mount stat-virtualization policy (virtiofs only) |
HostPermissions | HostPermissions | Per-mount host-permission propagation policy (virtiofs only) |
Tunes sandbox-time named volume provisioning for Mount.NamedWith.
| Field | Type | Description |
|---|---|---|
Mode | string | "existing", "create", or "ensure-exists"; empty means "existing" |
Kind | string | "dir" or "disk"; empty means "dir" |
SizeMiB | uint32 | Disk capacity in MiB; required when creating or ensuring a missing disk volume |
QuotaMiB | uint32 | Directory volume quota in MiB |
Tuning struct for Mount.Tmpfs.
| Field | Type | Description |
|---|---|---|
SizeMiB | uint32 | Maximum size in MiB |
Readonly | bool | Mount as read-only |
Noexec | bool | Prevent direct execution from the mount |
Nosuid | bool | Ignore setuid and setgid privilege elevation from files on the mount |
Nodev | bool | Ignore device files on the mount |
Tuning struct for Mount.Disk.
| Field | Type | Description |
|---|---|---|
Format | string | Format hint ("raw", "qcow2", "vmdk"). Optional; the runtime can usually probe |
Fstype | string | Inner filesystem type (e.g. "ext4", "xfs"). Optional; omitted means auto-detect |
Readonly | bool | Mount as read-only |
Noexec | bool | Prevent direct execution from the mount |
Nosuid | bool | Ignore setuid and setgid privilege elevation from files on the mount |
Nodev | bool | Ignore device files on the mount |