utils

package
v0.4.1 Latest Latest
Warning

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

Go to latest
Published: May 20, 2026 License: MIT Imports: 27 Imported by: 0

Documentation

Index

Constants

View Source
const (
	HTTPTimeout = 30 * time.Second
	MaxRetries  = 3
	BaseBackoff = 100 * time.Millisecond
)
View Source
const StaleTempAge = time.Hour

StaleTempAge is the age threshold for removing stale temp files during GC.

Variables

This section is empty.

Functions

func AtomicWriteFile

func AtomicWriteFile(path string, data []byte, perm os.FileMode) error

AtomicWriteFile writes data to a file atomically using temp + fsync + rename. This prevents partial writes from being visible to readers.

func AtomicWriteJSON

func AtomicWriteJSON(path string, v any) error

AtomicWriteJSON marshals v to JSON and writes it atomically.

func CheckSocket

func CheckSocket(socketPath string) error

CheckSocket verifies that a Unix socket is connectable.

func CleanStaleRecords

func CleanStaleRecords[T any](
	items map[string]*T,
	nameMap map[string]string,
	targetIDs []string,
	nameOf func(*T) string,
	isStale func(*T) bool,
)

CleanStaleRecords removes targetIDs from items, re-checking isStale to dodge TOCTOU; nameOf=="" skips nameMap cleanup.

func DetectHugePages

func DetectHugePages() bool

DetectHugePages returns true iff /proc/sys/vm/nr_hugepages > 0; false on any error (non-Linux, etc.).

func DirSize added in v0.4.1

func DirSize(dir string) (int64, error)

DirSize sums regular file sizes under dir (recursive). Missing dir → 0.

func DoAPI

func DoAPI(ctx context.Context, hc *http.Client, method, url string, body []byte, expectedStatus int) ([]byte, error)

DoAPI sends a request, validates status, returns body (nil for 204). url must be fully-formed.

func DoAPIOnce added in v0.3.9

func DoAPIOnce(ctx context.Context, hc *http.Client, method, url string, body []byte, successCodes ...int) ([]byte, error)

DoAPIOnce sends a single non-retried request; use for non-idempotent endpoints where retry would surface as duplicate/conflict (e.g. vm.add-fs, snapshot/create).

func DoAPIWithRetry added in v0.3.9

func DoAPIWithRetry(ctx context.Context, hc *http.Client, method, url string, body []byte, successCodes ...int) ([]byte, error)

DoAPIWithRetry wraps DoAPI in DoWithRetry; successCodes[0] is primary, codes[1:] are also accepted (silent nil-body).

func DoWithRetry

func DoWithRetry[T any](ctx context.Context, fn func() (T, error)) (T, error)

DoWithRetry retries fn with exponential backoff for transient errors.

func EnsureDirs

func EnsureDirs(dirs ...string) error

EnsureDirs creates all directories with 0o750 permissions.

func ExtractTar

func ExtractTar(dir string, r io.Reader) error

ExtractTar extracts flat tar entries into dir.

func FileHead added in v0.4.0

func FileHead(f *os.File, n int) ([]byte, error)

FileHead returns up to n bytes from offset 0 without moving the read position. Truncated at EOF, no error if shorter than n.

func FilterUnreferenced

func FilterUnreferenced(candidates []string, refs map[string]struct{}, exclude ...map[string]struct{}) []string

FilterUnreferenced returns elements of candidates not present in refs or any of the optional exclude sets.

func FindVMMByCmdline added in v0.4.1

func FindVMMByCmdline(binaryName, expectArg string) ([]int, error)

FindVMMByCmdline is the one-shot equivalent of ScanProcsByBinary().Find(); batch callers should use ScanProcsByBinary directly to share one /proc walk.

func GenerateID

func GenerateID() string

GenerateID returns a random 26-character crypto-secure base32 ID.

func InitNamedIndex

func InitNamedIndex[T any](items *map[string]*T, names *map[string]string)

