gzfs

package module
v0.0.0-...-c800c9d Latest Latest
Warning

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

Go to latest
Published: Jul 3, 2026 License: BSD-2-Clause Imports: 13 Imported by: 0

README

gzfs

A Go library for interacting with ZFS (Zettabyte File System) on FreeBSD and other ZFS-compatible systems. This library provides a clean, idiomatic Go interface for ZFS, ZPool, and ZDB operations.

ZFS Version Go Version License

Features

  • Core ZFS Operations: Create, list, get, snapshot, clone, destroy datasets and volumes
  • ZPool Management: Create, destroy, scrub pools, manage spares and cache devices
  • ZDB Integration: Low-level pool inspection with caching support
  • Type Safety: Strongly typed structs for all ZFS objects and properties
  • Mock Testing: Comprehensive test suite with mock runner for development
  • Flexible Command Execution: Support for sudo, custom binaries, and command runners
  • JSON Parsing: Native parsing of ZFS JSON output for reliability

Installation

go get github.com/alchemillahq/gzfs@latest

Requirements

  • OpenZFS >= 2.3.0
  • zfs, zpool, and zdb available in PATH
  • Root privileges or sudo for most write operations

Quick Start

package main

import (
    "context"
    "fmt"
    "log"

    "github.com/alchemillahq/gzfs"
)

func main() {
    ctx := context.Background()
    
    // Create a client (set Sudo: true if ZFS commands require privileges)
    client := gzfs.NewClient(gzfs.Options{
        Sudo: false,
    })

    // List all datasets
    datasets, err := client.ZFS.List(ctx, false)
    if err != nil {
        log.Fatalf("Failed to list datasets: %v", err)
    }

    for _, ds := range datasets {
        fmt.Printf("Dataset: %s, Type: %s, Used: %d bytes\n", 
            ds.Name, ds.Type, ds.Used)
    }

    // List all pools
    pools, err := client.Zpool.List(ctx)
    if err != nil {
        log.Fatalf("Failed to list pools: %v", err)
    }

    for _, pool := range pools {
        fmt.Printf("Pool: %s, State: %s, Size: %d bytes\n", 
            pool.Name, pool.State, pool.Size)
    }
}

License

This project is licensed under the BSD-2-Clause License - see the LICENSE file for details.

Acknowledgments

  • The ZFS development team for creating an amazing filesystem
  • The OpenZFS project for cross-platform ZFS support
  • The FreeBSD project for excellent ZFS integration

Support


Note: This library executes ZFS commands directly and requires appropriate permissions. Always test in a safe environment before using in production.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenerateDeterministicUUID

func GenerateDeterministicUUID(seed string) string

func ParseFloat64

func ParseFloat64(value string) float64

func ParsePercentage

func ParsePercentage(value string) float64

func ParseRatio

func ParseRatio(value string) float64

func ParseSize

func ParseSize(value string) uint64

func ParseString

func ParseString(value string) string

func ParseUint64

func ParseUint64(value string) uint64

Types

type Client

type Client struct {
	ZFS   *zfs
	Zpool *zpool
	ZDB   *zdb
}

func NewClient

func NewClient(opts Options) *Client

type Cmd

type Cmd struct {
	Bin    string
	Sudo   bool
	Runner Runner
}

func (Cmd) RunBytes

func (c Cmd) RunBytes(ctx context.Context, stdin io.Reader, args ...string) ([]byte, []byte, error)

func (Cmd) RunJSON

func (c Cmd) RunJSON(ctx context.Context, v any, args ...string) error

func (Cmd) RunStream

func (c Cmd) RunStream(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer, args ...string) error

type CmdError

type CmdError struct {
	Cmd      string
	Args     []string
	ExitErr  error
	Stderr   string
	Combined string
}

func (*CmdError) Error

func (e *CmdError) Error() string

func (*CmdError) Unwrap

func (e *CmdError) Unwrap() error

type Dataset

type Dataset struct {
	Name      string      `json:"name"`
	GUID      string      `json:"guid"`
	Type      DatasetType `json:"type"`
	Pool      string      `json:"pool"`
	CreateTXG string      `json:"createtxg"`

	Mountpoint    string  `json:"mountpoint"`
	Used          uint64  `json:"used"`
	Available     uint64  `json:"available"`
	Referenced    uint64  `json:"referenced"`
	Compressratio float64 `json:"compressratio"`

	Properties map[string]ZFSProperty `json:"properties"`
	// contains filtered or unexported fields
}

