mirror of
https://github.com/containers/skopeo.git
synced 2025-09-05 08:41:00 +00:00
Bump github.com/containers/storage from 1.42.0 to 1.43.0
Bumps [github.com/containers/storage](https://github.com/containers/storage) from 1.42.0 to 1.43.0. - [Release notes](https://github.com/containers/storage/releases) - [Changelog](https://github.com/containers/storage/blob/main/docs/containers-storage-changes.md) - [Commits](https://github.com/containers/storage/compare/v1.42.0...v1.43.0) --- updated-dependencies: - dependency-name: github.com/containers/storage dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] <support@github.com>
This commit is contained in:
449
vendor/github.com/mistifyio/go-zfs/v3/zfs.go
generated
vendored
Normal file
449
vendor/github.com/mistifyio/go-zfs/v3/zfs.go
generated
vendored
Normal file
@@ -0,0 +1,449 @@
|
||||
// Package zfs provides wrappers around the ZFS command line tools.
|
||||
package zfs
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// ZFS dataset types, which can indicate if a dataset is a filesystem, snapshot, or volume.
|
||||
const (
|
||||
DatasetFilesystem = "filesystem"
|
||||
DatasetSnapshot = "snapshot"
|
||||
DatasetVolume = "volume"
|
||||
)
|
||||
|
||||
// Dataset is a ZFS dataset. A dataset could be a clone, filesystem, snapshot, or volume.
|
||||
// The Type struct member can be used to determine a dataset's type.
|
||||
//
|
||||
// The field definitions can be found in the ZFS manual:
|
||||
// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html.
|
||||
type Dataset struct {
|
||||
Name string
|
||||
Origin string
|
||||
Used uint64
|
||||
Avail uint64
|
||||
Mountpoint string
|
||||
Compression string
|
||||
Type string
|
||||
Written uint64
|
||||
Volsize uint64
|
||||
Logicalused uint64
|
||||
Usedbydataset uint64
|
||||
Quota uint64
|
||||
Referenced uint64
|
||||
}
|
||||
|
||||
// InodeType is the type of inode as reported by Diff.
|
||||
type InodeType int
|
||||
|
||||
// Types of Inodes.
|
||||
const (
|
||||
_ = iota // 0 == unknown type
|
||||
BlockDevice InodeType = iota
|
||||
CharacterDevice
|
||||
Directory
|
||||
Door
|
||||
NamedPipe
|
||||
SymbolicLink
|
||||
EventPort
|
||||
Socket
|
||||
File
|
||||
)
|
||||
|
||||
// ChangeType is the type of inode change as reported by Diff.
|
||||
type ChangeType int
|
||||
|
||||
// Types of Changes.
|
||||
const (
|
||||
_ = iota // 0 == unknown type
|
||||
Removed ChangeType = iota
|
||||
Created
|
||||
Modified
|
||||
Renamed
|
||||
)
|
||||
|
||||
// DestroyFlag is the options flag passed to Destroy.
|
||||
type DestroyFlag int
|
||||
|
||||
// Valid destroy options.
|
||||
const (
|
||||
DestroyDefault DestroyFlag = 1 << iota
|
||||
DestroyRecursive = 1 << iota
|
||||
DestroyRecursiveClones = 1 << iota
|
||||
DestroyDeferDeletion = 1 << iota
|
||||
DestroyForceUmount = 1 << iota
|
||||
)
|
||||
|
||||
// InodeChange represents a change as reported by Diff.
|
||||
type InodeChange struct {
|
||||
Change ChangeType
|
||||
Type InodeType
|
||||
Path string
|
||||
NewPath string
|
||||
ReferenceCountChange int
|
||||
}
|
||||
|
||||
// Logger can be used to log commands/actions.
|
||||
type Logger interface {
|
||||
Log(cmd []string)
|
||||
}
|
||||
|
||||
type defaultLogger struct{}
|
||||
|
||||
func (*defaultLogger) Log([]string) {
|
||||
}
|
||||
|
||||
var logger Logger = &defaultLogger{}
|
||||
|
||||
// SetLogger set a log handler to log all commands including arguments before they are executed.
|
||||
func SetLogger(l Logger) {
|
||||
if l != nil {
|
||||
logger = l
|
||||
}
|
||||
}
|
||||
|
||||
// zfs is a helper function to wrap typical calls to zfs that ignores stdout.
|
||||
func zfs(arg ...string) error {
|
||||
_, err := zfsOutput(arg...)
|
||||
return err
|
||||
}
|
||||
|
||||
// zfs is a helper function to wrap typical calls to zfs.
|
||||
func zfsOutput(arg ...string) ([][]string, error) {
|
||||
c := command{Command: "zfs"}
|
||||
return c.Run(arg...)
|
||||
}
|
||||
|
||||
// Datasets returns a slice of ZFS datasets, regardless of type.
|
||||
// A filter argument may be passed to select a dataset with the matching name, or empty string ("") may be used to select all datasets.
|
||||
func Datasets(filter string) ([]*Dataset, error) {
|
||||
return listByType("all", filter)
|
||||
}
|
||||
|
||||
// Snapshots returns a slice of ZFS snapshots.
|
||||
// A filter argument may be passed to select a snapshot with the matching name, or empty string ("") may be used to select all snapshots.
|
||||
func Snapshots(filter string) ([]*Dataset, error) {
|
||||
return listByType(DatasetSnapshot, filter)
|
||||
}
|
||||
|
||||
// Filesystems returns a slice of ZFS filesystems.
|
||||
// A filter argument may be passed to select a filesystem with the matching name, or empty string ("") may be used to select all filesystems.
|
||||
func Filesystems(filter string) ([]*Dataset, error) {
|
||||
return listByType(DatasetFilesystem, filter)
|
||||
}
|
||||
|
||||
// Volumes returns a slice of ZFS volumes.
|
||||
// A filter argument may be passed to select a volume with the matching name, or empty string ("") may be used to select all volumes.
|
||||
func Volumes(filter string) ([]*Dataset, error) {
|
||||
return listByType(DatasetVolume, filter)
|
||||
}
|
||||
|
||||
// GetDataset retrieves a single ZFS dataset by name.
|
||||
// This dataset could be any valid ZFS dataset type, such as a clone, filesystem, snapshot, or volume.
|
||||
func GetDataset(name string) (*Dataset, error) {
|
||||
out, err := zfsOutput("list", "-Hp", "-o", dsPropListOptions, name)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ds := &Dataset{Name: name}
|
||||
for _, line := range out {
|
||||
if err := ds.parseLine(line); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
|
||||
return ds, nil
|
||||
}
|
||||
|
||||
// Clone clones a ZFS snapshot and returns a clone dataset.
|
||||
// An error will be returned if the input dataset is not of snapshot type.
|
||||
func (d *Dataset) Clone(dest string, properties map[string]string) (*Dataset, error) {
|
||||
if d.Type != DatasetSnapshot {
|
||||
return nil, errors.New("can only clone snapshots")
|
||||
}
|
||||
args := make([]string, 2, 4)
|
||||
args[0] = "clone"
|
||||
args[1] = "-p"
|
||||
if properties != nil {
|
||||
args = append(args, propsSlice(properties)...)
|
||||
}
|
||||
args = append(args, []string{d.Name, dest}...)
|
||||
if err := zfs(args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetDataset(dest)
|
||||
}
|
||||
|
||||
// Unmount unmounts currently mounted ZFS file systems.
|
||||
func (d *Dataset) Unmount(force bool) (*Dataset, error) {
|
||||
if d.Type == DatasetSnapshot {
|
||||
return nil, errors.New("cannot unmount snapshots")
|
||||
}
|
||||
args := make([]string, 1, 3)
|
||||
args[0] = "umount"
|
||||
if force {
|
||||
args = append(args, "-f")
|
||||
}
|
||||
args = append(args, d.Name)
|
||||
if err := zfs(args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetDataset(d.Name)
|
||||
}
|
||||
|
||||
// Mount mounts ZFS file systems.
|
||||
func (d *Dataset) Mount(overlay bool, options []string) (*Dataset, error) {
|
||||
if d.Type == DatasetSnapshot {
|
||||
return nil, errors.New("cannot mount snapshots")
|
||||
}
|
||||
args := make([]string, 1, 5)
|
||||
args[0] = "mount"
|
||||
if overlay {
|
||||
args = append(args, "-O")
|
||||
}
|
||||
if options != nil {
|
||||
args = append(args, "-o")
|
||||
args = append(args, strings.Join(options, ","))
|
||||
}
|
||||
args = append(args, d.Name)
|
||||
if err := zfs(args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetDataset(d.Name)
|
||||
}
|
||||
|
||||
// ReceiveSnapshot receives a ZFS stream from the input io.Reader.
|
||||
// A new snapshot is created with the specified name, and streams the input data into the newly-created snapshot.
|
||||
func ReceiveSnapshot(input io.Reader, name string) (*Dataset, error) {
|
||||
c := command{Command: "zfs", Stdin: input}
|
||||
if _, err := c.Run("receive", name); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetDataset(name)
|
||||
}
|
||||
|
||||
// SendSnapshot sends a ZFS stream of a snapshot to the input io.Writer.
|
||||
// An error will be returned if the input dataset is not of snapshot type.
|
||||
func (d *Dataset) SendSnapshot(output io.Writer) error {
|
||||
if d.Type != DatasetSnapshot {
|
||||
return errors.New("can only send snapshots")
|
||||
}
|
||||
|
||||
c := command{Command: "zfs", Stdout: output}
|
||||
_, err := c.Run("send", d.Name)
|
||||
return err
|
||||
}
|
||||
|
||||
// IncrementalSend sends a ZFS stream of a snapshot to the input io.Writer using the baseSnapshot as the starting point.
|
||||
// An error will be returned if the input dataset is not of snapshot type.
|
||||
func (d *Dataset) IncrementalSend(baseSnapshot *Dataset, output io.Writer) error {
|
||||
if d.Type != DatasetSnapshot || baseSnapshot.Type != DatasetSnapshot {
|
||||
return errors.New("can only send snapshots")
|
||||
}
|
||||
c := command{Command: "zfs", Stdout: output}
|
||||
_, err := c.Run("send", "-i", baseSnapshot.Name, d.Name)
|
||||
return err
|
||||
}
|
||||
|
||||
// CreateVolume creates a new ZFS volume with the specified name, size, and properties.
|
||||
//
|
||||
// A full list of available ZFS properties may be found in the ZFS manual:
|
||||
// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html.
|
||||
func CreateVolume(name string, size uint64, properties map[string]string) (*Dataset, error) {
|
||||
args := make([]string, 4, 5)
|
||||
args[0] = "create"
|
||||
args[1] = "-p"
|
||||
args[2] = "-V"
|
||||
args[3] = strconv.FormatUint(size, 10)
|
||||
if properties != nil {
|
||||
args = append(args, propsSlice(properties)...)
|
||||
}
|
||||
args = append(args, name)
|
||||
if err := zfs(args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetDataset(name)
|
||||
}
|
||||
|
||||
// Destroy destroys a ZFS dataset.
|
||||
// If the destroy bit flag is set, any descendents of the dataset will be recursively destroyed, including snapshots.
|
||||
// If the deferred bit flag is set, the snapshot is marked for deferred deletion.
|
||||
func (d *Dataset) Destroy(flags DestroyFlag) error {
|
||||
args := make([]string, 1, 3)
|
||||
args[0] = "destroy"
|
||||
if flags&DestroyRecursive != 0 {
|
||||
args = append(args, "-r")
|
||||
}
|
||||
|
||||
if flags&DestroyRecursiveClones != 0 {
|
||||
args = append(args, "-R")
|
||||
}
|
||||
|
||||
if flags&DestroyDeferDeletion != 0 {
|
||||
args = append(args, "-d")
|
||||
}
|
||||
|
||||
if flags&DestroyForceUmount != 0 {
|
||||
args = append(args, "-f")
|
||||
}
|
||||
|
||||
args = append(args, d.Name)
|
||||
err := zfs(args...)
|
||||
return err
|
||||
}
|
||||
|
||||
// SetProperty sets a ZFS property on the receiving dataset.
|
||||
//
|
||||
// A full list of available ZFS properties may be found in the ZFS manual:
|
||||
// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html.
|
||||
func (d *Dataset) SetProperty(key, val string) error {
|
||||
prop := strings.Join([]string{key, val}, "=")
|
||||
err := zfs("set", prop, d.Name)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetProperty returns the current value of a ZFS property from the receiving dataset.
|
||||
//
|
||||
// A full list of available ZFS properties may be found in the ZFS manual:
|
||||
// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html.
|
||||
func (d *Dataset) GetProperty(key string) (string, error) {
|
||||
out, err := zfsOutput("get", "-H", key, d.Name)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
return out[0][2], nil
|
||||
}
|
||||
|
||||
// Rename renames a dataset.
|
||||
func (d *Dataset) Rename(name string, createParent, recursiveRenameSnapshots bool) (*Dataset, error) {
|
||||
args := make([]string, 3, 5)
|
||||
args[0] = "rename"
|
||||
args[1] = d.Name
|
||||
args[2] = name
|
||||
if createParent {
|
||||
args = append(args, "-p")
|
||||
}
|
||||
if recursiveRenameSnapshots {
|
||||
args = append(args, "-r")
|
||||
}
|
||||
if err := zfs(args...); err != nil {
|
||||
return d, err
|
||||
}
|
||||
|
||||
return GetDataset(name)
|
||||
}
|
||||
|
||||
// Snapshots returns a slice of all ZFS snapshots of a given dataset.
|
||||
func (d *Dataset) Snapshots() ([]*Dataset, error) {
|
||||
return Snapshots(d.Name)
|
||||
}
|
||||
|
||||
// CreateFilesystem creates a new ZFS filesystem with the specified name and properties.
|
||||
//
|
||||
// A full list of available ZFS properties may be found in the ZFS manual:
|
||||
// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html.
|
||||
func CreateFilesystem(name string, properties map[string]string) (*Dataset, error) {
|
||||
args := make([]string, 1, 4)
|
||||
args[0] = "create"
|
||||
|
||||
if properties != nil {
|
||||
args = append(args, propsSlice(properties)...)
|
||||
}
|
||||
|
||||
args = append(args, name)
|
||||
if err := zfs(args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetDataset(name)
|
||||
}
|
||||
|
||||
// Snapshot creates a new ZFS snapshot of the receiving dataset, using the specified name.
|
||||
// Optionally, the snapshot can be taken recursively, creating snapshots of all descendent filesystems in a single, atomic operation.
|
||||
func (d *Dataset) Snapshot(name string, recursive bool) (*Dataset, error) {
|
||||
args := make([]string, 1, 4)
|
||||
args[0] = "snapshot"
|
||||
if recursive {
|
||||
args = append(args, "-r")
|
||||
}
|
||||
snapName := fmt.Sprintf("%s@%s", d.Name, name)
|
||||
args = append(args, snapName)
|
||||
if err := zfs(args...); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return GetDataset(snapName)
|
||||
}
|
||||
|
||||
// Rollback rolls back the receiving ZFS dataset to a previous snapshot.
|
||||
// Optionally, intermediate snapshots can be destroyed.
|
||||
// A ZFS snapshot rollback cannot be completed without this option, if more recent snapshots exist.
|
||||
// An error will be returned if the input dataset is not of snapshot type.
|
||||
func (d *Dataset) Rollback(destroyMoreRecent bool) error {
|
||||
if d.Type != DatasetSnapshot {
|
||||
return errors.New("can only rollback snapshots")
|
||||
}
|
||||
|
||||
args := make([]string, 1, 3)
|
||||
args[0] = "rollback"
|
||||
if destroyMoreRecent {
|
||||
args = append(args, "-r")
|
||||
}
|
||||
args = append(args, d.Name)
|
||||
|
||||
err := zfs(args...)
|
||||
return err
|
||||
}
|
||||
|
||||
// Children returns a slice of children of the receiving ZFS dataset.
|
||||
// A recursion depth may be specified, or a depth of 0 allows unlimited recursion.
|
||||
func (d *Dataset) Children(depth uint64) ([]*Dataset, error) {
|
||||
args := []string{"list"}
|
||||
if depth > 0 {
|
||||
args = append(args, "-d")
|
||||
args = append(args, strconv.FormatUint(depth, 10))
|
||||
} else {
|
||||
args = append(args, "-r")
|
||||
}
|
||||
args = append(args, "-t", "all", "-Hp", "-o", dsPropListOptions)
|
||||
args = append(args, d.Name)
|
||||
|
||||
out, err := zfsOutput(args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var datasets []*Dataset
|
||||
name := ""
|
||||
var ds *Dataset
|
||||
for _, line := range out {
|
||||
if name != line[0] {
|
||||
name = line[0]
|
||||
ds = &Dataset{Name: name}
|
||||
datasets = append(datasets, ds)
|
||||
}
|
||||
if err := ds.parseLine(line); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
}
|
||||
return datasets[1:], nil
|
||||
}
|
||||
|
||||
// Diff returns changes between a snapshot and the given ZFS dataset.
|
||||
// The snapshot name must include the filesystem part as it is possible to compare clones with their origin snapshots.
|
||||
func (d *Dataset) Diff(snapshot string) ([]*InodeChange, error) {
|
||||
args := []string{"diff", "-FH", snapshot, d.Name}
|
||||
out, err := zfsOutput(args...)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
inodeChanges, err := parseInodeChanges(out)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return inodeChanges, nil
|
||||
}
|
Reference in New Issue
Block a user