InitNamedIndex initializes nil maps in a named index (Items + Names pattern).

func IsProcessAlive

func IsProcessAlive(pid int) bool

IsProcessAlive uses kill(pid, 0) — true if the process exists; EPERM still counts (process exists, lacking signal permission).

func IsRetryable

func IsRetryable(err error) bool

IsRetryable returns true for transient errors (connection failures, 5xx, 429).

func LookupCopy

func LookupCopy[T any](m map[string]*T, key string) (T, error)

LookupCopy returns a shallow copy at key. Pointer/slice/map fields inside T still alias the original — callers must not mutate them without deep-copying.

func Map added in v0.2.5

func Map[T, R any](ctx context.Context, items []T, fn func(ctx context.Context, idx int, item T) (R, error), concurrency ...int) ([]R, error)

Map runs fn concurrently and returns results in input order; fail-fast via errgroup. concurrency[0] caps in-flight goroutines (0 = unlimited).

func MapValues added in v0.3.9

func MapValues[K comparable, V, R any](m map[K]*V, fn func(*V) R) []R

MapValues projects every non-nil value in m through fn into a slice.

func MergeSets

func MergeSets[K comparable](sets ...map[K]struct{}) map[K]struct{}

MergeSets unions any number of set maps into a new set.

func NewSocketHTTPClient

func NewSocketHTTPClient(socketPath string) *http.Client

NewSocketHTTPClient creates an HTTP client that dials a Unix socket.

func NewSocketHTTPClientWithTimeout added in v0.3.1

func NewSocketHTTPClientWithTimeout(socketPath string, timeout time.Duration) *http.Client

NewSocketHTTPClientWithTimeout overrides HTTPTimeout for long ops (e.g. snapshot/restore on multi-GiB VMs).

func PeekReader added in v0.3.9

func PeekReader(r io.Reader, n int) ([]byte, io.Reader, error)

PeekReader peeks up to n bytes + returns a reader that re-emits them then the rest; short read at EOF is not an error.

func ReadJSONFile added in v0.4.0

func ReadJSONFile(path string, v any) error

ReadJSONFile loads path and unmarshals it into v.

func ReadPIDFile

func ReadPIDFile(path string) (int, error)

ReadPIDFile reads a PID integer from path.

func ReflinkCopy

func ReflinkCopy(dst, src string) error

ReflinkCopy copies a single file, preferring FICLONE (O(1) CoW on btrfs/xfs/bcachefs) and falling back to SparseCopy on any error.

func RemoveMatching

func RemoveMatching(ctx context.Context, dir string, match func(os.DirEntry) bool) []error

RemoveMatching scans dir and removes entries where match returns true. Returns a slice of errors for entries that could not be removed.

func ResolveRef

func ResolveRef[T any](items map[string]*T, names map[string]string, ref string, notFound error) (string, error)

ResolveRef resolves a ref (exact ID, name, or ID prefix ≥3 chars) to a full ID. Works with any Index that has an Items map and a Names map.

func ResolveRefs

func ResolveRefs[T any](items map[string]*T, names map[string]string, refs []string, notFound error) ([]string, error)

ResolveRefs batch-resolves refs to exact IDs, deduplicating results.

func RunQemuImg added in v0.3.9

func RunQemuImg(ctx context.Context, args ...string) error

RunQemuImg shells out to qemu-img; non-zero exit returns wrapped combined output. Use exec.CommandContext directly when stdout matters.

func ScanFileStems

func ScanFileStems(dir, suffix string) ([]string, error)

ScanFileStems returns the name-without-suffix of every file in dir whose name ends with suffix.

func ScanSubdirs

func ScanSubdirs(dir string) ([]string, error)

ScanSubdirs returns the names of all immediate subdirectories of dir.

func SparseCopy

func SparseCopy(dst, src string) error

SparseCopy copies src to dst preserving sparsity via SEEK_HOLE/SEEK_DATA. dst is created as a new file (truncated to src size, then only data segments written).

func SyncParentDir

func SyncParentDir(dir string) error