func (*Dataset) Clone

func (d *Dataset) Clone(ctx context.Context, dest string, properties map[string]string) (*Dataset, error)

func (*Dataset) Destroy

func (d *Dataset) Destroy(ctx context.Context, recursive bool, deferDeletion bool) error

func (*Dataset) GetEncryptionProperties

func (d *Dataset) GetEncryptionProperties(ctx context.Context) (*EncryptionProperties, error)

func (*Dataset) GetProperty

func (d *Dataset) GetProperty(ctx context.Context, name string) (ZFSProperty, error)

func (*Dataset) IsEncrypted

func (d *Dataset) IsEncrypted() bool

func (*Dataset) LoadKey

func (d *Dataset) LoadKey(ctx context.Context, recursive bool) error

func (*Dataset) LoadKeyWithPassphrase

func (d *Dataset) LoadKeyWithPassphrase(ctx context.Context, passphrase string, recursive bool) error

func (*Dataset) Mount

func (d *Dataset) Mount(ctx context.Context, overlay bool, options ...string) error

func (*Dataset) MountWithKey

func (d *Dataset) MountWithKey(ctx context.Context, overlay bool, options ...string) error

func (*Dataset) Rename

func (d *Dataset) Rename(ctx context.Context, newName string, recursive bool) (*Dataset, error)

func (*Dataset) Rollback

func (d *Dataset) Rollback(ctx context.Context, destroyMoreRecent bool) error

func (*Dataset) SendIncremental

func (d *Dataset) SendIncremental(ctx context.Context, baseSnapshot string, out io.Writer) error

func (*Dataset) SendIncrementalWithIntermediates

func (d *Dataset) SendIncrementalWithIntermediates(ctx context.Context, baseSnapshot string, out io.Writer) error

func (*Dataset) SendSnapshot

func (d *Dataset) SendSnapshot(ctx context.Context, out io.Writer) error

func (*Dataset) SendToDataset

func (d *Dataset) SendToDataset(ctx context.Context, dest string, force bool) (*Dataset, error)

func (*Dataset) SetProperties

func (d *Dataset) SetProperties(ctx context.Context, kvPairs ...string) error

func (*Dataset) Snapshot

func (d *Dataset) Snapshot(ctx context.Context, name string, recursive bool) (*Dataset, error)

func (*Dataset) Snapshots

func (d *Dataset) Snapshots() ([]*Dataset, error)

func (*Dataset) UnloadKey

func (d *Dataset) UnloadKey(ctx context.Context, recursive bool) error

func (*Dataset) Unmount

func (d *Dataset) Unmount(ctx context.Context, force bool) error

type DatasetList

type DatasetList struct {
	OutputVersion OutputVersion       `json:"output_version"`
	Datasets      map[string]*Dataset `json:"datasets"`
}

type DatasetType

type DatasetType string
const (
	DatasetTypeAll        DatasetType = "ALL"
	DatasetTypeFilesystem DatasetType = "FILESYSTEM"
	DatasetTypeVolume     DatasetType = "VOLUME"
	DatasetTypeSnapshot   DatasetType = "SNAPSHOT"
)

type EncryptionProperties

type EncryptionProperties struct {
	Encryption     string `json:"encryption"`
	KeyLocation    string `json:"keylocation"`
	KeyFormat      string `json:"keyformat"`
	KeyStatus      string `json:"keystatus"`
	EncryptionRoot string `json:"encryptionroot"`
}

type LocalRunner

type LocalRunner struct{}

func (LocalRunner) Run

func (LocalRunner) Run(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer, name string, args ...string) error

type Options

type Options struct {
	Sudo     bool
	Runner   Runner
	ZFSBin   string
	ZpoolBin string
	ZDBBin   string

	ZDBCacheTTLSeconds int32
}

type OutputVersion

type OutputVersion struct {
	Command   string `json:"command"`
	VersMajor int    `json:"vers_major"`
	VersMinor int    `json:"vers_minor"`
}

type Runner

type Runner interface {
	Run(ctx context.Context, stdin io.Reader, stdout, stderr io.Writer, name string, args ...string) error
}

