Skip to content

Storage Package Reference

pkg/storage/ — Volume Manager, Secret Manager, and DebugFS Injection.


The pkg/storage package provides storage abstractions for Firecracker VMs, including volume management (directory and block drivers), secret/config injection, and debugfs operations for ext4 rootfs modification.

Package Structure:

pkg/storage/
├── volume.go # VolumeManager (dispatcher)
├── volume_dir.go # DirectoryDriver (host directory volumes)
├── volume_block.go # BlockDriver (block device volumes)
├── volume_meta.go # MetaStore (volume metadata)
├── volume_quota.go # Quota management
├── credential_store.go # SecretManager (secrets/configs)
├── driver.go # VolumeDriver interface
└───────────────────────┴────────────────────────────────────────────────────

File: volume.go

The VolumeManager dispatches volume operations to appropriate drivers.

type VolumeManager struct {
drivers map[VolumeType]VolumeDriver
defaultType VolumeType
mu sync.RWMutex
}
type VolumeType string
const (
VolumeTypeDir VolumeType = "dir" // Host directory
VolumeTypeBlock VolumeType = "block" // Block device
)
type Volume struct {
ID string `json:"id"` // Sanitized name
Name string `json:"name"` // Original name
Path string `json:"path"` // Volume path
TaskID string `json:"task_id"` // Associated task
}
func NewVolumeManager(volumesDir string) (*VolumeManager, error)

Parameters:

  • volumesDir — Base directory for volumes (default: /var/lib/swarmcracker/volumes)

Example:

vm, err := storage.NewVolumeManager("/var/lib/swarmcracker/volumes")
if err != nil {
log.Fatal(err)
}

func (vm *VolumeManager) CreateVolume(ctx context.Context, name, taskID string, sizeMB int) (*Volume, error)

Purpose: Create volume with default type (dir).


func (vm *VolumeManager) CreateVolumeWithOptions(ctx context.Context, name, taskID string, opts CreateOptions) (*Volume, error)

Purpose: Create volume with full options.

type CreateOptions struct {
Type VolumeType
SizeMB int
Quota QuotaConfig
Labels map[string]string
}

Example:

vol, err := vm.CreateVolumeWithOptions(ctx, "data-vol", "task-123", storage.CreateOptions{
Type: storage.VolumeTypeDir,
SizeMB: 1024,
})

func (vm *VolumeManager) GetVolume(name string) (*Volume, error)

Purpose: Retrieve volume handle by name.


func (vm *VolumeManager) GetVolumeInfo(ctx context.Context, name string, volType VolumeType) (*VolumeInfo, error)

Purpose: Get detailed volume info.

type VolumeInfo struct {
Name string
Type VolumeType
SizeMB int
UsedMB int64
CreatedAt time.Time
LastUsedAt time.Time
TaskID string
}

func (vm *VolumeManager) MountVolume(ctx context.Context, vol *Volume, rootfsPath, target string) error

Purpose: Copy volume data into rootfs at target path.

Implementation (DirectoryDriver):

  1. Copy directory contents to rootfs subdirectory
  2. Preserve permissions and ownership

func (vm *VolumeManager) UnmountVolume(ctx context.Context, vol *Volume, rootfsPath, target string, readOnly bool) error

Purpose: Sync data back from rootfs to volume.


func (vm *VolumeManager) DeleteVolume(ctx context.Context, name string) error

Purpose: Remove volume and its data.


func (vm *VolumeManager) ListVolumes(ctx context.Context) ([]*Volume, error)

Purpose: List all volumes.


func (vm *VolumeManager) ListVolumeInfos(ctx context.Context) ([]*VolumeInfo, error)

Purpose: List detailed volume info.


func (vm *VolumeManager) SnapshotVolume(ctx context.Context, name string) (*Snapshot, error)

Purpose: Create point-in-time snapshot.


func (vm *VolumeManager) RestoreVolume(ctx context.Context, name string, snap *Snapshot) error

Purpose: Restore from snapshot.


File: volume_dir.go

Host directory-backed volumes.

type DirectoryDriver struct {
baseDir string
meta *MetaStore
quotaMgr *QuotaManager
}
func NewDirectoryDriver(baseDir string) (*DirectoryDriver, error)

func (d *DirectoryDriver) Create(ctx context.Context, name string, opts CreateOptions) (string, error)

Purpose: Create directory volume.

Implementation:

volPath := filepath.Join(d.baseDir, sanitizeVolumeName(name))
os.MkdirAll(volPath, 0755)
// Apply quota if specified
if opts.Quota.Enabled {
d.quotaMgr.SetQuota(volPath, opts.Quota.MaxBytes)
}