SyncParentDir fsyncs the directory containing the file to ensure the directory entry is persisted.

func TarDir

func TarDir(tw *tar.Writer, dir string) error

TarDir writes regular files in dir into tw as flat tar entries.

func TarDirStream

func TarDirStream(dir string, cleanup func()) io.ReadCloser

TarDirStream streams a directory as a tar archive via a pipe.

func TarDirStreamWithRemove

func TarDirStreamWithRemove(dir string) io.ReadCloser

TarDirStreamWithRemove streams a directory as tar and removes it after close.

func TerminateProcess

func TerminateProcess(ctx context.Context, pid int, binaryName, expectArg string, gracePeriod time.Duration) error

TerminateProcess verifies pid matches binaryName+expectArg, sends SIGTERM, waits gracePeriod, escalates to SIGKILL.

func UUIDv5

func UUIDv5(name string) string

UUIDv5 generates a deterministic UUID v5 from the given name using the URL namespace. Compatible with the uuid_v5() bash function in os-image/start.sh.

func ValidFile

func ValidFile(path string) bool

ValidFile returns true if path is a regular file with size > 0.

func VerifyProcessCmdline

func VerifyProcessCmdline(pid int, binaryName, expectArg string) bool

VerifyProcessCmdline matches pid against binaryName + expectArg in /proc/<pid>/cmdline; falls back to IsProcessAlive on non-Linux or read errors.

func WaitFor

func WaitFor(ctx context.Context, timeout, interval time.Duration, check func() (done bool, err error)) error

WaitFor polls check at the given interval until it returns (true, nil), returns a non-nil error, or the timeout/context expires.

func WatchFile added in v0.2.6

func WatchFile(ctx context.Context, filePath string, debounce time.Duration) (<-chan struct{}, error)

WatchFile watches a file via fsnotify on the parent dir (atomic rename changes inode).

func WritePIDFile

func WritePIDFile(path string, pid int) error

WritePIDFile writes pid to path with 0600 permissions.

Types

type APIError

type APIError struct {
	Code    int
	Message string
}

APIError carries the HTTP status code from a REST API response.

func (*APIError) Error

func (e *APIError) Error() string

type BatchResult

type BatchResult[T any] struct {
	Succeeded []T
	Errors    []error
}

BatchResult holds the outcome of a best-effort batch operation.

func ForEach

func ForEach[T any](ctx context.Context, items []T, fn func(context.Context, T) error, concurrency ...int) BatchResult[T]

ForEach runs fn concurrently on each item, best-effort.

func (BatchResult[T]) Err

func (r BatchResult[T]) Err() error

Err returns the combined error from all failed operations.

type PipeStreamReader

type PipeStreamReader struct {
	*io.PipeReader
	// contains filtered or unexported fields
}

PipeStreamReader wraps a PipeReader with background error collection and cleanup.

func NewPipeStreamReader

func NewPipeStreamReader(pr *io.PipeReader, done <-chan error, cleanup func()) *PipeStreamReader

NewPipeStreamReader pairs pr with the producer's done channel so Close surfaces background errors and runs cleanup exactly once.

func (*PipeStreamReader) Close

func (r *PipeStreamReader) Close() error

Close drains the producer, runs cleanup, and returns any accumulated error.

type ProcScan added in v0.4.1

type ProcScan []procEntry

ProcScan caches /proc cmdlines for one binaryName. Batch callers scan once then Find per id, replacing N /proc walks with one.

func ScanProcsByBinary added in v0.4.1

func ScanProcsByBinary(binaryName string) (ProcScan, error)

ScanProcsByBinary walks /proc once, capturing argv[0]-basename matches. ENOENT (process exited mid-scan) is skipped; other read errors fail closed.

func (ProcScan) Find added in v0.4.1

func (s ProcScan) Find(expectArg string) []int

Find returns the cached pids whose cmdline contains expectArg, sorted numerically; empty expectArg matches all.

Jump to

Keyboard shortcuts

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