type ZDBPool

type ZDBPool struct {
	Name     string         `json:"name"`
	GUID     string         `json:"guid"`
	Version  string         `json:"version"`
	Children []ZDBPoolChild `json:"children,omitempty"`
}

type ZDBPoolChild

type ZDBPoolChild struct {
	Type          string            `json:"type,omitempty"`
	ID            int               `json:"id,omitempty"`
	GUID          uint64            `json:"guid,omitempty"`
	Path          string            `json:"path,omitempty"`
	WholeDisk     int               `json:"whole_disk,omitempty"`
	MetaslabArray int               `json:"metaslab_array,omitempty"`
	MetaslabShift int               `json:"metaslab_shift,omitempty"`
	Ashift        int               `json:"ashift,omitempty"`
	Asize         uint64            `json:"asize,omitempty"`
	IsLog         int               `json:"is_log,omitempty"`
	CreateTXG     uint64            `json:"create_txg,omitempty"`
	Properties    map[string]string `json:"properties,omitempty"`
	Children      []ZDBPoolChild    `json:"children,omitempty"`
}

type ZFSProperty

type ZFSProperty struct {
	Value  string            `json:"value"`
	Source ZFSPropertySource `json:"source"`
}

type ZFSPropertySource

type ZFSPropertySource struct {
	Type string `json:"type"`
	Data string `json:"data"`
}

type ZPool

type ZPool struct {
	Name       string     `json:"name"`
	Type       string     `json:"type"`
	State      ZPoolState `json:"state"`
	PoolGUID   string     `json:"pool_guid"`
	TXG        string     `json:"txg"`
	SPAVersion string     `json:"spa_version"`
	ZPLVersion string     `json:"zpl_version"`

	Size          uint64  `json:"size"`
	Free          uint64  `json:"free"`
	Alloc         uint64  `json:"allocated"`
	Fragmentation float64 `json:"fragmentation"`
	DedupRatio    float64 `json:"dedup_ratio"`

	Properties map[string]ZFSProperty `json:"properties"`

	Vdevs   map[string]*ZPoolVDEV `json:"-"`
	Logs    map[string]*ZPoolVDEV `json:"logs"`
	L2Cache map[string]*ZPoolVDEV `json:"l2cache"`
	Spares  map[string]*ZPoolVDEV `json:"spares"`
	Special map[string]*ZPoolVDEV `json:"special"`
	Dedup   map[string]*ZPoolVDEV `json:"dedup"`
	// contains filtered or unexported fields
}

func (*ZPool) AddSpare

func (p *ZPool) AddSpare(ctx context.Context, device string, force bool) error

func (*ZPool) Datasets

func (p *ZPool) Datasets(ctx context.Context, t DatasetType) ([]*Dataset, error)

func (*ZPool) Destroy

func (p *ZPool) Destroy(ctx context.Context) error

func (*ZPool) Detach

func (p *ZPool) Detach(ctx context.Context, device string) error

func (*ZPool) GetProperties

func (p *ZPool) GetProperties(ctx context.Context) (map[string]ZFSProperty, error)

func (*ZPool) GetProperty

func (p *ZPool) GetProperty(name string) (ZFSProperty, error)

func (*ZPool) MarshalJSON

func (p *ZPool) MarshalJSON() ([]byte, error)

func (*ZPool) RemoveSpare

func (p *ZPool) RemoveSpare(ctx context.Context, device string) error

func (*ZPool) ReplaceDevice

func (p *ZPool) ReplaceDevice(ctx context.Context, oldDevice, newDevice string, force bool) error

func (*ZPool) RequiredSpareSize

func (p *ZPool) RequiredSpareSize(ctx context.Context) (uint64, error)

func (*ZPool) Scrub

func (p *ZPool) Scrub(ctx context.Context) error

func (*ZPool) SetProperty

func (p *ZPool) SetProperty(ctx context.Context, property, value string) error

func (*ZPool) Status

func (p *ZPool) Status(ctx context.Context) (*ZPoolStatusPool, error)

func (*ZPool) UnmarshalJSON

func (p *ZPool) UnmarshalJSON(data []byte) error

func (*ZPool) ZDB

func (z *ZPool) ZDB(ctx context.Context) (*ZDBPool, error)