func (d *DirectoryDriver) Mount(ctx context.Context, name, rootfsPath, target string) error

Purpose: Copy volume contents into rootfs using debugfs.

Implementation:

// For each file in volume:
debugfs -w rootfsPath -R "write <src> <target>"

func (d *DirectoryDriver) Unmount(ctx context.Context, name, rootfsPath, target string, readOnly bool) error

Purpose: Copy rootfs data back to volume.


func (d *DirectoryDriver) Delete(ctx context.Context, name string) error

func (d *DirectoryDriver) Stat(ctx context.Context, name string) (*VolumeInfo, error)

File: volume_block.go

Block device-backed volumes for high-performance I/O.

type BlockDriver struct {
baseDir string
meta *MetaStore
}
func NewBlockDriver(baseDir string) (*BlockDriver, error)

func (b *BlockDriver) Create(ctx context.Context, name string, opts CreateOptions) (string, error)

Purpose: Create block device volume.

Implementation:

  1. Create qcow2 or raw image file
  2. Setup loop device
  3. Format with ext4

func (b *BlockDriver) Mount(ctx context.Context, name, rootfsPath, target string) error

Purpose: Mount block volume and copy to rootfs.


func (b *BlockDriver) Snapshot(ctx context.Context, name string) (*Snapshot, error)

Purpose: Create qcow2 snapshot.


File: volume_meta.go

JSON-based volume metadata storage.

type MetaStore struct {
metaDir string
mu sync.RWMutex
}
type VolumeMeta struct {
Name string `json:"name"`
Type VolumeType `json:"type"`
SizeMB int `json:"size_mb"`
CreatedAt time.Time `json:"created_at"`
LastUsedAt time.Time `json:"last_used_at"`
TaskID string `json:"task_id"`
Quota QuotaInfo `json:"quota"`
}
func (m *MetaStore) Save(ctx context.Context, meta *VolumeMeta) error
func (m *MetaStore) Load(ctx context.Context, name string) (*VolumeMeta, error)
func (m *MetaStore) List(ctx context.Context) ([]*VolumeMeta, error)
func (m *MetaStore) Delete(ctx context.Context, name string) error
func (m *MetaStore) UpdateTaskID(ctx context.Context, name, taskID string) error

File: volume_quota.go

type QuotaManager struct {
enabled bool
}
type QuotaConfig struct {
Enabled bool
MaxBytes int64
}
func (q *QuotaManager) SetQuota(path string, maxBytes int64) error
func (q *QuotaManager) GetUsage(path string) (int64, error)

Implementation (Linux):

Terminal window
# Set project quota
setquota -P <project-id> <soft> <hard> 0 0 <path>

File: credential_store.go

Manages secrets and configs injection into VM rootfs.

type SecretManager struct {
secretsDir string
configsDir string
}
func NewSecretManager(secretsDir, configsDir string) *SecretManager

func (sm *SecretManager) InjectSecret(ctx context.Context, rootfsPath, targetPath string, secretData []byte) error

Purpose: Inject secret file into rootfs.

Implementation:

// Use debugfs to write file
debugfs -w rootfsPath -R "write <temp-file> <target-path>"

func (sm *SecretManager) InjectConfig(ctx context.Context, rootfsPath, targetPath string, configData []byte) error

Purpose: Inject config file into rootfs.


func (sm *SecretManager) ListSecrets(ctx context.Context) ([]string, error)

func (sm *SecretManager) DeleteSecret(ctx context.Context, name string) error

File: volume.go

func IsVolumeReference(source string) bool

Purpose: Check if mount source is a volume reference.

Rules:

  • volume://name → Volume reference
  • name (no slashes) → Volume reference
  • /path/to/dir → Host path (not volume)

func ExtractVolumeName(source string) string

Purpose: Extract volume name from reference.

IsVolumeReference("volume://data") // true → "data"
IsVolumeReference("data") // true → "data"
IsVolumeReference("/var/data") // false → ""

type MockVolumeManager struct {
Volumes map[string]*Volume
}
func (m *MockVolumeManager) CreateVolume(ctx context.Context, name, taskID string, sizeMB int) (*Volume, error) {
vol := &Volume{
ID: name,
Name: name,
Path: "/mock/" + name,
}
m.Volumes[name] = vol
return vol, nil
}

Error Cause Resolution
"volume name cannot be empty" Empty name Provide valid name
"volume not found" Invalid name Check volume exists
"no driver registered for type" Unknown type Use dir or block
"block driver unavailable" Not root Run with privileges
"quota not supported" No quota support Enable project quotas

Topic Document
SwarmKit executor SwarmKit Reference
Image preparation Image Reference
Operations guide Operations Guide