summaryrefslogtreecommitdiff
path: root/vendor/github.com/mistifyio/go-zfs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/github.com/mistifyio/go-zfs')
-rw-r--r--vendor/github.com/mistifyio/go-zfs/.travis.yml43
-rw-r--r--vendor/github.com/mistifyio/go-zfs/README.md2
-rw-r--r--vendor/github.com/mistifyio/go-zfs/utils.go102
-rw-r--r--vendor/github.com/mistifyio/go-zfs/utils_notsolaris.go17
-rw-r--r--vendor/github.com/mistifyio/go-zfs/utils_solaris.go17
-rw-r--r--vendor/github.com/mistifyio/go-zfs/zfs.go82
-rw-r--r--vendor/github.com/mistifyio/go-zfs/zpool.go19
7 files changed, 238 insertions, 44 deletions
diff --git a/vendor/github.com/mistifyio/go-zfs/.travis.yml b/vendor/github.com/mistifyio/go-zfs/.travis.yml
new file mode 100644
index 000000000..acbd39cef
--- /dev/null
+++ b/vendor/github.com/mistifyio/go-zfs/.travis.yml
@@ -0,0 +1,43 @@
+language: go
+dist: trusty
+sudo: required
+cache:
+ directories:
+ - $HOME/.ccache
+ - $HOME/zfs
+
+branches:
+ only:
+ - master
+
+env:
+ - rel=0.6.5.11
+ - rel=0.7.6
+
+go:
+ - "1.10.x"
+ - master
+
+before_install:
+ - export MAKEFLAGS=-j$(($(grep -c '^processor' /proc/cpuinfo) * 2 + 1))
+ - export PATH=/usr/lib/ccache:$PATH
+ - go get github.com/alecthomas/gometalinter
+ - gometalinter --install --update
+ - sudo apt-get update -y && sudo apt-get install -y libattr1-dev libblkid-dev linux-headers-$(uname -r) tree uuid-dev
+ - mkdir -p $HOME/zfs
+ - cd $HOME/zfs
+ - [[ -d spl-$rel.tar.gz ]] || curl -L https://github.com/zfsonlinux/zfs/releases/download/zfs-$rel/spl-$rel.tar.gz | tar xz
+ - [[ -d zfs-$rel.tar.gz ]] || curl -L https://github.com/zfsonlinux/zfs/releases/download/zfs-$rel/zfs-$rel.tar.gz | tar xz
+ - (cd spl-$rel && ./configure --prefix=/usr && make && sudo make install)
+ - (cd zfs-$rel && ./configure --prefix=/usr && make && sudo make install)
+ - sudo modprobe zfs
+ - cd $TRAVIS_BUILD_DIR
+
+script:
+ - sudo -E $(which go) test -v ./...
+ - gometalinter --vendor --vendored-linters ./... || true
+ - gometalinter --errors --vendor --vendored-linters ./...
+
+notifications:
+ email: false
+ irc: "chat.freenode.net#cerana"
diff --git a/vendor/github.com/mistifyio/go-zfs/README.md b/vendor/github.com/mistifyio/go-zfs/README.md
index 2515e588e..fef80d727 100644
--- a/vendor/github.com/mistifyio/go-zfs/README.md
+++ b/vendor/github.com/mistifyio/go-zfs/README.md
@@ -29,7 +29,7 @@ The tests have decent examples for most functions.
```go
//assuming a zpool named test
-//error handling ommitted
+//error handling omitted
f, err := zfs.CreateFilesystem("test/snapshot-test", nil)
diff --git a/vendor/github.com/mistifyio/go-zfs/utils.go b/vendor/github.com/mistifyio/go-zfs/utils.go
index d5b735349..c18c2c3da 100644
--- a/vendor/github.com/mistifyio/go-zfs/utils.go
+++ b/vendor/github.com/mistifyio/go-zfs/utils.go
@@ -2,12 +2,16 @@ package zfs
import (
"bytes"
+ "errors"
"fmt"
"io"
"os/exec"
"regexp"
+ "runtime"
"strconv"
"strings"
+
+ "github.com/google/uuid"
)
type command struct {
@@ -34,16 +38,17 @@ func (c *command) Run(arg ...string) ([][]string, error) {
}
cmd.Stderr = &stderr
- debug := strings.Join([]string{cmd.Path, strings.Join(cmd.Args, " ")}, " ")
- if logger != nil {
- logger.Log(cmd.Args)
- }
+ id := uuid.New().String()
+ joinedArgs := strings.Join(cmd.Args, " ")
+
+ logger.Log([]string{"ID:" + id, "START", joinedArgs})
err := cmd.Run()
+ logger.Log([]string{"ID:" + id, "FINISH"})
if err != nil {
return nil, &Error{
Err: err,
- Debug: debug,
+ Debug: strings.Join([]string{cmd.Path, joinedArgs[1:]}, " "),
Stderr: stderr.String(),
}
}
@@ -88,34 +93,50 @@ func setUint(field *uint64, value string) error {
}
func (ds *Dataset) parseLine(line []string) error {
- prop := line[1]
- val := line[2]
-
var err error
- switch prop {
- case "available":
- err = setUint(&ds.Avail, val)
- case "compression":
- setString(&ds.Compression, val)
- case "mountpoint":
- setString(&ds.Mountpoint, val)
- case "quota":
- err = setUint(&ds.Quota, val)
- case "type":
- setString(&ds.Type, val)
- case "origin":
- setString(&ds.Origin, val)
- case "used":
- err = setUint(&ds.Used, val)
- case "volsize":
- err = setUint(&ds.Volsize, val)
- case "written":
- err = setUint(&ds.Written, val)
- case "logicalused":
- err = setUint(&ds.Logicalused, val)
+ if len(line) != len(dsPropList) {
+ return errors.New("Output does not match what is expected on this platform")
}
- return err
+ setString(&ds.Name, line[0])
+ setString(&ds.Origin, line[1])
+
+ if err = setUint(&ds.Used, line[2]); err != nil {
+ return err
+ }
+ if err = setUint(&ds.Avail, line[3]); err != nil {
+ return err
+ }
+
+ setString(&ds.Mountpoint, line[4])
+ setString(&ds.Compression, line[5])
+ setString(&ds.Type, line[6])
+
+ if err = setUint(&ds.Volsize, line[7]); err != nil {
+ return err
+ }
+ if err = setUint(&ds.Quota, line[8]); err != nil {
+ return err
+ }
+ if err = setUint(&ds.Referenced, line[9]); err != nil {
+ return err
+ }
+
+ if runtime.GOOS == "solaris" {
+ return nil
+ }
+
+ if err = setUint(&ds.Written, line[10]); err != nil {
+ return err
+ }
+ if err = setUint(&ds.Logicalused, line[11]); err != nil {
+ return err
+ }
+ if err = setUint(&ds.Usedbydataset, line[12]); err != nil {
+ return err
+ }
+
+ return nil
}
/*
@@ -264,7 +285,8 @@ func parseInodeChanges(lines [][]string) ([]*InodeChange, error) {
}
func listByType(t, filter string) ([]*Dataset, error) {
- args := []string{"get", "-rHp", "-t", t, "all"}
+ args := []string{"list", "-rHp", "-t", t, "-o", dsPropListOptions}
+
if filter != "" {
args = append(args, filter)
}
@@ -307,6 +329,8 @@ func (z *Zpool) parseLine(line []string) error {
var err error
switch prop {
+ case "name":
+ setString(&z.Name, val)
case "health":
setString(&z.Health, val)
case "allocated":
@@ -315,6 +339,22 @@ func (z *Zpool) parseLine(line []string) error {
err = setUint(&z.Size, val)
case "free":
err = setUint(&z.Free, val)
+ case "fragmentation":
+ // Trim trailing "%" before parsing uint
+ i := strings.Index(val, "%")
+ if i < 0 {
+ i = len(val)
+ }
+ err = setUint(&z.Fragmentation, val[:i])
+ case "readonly":
+ z.ReadOnly = val == "on"
+ case "freeing":
+ err = setUint(&z.Freeing, val)
+ case "leaked":
+ err = setUint(&z.Leaked, val)
+ case "dedupratio":
+ // Trim trailing "x" before parsing float64
+ z.DedupRatio, err = strconv.ParseFloat(val[:len(val)-1], 64)
}
return err
}
diff --git a/vendor/github.com/mistifyio/go-zfs/utils_notsolaris.go b/vendor/github.com/mistifyio/go-zfs/utils_notsolaris.go
new file mode 100644
index 000000000..a46f73060
--- /dev/null
+++ b/vendor/github.com/mistifyio/go-zfs/utils_notsolaris.go
@@ -0,0 +1,17 @@
+// +build !solaris
+
+package zfs
+
+import (
+ "strings"
+)
+
+// List of ZFS properties to retrieve from zfs list command on a non-Solaris platform
+var dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced", "written", "logicalused", "usedbydataset"}
+
+var dsPropListOptions = strings.Join(dsPropList, ",")
+
+// List of Zpool properties to retrieve from zpool list command on a non-Solaris platform
+var zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio", "fragmentation", "freeing", "leaked"}
+var zpoolPropListOptions = strings.Join(zpoolPropList, ",")
+var zpoolArgs = []string{"get", "-p", zpoolPropListOptions}
diff --git a/vendor/github.com/mistifyio/go-zfs/utils_solaris.go b/vendor/github.com/mistifyio/go-zfs/utils_solaris.go
new file mode 100644
index 000000000..0a7e90f22
--- /dev/null
+++ b/vendor/github.com/mistifyio/go-zfs/utils_solaris.go
@@ -0,0 +1,17 @@
+// +build solaris
+
+package zfs
+
+import (
+ "strings"
+)
+
+// List of ZFS properties to retrieve from zfs list command on a Solaris platform
+var dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced"}
+
+var dsPropListOptions = strings.Join(dsPropList, ",")
+
+// List of Zpool properties to retrieve from zpool list command on a non-Solaris platform
+var zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio"}
+var zpoolPropListOptions = strings.Join(zpoolPropList, ",")
+var zpoolArgs = []string{"get", "-p", zpoolPropListOptions}
diff --git a/vendor/github.com/mistifyio/go-zfs/zfs.go b/vendor/github.com/mistifyio/go-zfs/zfs.go
index a1d740e07..4e5087ffe 100644
--- a/vendor/github.com/mistifyio/go-zfs/zfs.go
+++ b/vendor/github.com/mistifyio/go-zfs/zfs.go
@@ -32,9 +32,10 @@ type Dataset struct {
Type string
Written uint64
Volsize uint64
- Usedbydataset uint64
Logicalused uint64
+ Usedbydataset uint64
Quota uint64
+ Referenced uint64
}
// InodeType is the type of inode as reported by Diff
@@ -92,12 +93,20 @@ type Logger interface {
Log(cmd []string)
}
-var logger Logger
+type defaultLogger struct{}
+
+func (*defaultLogger) Log(cmd []string) {
+ return
+}
+
+var logger Logger = &defaultLogger{}
// SetLogger set a log handler to log all commands including arguments before
// they are executed
func SetLogger(l Logger) {
- logger = l
+ if l != nil {
+ logger = l
+ }
}
// zfs is a helper function to wrap typical calls to zfs.
@@ -137,7 +146,7 @@ func Volumes(filter string) ([]*Dataset, error) {
// 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 := zfs("get", "-Hp", "all", name)
+ out, err := zfs("list", "-Hp", "-o", dsPropListOptions, name)
if err != nil {
return nil, err
}
@@ -172,6 +181,46 @@ func (d *Dataset) Clone(dest string, properties map[string]string) (*Dataset, er
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)
+ _, err := zfs(args...)
+ if 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)
+ _, err := zfs(args...)
+ if err != nil {
+ return nil, err
+ }
+ return GetDataset(d.Name)
+}
+
// ReceiveSnapshot receives a ZFS stream from the input io.Reader, creates a
// new snapshot with the specified name, and streams the input data into the
// newly-created snapshot.
@@ -259,7 +308,7 @@ func (d *Dataset) SetProperty(key, val string) error {
// A full list of available ZFS properties may be found here:
// https://www.freebsd.org/cgi/man.cgi?zfs(8).
func (d *Dataset) GetProperty(key string) (string, error) {
- out, err := zfs("get", key, d.Name)
+ out, err := zfs("get", "-H", key, d.Name)
if err != nil {
return "", err
}
@@ -267,6 +316,26 @@ func (d *Dataset) GetProperty(key string) (string, error) {
return out[0][2], nil
}
+// Rename renames a dataset.
+func (d *Dataset) Rename(name string, createParent bool, 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")
+ }
+ _, err := zfs(args...)
+ if 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)
@@ -335,13 +404,14 @@ func (d *Dataset) Rollback(destroyMoreRecent bool) error {
// A recursion depth may be specified, or a depth of 0 allows unlimited
// recursion.
func (d *Dataset) Children(depth uint64) ([]*Dataset, error) {
- args := []string{"get", "-t", "all", "-Hp", "all"}
+ 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 := zfs(args...)
diff --git a/vendor/github.com/mistifyio/go-zfs/zpool.go b/vendor/github.com/mistifyio/go-zfs/zpool.go
index 6ba52d30c..d8db945d7 100644
--- a/vendor/github.com/mistifyio/go-zfs/zpool.go
+++ b/vendor/github.com/mistifyio/go-zfs/zpool.go
@@ -15,11 +15,16 @@ const (
// Zpool is a ZFS zpool. A pool is a top-level structure in ZFS, and can
// contain many descendent datasets.
type Zpool struct {
- Name string
- Health string
- Allocated uint64
- Size uint64
- Free uint64
+ Name string
+ Health string
+ Allocated uint64
+ Size uint64
+ Free uint64
+ Fragmentation uint64
+ ReadOnly bool
+ Freeing uint64
+ Leaked uint64
+ DedupRatio float64
}
// zpool is a helper function to wrap typical calls to zpool.
@@ -30,7 +35,9 @@ func zpool(arg ...string) ([][]string, error) {
// GetZpool retrieves a single ZFS zpool by name.
func GetZpool(name string) (*Zpool, error) {
- out, err := zpool("get", "all", "-p", name)
+ args := zpoolArgs
+ args = append(args, name)
+ out, err := zpool(args...)
if err != nil {
return nil, err
}