type ZPoolList

type ZPoolList struct {
	OutputVersion OutputVersion     `json:"output_version"`
	Pools         map[string]*ZPool `json:"pools"`
}

type ZPoolState

type ZPoolState string
const (
	ZPoolStateOnline      ZPoolState = "ONLINE"
	ZPoolStateDegraded    ZPoolState = "DEGRADED"
	ZPoolStateFaulted     ZPoolState = "FAULTED"
	ZPoolStateOffline     ZPoolState = "OFFLINE"
	ZPoolStateRemoved     ZPoolState = "REMOVED"
	ZPoolStateUnavailible ZPoolState = "UNAVAIL"
	ZPoolStateCorruptData ZPoolState = "CORRUPT_DATA"
	ZPoolStateUnknown     ZPoolState = "UNKNOWN"
)

type ZPoolStatus

type ZPoolStatus struct {
	OutputVersion OutputVersion               `json:"output_version"`
	Pools         map[string]*ZPoolStatusPool `json:"pools"`
}

type ZPoolStatusPool

type ZPoolStatusPool struct {
	Name       string `json:"name"`
	State      string `json:"state"`
	PoolGUID   string `json:"pool_guid"`
	TXG        string `json:"txg"`
	SPAVersion string `json:"spa_version"`
	ZPLVersion string `json:"zpl_version"`
	Status     string `json:"status"`
	Action     string `json:"action"`

	ScanStats *ZPoolStatusScanStats       `json:"scan_stats"`
	Vdevs     map[string]*ZPoolStatusVDEV `json:"vdevs"`
	Logs      map[string]*ZPoolStatusVDEV `json:"logs"`
	Spares    map[string]*ZPoolStatusVDEV `json:"spares"`
	L2Cache   map[string]*ZPoolStatusVDEV `json:"l2cache"`
	Special   map[string]*ZPoolStatusVDEV `json:"special"`
	Dedup     map[string]*ZPoolStatusVDEV `json:"dedup"`
}

type ZPoolStatusScanStats

type ZPoolStatusScanStats struct {
	Function           string `json:"function"`
	State              string `json:"state"`
	StartTime          string `json:"start_time"`
	EndTime            string `json:"end_time"`
	ToExamine          string `json:"to_examine"`
	Examined           string `json:"examined"`
	Skipped            string `json:"skipped"`
	Processed          string `json:"processed"`
	Errors             string `json:"errors"`
	BytesPerScan       string `json:"bytes_per_scan"`
	PassStart          string `json:"pass_start"`
	ScrubPause         string `json:"scrub_pause"`
	ScrubSpentPaused   string `json:"scrub_spent_paused"`
	IssuedBytesPerScan string `json:"issued_bytes_per_scan"`
	Issued             string `json:"issued"`
}

type ZPoolStatusVDEV

type ZPoolStatusVDEV struct {
	Name        string `json:"name"`
	VdevType    string `json:"vdev_type"`
	GUID        string `json:"guid"`
	Path        string `json:"path"`
	Class       string `json:"class"`
	State       string `json:"state"`
	AllocSpace  string `json:"alloc_space"`
	TotalSpace  string `json:"total_space"`
	DefSpace    string `json:"def_space"`
	RepDevSize  string `json:"rep_dev_size"`
	ReadErrors  string `json:"read_errors"`
	WriteErrors string `json:"write_errors"`
	ChkErrors   string `json:"checksum_errors"`

	Vdevs map[string]*ZPoolStatusVDEV `json:"vdevs"`
}

type ZPoolVDEV

type ZPoolVDEV struct {
	Name     string `json:"name"`
	VdevType string `json:"vdev_type"`
	GUID     string `json:"guid"`
	Path     string `json:"path"`
	PhysPath string `json:"phys_path"`
	Class    string `json:"class"`
	State    string `json:"state"`

	Size          uint64  `json:"size"`
	Free          uint64  `json:"free"`
	Alloc         uint64  `json:"allocated"`
	Fragmentation float64 `json:"fragmentation"`

	Properties map[string]ZFSProperty `json:"properties"`
	Vdevs      map[string]*ZPoolVDEV  `json:"vdevs"`
}

Directories

Path Synopsis
examples
zdb command
zfs command
zpool command

Jump to

Keyboard shortcuts

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