Merge pull request #45672 from thaJeztah/24.0_backport_bump_zfs

[24.0 backport] vendor: github.com/mistifyio/go-zfs/v3 v3.0.1
This commit is contained in:
Sebastiaan van Stijn 2023-06-02 11:48:36 +02:00 committed by GitHub
commit 32d442aee1
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
27 changed files with 907 additions and 298 deletions

View file

@ -16,7 +16,7 @@ import (
"github.com/docker/docker/daemon/graphdriver"
"github.com/docker/docker/pkg/idtools"
"github.com/docker/docker/pkg/parsers"
zfs "github.com/mistifyio/go-zfs"
zfs "github.com/mistifyio/go-zfs/v3"
"github.com/moby/locker"
"github.com/moby/sys/mount"
"github.com/moby/sys/mountinfo"

View file

@ -55,7 +55,7 @@ require (
github.com/ishidawataru/sctp v0.0.0-20230406120618-7ff4192f6ff2
github.com/klauspost/compress v1.16.3
github.com/miekg/dns v1.1.43
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
github.com/mistifyio/go-zfs/v3 v3.0.1
github.com/moby/buildkit v0.11.7-0.20230525183624-798ad6b0ce9f // IMPORTANT: when updating, also update the version in builder/builder-next/worker/worker.go
github.com/moby/ipvs v1.1.0
github.com/moby/locker v1.0.1

View file

@ -1024,8 +1024,9 @@ github.com/miekg/dns v1.1.26/go.mod h1:bPDLeHnStXmXAq1m/Ch/hvfNHr14JKNPMBo3VZKju
github.com/miekg/dns v1.1.43 h1:JKfpVSCB84vrAmHzyrsxB5NAr5kLoMXZArPSw7Qlgyg=
github.com/miekg/dns v1.1.43/go.mod h1:+evo5L0630/F6ca/Z9+GAqzhjGyn8/c+TBaOyfEl0V4=
github.com/miekg/pkcs11 v1.0.3/go.mod h1:XsNlhZGX73bx86s2hdc/FuaLm2CPZJemRLMA+WTFxgs=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible h1:aKW/4cBs+yK6gpqU3K/oIwk9Q/XICqd3zOX/UFuvqmk=
github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible/go.mod h1:8AuVvqP/mXw1px98n46wfvcGfQ4ci2FwoAjKYxuo3Z4=
github.com/mistifyio/go-zfs/v3 v3.0.1 h1:YaoXgBePoMA12+S1u/ddkv+QqxcfiZK4prI6HPnkFiU=
github.com/mistifyio/go-zfs/v3 v3.0.1/go.mod h1:CzVgeB0RvF2EGzQnytKVvVSDwmKJXxkOTUGbNrTja/k=
github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=

View file

@ -1 +0,0 @@
.vagrant

View file

@ -1,43 +0,0 @@
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"

View file

@ -1,34 +0,0 @@
VAGRANTFILE_API_VERSION = "2"
Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = "ubuntu/trusty64"
config.ssh.forward_agent = true
config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/mistifyio/go-zfs", create: true
config.vm.provision "shell", inline: <<EOF
cat << END > /etc/profile.d/go.sh
export GOPATH=\\$HOME/go
export PATH=\\$GOPATH/bin:/usr/local/go/bin:\\$PATH
END
chown -R vagrant /home/vagrant/go
apt-get update
apt-get install -y software-properties-common curl
apt-add-repository --yes ppa:zfs-native/stable
apt-get update
apt-get install -y ubuntu-zfs
cd /home/vagrant
curl -z go1.3.3.linux-amd64.tar.gz -L -O https://storage.googleapis.com/golang/go1.3.3.linux-amd64.tar.gz
tar -C /usr/local -zxf /home/vagrant/go1.3.3.linux-amd64.tar.gz
cat << END > /etc/sudoers.d/go
Defaults env_keep += "GOPATH"
END
EOF
end

View file

@ -1,17 +0,0 @@
// +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}

View file

@ -1,17 +0,0 @@
// +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}

6
vendor/github.com/mistifyio/go-zfs/v3/.gitignore generated vendored Normal file
View file

@ -0,0 +1,6 @@
bin
go-zfs.test
.vagrant
# added by lint-install
out/

207
vendor/github.com/mistifyio/go-zfs/v3/.golangci.yml generated vendored Normal file
View file

@ -0,0 +1,207 @@
run:
# The default runtime timeout is 1m, which doesn't work well on Github Actions.
timeout: 4m
# NOTE: This file is populated by the lint-install tool. Local adjustments may be overwritten.
linters-settings:
cyclop:
# NOTE: This is a very high transitional threshold
max-complexity: 37
package-average: 34.0
skip-tests: true
gocognit:
# NOTE: This is a very high transitional threshold
min-complexity: 98
dupl:
threshold: 200
goconst:
min-len: 4
min-occurrences: 5
ignore-tests: true
gosec:
excludes:
- G107 # Potential HTTP request made with variable url
- G204 # Subprocess launched with function call as argument or cmd arguments
- G404 # Use of weak random number generator (math/rand instead of crypto/rand
errorlint:
# these are still common in Go: for instance, exit errors.
asserts: false
exhaustive:
default-signifies-exhaustive: true
nestif:
min-complexity: 8
nolintlint:
require-explanation: true
allow-unused: false
require-specific: true
revive:
ignore-generated-header: true
severity: warning
rules:
- name: atomic
- name: blank-imports
- name: bool-literal-in-expr
- name: confusing-naming
- name: constant-logical-expr
- name: context-as-argument
- name: context-keys-type
- name: deep-exit
- name: defer
- name: range-val-in-closure
- name: range-val-address
- name: dot-imports
- name: error-naming
- name: error-return
- name: error-strings
- name: errorf
- name: exported
- name: identical-branches
- name: if-return
- name: import-shadowing
- name: increment-decrement
- name: indent-error-flow
- name: indent-error-flow
- name: package-comments
- name: range
- name: receiver-naming
- name: redefines-builtin-id
- name: superfluous-else
- name: struct-tag
- name: time-naming
- name: unexported-naming
- name: unexported-return
- name: unnecessary-stmt
- name: unreachable-code
- name: unused-parameter
- name: var-declaration
- name: var-naming
- name: unconditional-recursion
- name: waitgroup-by-value
staticcheck:
go: "1.16"
unused:
go: "1.16"
output:
sort-results: true
linters:
disable-all: true
enable:
- asciicheck
- bodyclose
- cyclop
- deadcode
- dogsled
- dupl
- durationcheck
- errcheck
- errname
- errorlint
- exhaustive
- exportloopref
- forcetypeassert
- gocognit
- goconst
- gocritic
- godot
- gofmt
- gofumpt
- gosec
- goheader
- goimports
- goprintffuncname
- gosimple
- govet
- ifshort
- importas
- ineffassign
- makezero
- misspell
- nakedret
- nestif
- nilerr
- noctx
- nolintlint
- predeclared
# disabling for the initial iteration of the linting tool
# - promlinter
- revive
- rowserrcheck
- sqlclosecheck
- staticcheck
- structcheck
- stylecheck
- thelper
- tparallel
- typecheck
- unconvert
- unparam
- unused
- varcheck
- wastedassign
- whitespace
# Disabled linters, due to being misaligned with Go practices
# - exhaustivestruct
# - gochecknoglobals
# - gochecknoinits
# - goconst
# - godox
# - goerr113
# - gomnd
# - lll
# - nlreturn
# - testpackage
# - wsl
# Disabled linters, due to not being relevant to our code base:
# - maligned
# - prealloc "For most programs usage of prealloc will be a premature optimization."
# Disabled linters due to bad error messages or bugs
# - tagliatelle
issues:
# Excluding configuration per-path, per-linter, per-text and per-source
exclude-rules:
- path: _test\.go
linters:
- dupl
- errcheck
- forcetypeassert
- gocyclo
- gosec
- noctx
- path: .*cmd.*
linters:
- noctx
- path: main\.go
linters:
- noctx
- path: .*cmd.*
text: "deep-exit"
- path: main\.go
text: "deep-exit"
# This check is of questionable value
- linters:
- tparallel
text: "call t.Parallel on the top level as well as its subtests"
# Don't hide lint issues just because there are many of them
max-same-issues: 0
max-issues-per-linter: 0

16
vendor/github.com/mistifyio/go-zfs/v3/.yamllint generated vendored Normal file
View file

@ -0,0 +1,16 @@
---
extends: default
rules:
braces:
max-spaces-inside: 1
brackets:
max-spaces-inside: 1
comments: disable
comments-indentation: disable
document-start: disable
line-length:
level: warning
max: 160
allow-non-breakable-inline-mappings: true
truthy: disable

250
vendor/github.com/mistifyio/go-zfs/v3/CHANGELOG.md generated vendored Normal file
View file

@ -0,0 +1,250 @@
# Change Log
All notable changes to this project will be documented in this file.
This project adheres to [Semantic Versioning](http://semver.org/).
This change log follows the advice of [Keep a CHANGELOG](https://github.com/olivierlacan/keep-a-changelog).
## [Unreleased]
## [3.0.0] - 2022-03-30
### Added
- Rename, Mount and Unmount methods
- Parse more fields into Zpool type:
- dedupratio
- fragmentation
- freeing
- leaked
- readonly
- Parse more fields into Dataset type:
- referenced
- Incremental Send
- Parse numbers in exact format
- Support for Solaris (non-blockint, best-effort status)
- Debug logging for command invocation
- Use GitHub Actions for CI
- Nix shell for dev env reproducibility
- Direnv file for ease of dev
- Formatting/lint checks (enforced by CI)
- Go Module
- FreeBSD based vagrant machine
### Changed
- Temporarily adjust TestDiff expected strings depending on ZFS version
- Use one `zfs list`/`zpool list` call instead of many `zfs get`/`zpool get`
- ZFS docs links now point to OpenZFS pages
- Ubuntu vagrant box changed to generic/ubuntu2004
### Fixed
- `GetProperty` returning `VALUE` instead of the actual value
### Shortlog
Amit Krishnan (1):
Issue #39 and Issue #40 - Enable Solaris support for go-zfs Switch from zfs/zpool get to zfs/zpool list for better performance Signed-off-by: Amit Krishnan <krish.amit@gmail.com>
Anand Patil (3):
Added Rename
Small fix to rename.
Added mount and umount methods
Brian Akins (1):
Add 'referenced' to zfs properties
Brian Bickerton (3):
Add debug logging before and after running external zfs command
Don't export the default no-op logger
Update uuid package repo url
Dmitry Teselkin (1):
Issue #52 - fix parseLine for fragmentation field
Edward Betts (1):
correct spelling mistake
Justin Cormack (1):
Switch to google/uuid which is the maintained version of pborman/uuid
Manuel Mendez (40):
rename Umount -> Unmount to follow zfs command name
add missing Unmount/Mount docs
always allocate largest Mount slice
add travis config
travis: update to go 1.7
travis: get go deps first
test: add nok helper to verify an error occurred
test: add test for Dataset.GetProperty
ci: swap #cerana on freenode for slack
ci: install new deps for 0.7 relases
ci: bump zol versions
ci: bump go versions
ci: use better gometalinter invocations
ci: add ccache
ci: set env earlier in before_install
fix test nok error printing
test: restructure TestDiff to deal with different order of changes
test: better unicode path handling in TestDiff
travis: bump zfs and go versions
cache zfs artifacts
Add nix-shell and direnv goodness
prettierify all the files
Add go based tools
Add Makefile and rules.mk files
gofumptize the code base
Use tinkerbell/lint-install to setup linters
make golangci-lint happy
Update CONTRIBUTING.md with make based approach
Add GitHub Actions
Drop Travis CI
One sentence per line
Update documentation links to openzfs-docs pages
Format Vagrantfile using rufo
Add go-zfs.test to .gitignore
test: Avoid reptitive/duplicate error logging and quitting
test: Use t.Logf instead of fmt.Printf
test: Better cleanup and error handling in zpoolTest
test: Do not mark TestDatasets as a t.Helper.
test: Change zpoolTest to a pure helper that returns a clean up function
test: Move helpers to a different file
vagrant: Add set -euxo pipefail to provision script
vagrant: Update to generic/ubuntu2004
vagrant: Minor fixes to Vagrantfile
vagrant: Update to go 1.17.8
vagrant: Run go tests as part of provision script
vagrant: Indent heredoc script
vagrant: Add freebsd machine
Matt Layher (1):
Parse more fields into Zpool type
Michael Crosby (1):
Add incremental send
Rikard Gynnerstedt (1):
remove command name from joined args
Sebastiaan van Stijn (1):
Add go.mod and rename to github.com/mistifyio/go-zfs/v3 (v3.0.0)
mikudeko (1):
Fix GetProperty always returning 'VALUE'
## [2.1.1] - 2015-05-29
### Fixed
- Ignoring first pool listed
- Incorrect `zfs get` argument ordering
### Shortlog
Alexey Guskov (1):
zfs command uses different order of arguments on freebsd
Brian Akins (4):
test that ListZpools returns expected zpool
test error first
test error first
fix test to check correct return value
James Cunningham (1):
Fix Truncating First Zpool
Pat Norton (2):
Added Use of Go Tools
Update CONTRIBUTING.md
## [2.1.0] - 2014-12-08
### Added
- Parse hardlink modification count returned from `zfs diff`
### Fixed
- Continuing instead of erroring when rolling back a non-snapshot
### Shortlog
Brian Akins (2):
need to return the error here
use named struct fields
Jörg Thalheim (1):
zfs diff handle hardlinks modification now
## [2.0.0] - 2014-12-02
### Added
- Flags for Destroy:
- DESTROY_DEFAULT
- DESTROY_DEFER_DELETION (`zfs destroy ... -d`)
- DESTROY_FORCE (`zfs destroy ... -f`)
- DESTROY_RECURSIVE_CLONES (`zfs destroy ... -R`)
- DESTROY_RECURSIVE (`zfs destroy ... -r`)
- etc
- Diff method (`zfs diff`)
- LogicalUsed and Origin properties to Dataset
- Type constants for Dataset
- State constants for Zpool
- Logger interface
- Improve documentation
### Shortlog
Brian Akins (8):
remove reflection
style change for switches
need to check for error
keep in scope
go 1.3.3
golint cleanup
Just test if logical used is greater than 0, as this appears to be implementation specific
add docs to satisfy golint
Jörg Thalheim (8):
Add deferred flag to zfs.Destroy()
add Logicalused property
Add Origin property
gofmt
Add zfs.Diff
Add Logger
add recursive destroy with clones
use CamelCase-style constants
Matt Layher (4):
Improve documentation, document common ZFS operations, provide more references
Add zpool state constants, for easier health checking
Add dataset type constants, for easier type checking
Fix string split in command.Run(), use strings.Fields() instead of strings.Split()
## [1.0.0] - 2014-11-12
### Shortlog
Brian Akins (7):
add godoc badge
Add example
add information about zpool to struct and parser
Add Quota
add Children call
add Children call
fix snapshot tests
Brian Bickerton (3):
MIST-150 Change Snapshot second paramater from properties map[string][string] to recursive bool
MIST-150 Add Rollback method and related tests
MIST-160 Add SendSnapshot streaming method and tests
Matt Layher (1):
Add Error struct type and tests, enabling easier error return checking
[3.0.0]: https://github.com/mistifyio/go-zfs/compare/v2.1.1...v3.0.0
[2.1.1]: https://github.com/mistifyio/go-zfs/compare/v2.1.0...v2.1.1
[2.1.0]: https://github.com/mistifyio/go-zfs/compare/v2.0.0...v2.1.0
[2.0.0]: https://github.com/mistifyio/go-zfs/compare/v1.0.0...v2.0.0
[1.0.0]: https://github.com/mistifyio/go-zfs/compare/v0.0.0...v1.0.0

View file

@ -1,20 +1,23 @@
## How to Contribute ##
## How to Contribute
We always welcome contributions to help make `go-zfs` better. Please take a moment to read this document if you would like to contribute.
We always welcome contributions to help make `go-zfs` better.
Please take a moment to read this document if you would like to contribute.
### Reporting issues ###
### Reporting issues
We use [Github issues](https://github.com/mistifyio/go-zfs/issues) to track bug reports, feature requests, and submitting pull requests.
If you find a bug:
* Use the GitHub issue search to check whether the bug has already been reported.
* If the issue has been fixed, try to reproduce the issue using the latest `master` branch of the repository.
* If the issue still reproduces or has not yet been reported, try to isolate the problem before opening an issue, if possible. Also provide the steps taken to reproduce the bug.
- Use the GitHub issue search to check whether the bug has already been reported.
- If the issue has been fixed, try to reproduce the issue using the latest `master` branch of the repository.
- If the issue still reproduces or has not yet been reported, try to isolate the problem before opening an issue, if possible. Also provide the steps taken to reproduce the bug.
### Pull requests ###
### Pull requests
We welcome bug fixes, improvements, and new features. Before embarking on making significant changes, please open an issue and ask first so that you do not risk duplicating efforts or spending time working on something that may be out of scope. For minor items, just open a pull request.
We welcome bug fixes, improvements, and new features.
Before embarking on making significant changes, please open an issue and ask first so that you do not risk duplicating efforts or spending time working on something that may be out of scope.
For minor items, just open a pull request.
[Fork the project](https://help.github.com/articles/fork-a-repo), clone your fork, and add the upstream to your remote:
@ -28,11 +31,13 @@ If you need to pull new changes committed upstream:
$ git fetch upstream
$ git merge upstream/master
Don' work directly on master as this makes it harder to merge later. Create a feature branch for your fix or new feature:
Don' work directly on master as this makes it harder to merge later.
Create a feature branch for your fix or new feature:
$ git checkout -b <feature-branch-name>
Please try to commit your changes in logical chunks. Ideally, you should include the issue number in the commit message.
Please try to commit your changes in logical chunks.
Ideally, you should include the issue number in the commit message.
$ git commit -m "Issue #<issue-number> - <commit-message>"
@ -40,21 +45,20 @@ Push your feature branch to your fork.
$ git push origin <feature-branch-name>
[Open a Pull Request](https://help.github.com/articles/using-pull-requests) against the upstream master branch. Please give your pull request a clear title and description and note which issue(s) your pull request fixes.
[Open a Pull Request](https://help.github.com/articles/using-pull-requests) against the upstream master branch.
Please give your pull request a clear title and description and note which issue(s) your pull request fixes.
* All Go code should be formatted using [gofmt](http://golang.org/cmd/gofmt/).
* Every exported function should have [documentation](http://blog.golang.org/godoc-documenting-go-code) and corresponding [tests](http://golang.org/doc/code.html#Testing).
- All linters should be happy (can be run with `make verify`).
- Every exported function should have [documentation](http://blog.golang.org/godoc-documenting-go-code) and corresponding [tests](http://golang.org/doc/code.html#Testing).
**Important:** By submitting a patch, you agree to allow the project owners to license your work under the [Apache 2.0 License](./LICENSE).
### Go Tools ###
For consistency and to catch minor issues for all of go code, please run the following:
* goimports
* go vet
* golint
* errcheck
### Go Tools
For consistency and to catch minor issues for all of go code, please run `make verify`.
Many editors can execute the above on save.
----
---
Guidelines based on http://azkaban.github.io/contributing.html

19
vendor/github.com/mistifyio/go-zfs/v3/Makefile generated vendored Normal file
View file

@ -0,0 +1,19 @@
help: ## Print this help
@grep --no-filename -E '^[a-zA-Z0-9_-]+:.*?## .*$$' $(MAKEFILE_LIST) | sed 's/:.*## /·/' | sort | column -t -W 2 -s '·' -c $(shell tput cols)
all: test ## Run tests
-include rules.mk
-include lint.mk
test: ## Run tests
go test ./...
verify: gofumpt prettier lint ## Verify code style, is lint free, freshness ...
git diff | (! grep .)
fix: gofumpt-fix prettier-fix ## Fix code formatting errors
tools: ${toolsBins} ## Build Go based build tools
.PHONY: all help test tools verify

View file

@ -1,12 +1,12 @@
# Go Wrapper for ZFS #
# Go Wrapper for ZFS
Simple wrappers for ZFS command line tools.
[![GoDoc](https://godoc.org/github.com/mistifyio/go-zfs?status.svg)](https://godoc.org/github.com/mistifyio/go-zfs)
## Requirements ##
## Requirements
You need a working ZFS setup. To use on Ubuntu 14.04, setup ZFS:
You need a working ZFS setup. To use on Ubuntu 14.04, setup ZFS:
sudo apt-get install python-software-properties
sudo apt-add-repository ppa:zfs-native/stable
@ -17,13 +17,13 @@ Developed using Go 1.3, but currently there isn't anything 1.3 specific. Don't u
Generally you need root privileges to use anything zfs related.
## Status ##
## Status
This has been only been tested on Ubuntu 14.04
In the future, we hope to work directly with libzfs.
# Hacking #
# Hacking
The tests have decent examples for most functions.
@ -48,7 +48,6 @@ err := f.Destroy()
```
# Contributing #
# Contributing
See the [contributing guidelines](./CONTRIBUTING.md)

33
vendor/github.com/mistifyio/go-zfs/v3/Vagrantfile generated vendored Normal file
View file

@ -0,0 +1,33 @@
GOVERSION = "1.17.8"
Vagrant.configure("2") do |config|
config.vm.define "ubuntu" do |ubuntu|
ubuntu.vm.box = "generic/ubuntu2004"
end
config.vm.define "freebsd" do |freebsd|
freebsd.vm.box = "generic/freebsd13"
end
config.ssh.forward_agent = true
config.vm.synced_folder ".", "/home/vagrant/go/src/github.com/mistifyio/go-zfs", create: true
config.vm.provision "shell", inline: <<-EOF
set -euxo pipefail
os=$(uname -s|tr '[A-Z]' '[a-z]')
case $os in
linux) apt-get update -y && apt-get install -y --no-install-recommends gcc libc-dev zfsutils-linux ;;
esac
cd /tmp
curl -fLO --retry-max-time 30 --retry 10 https://go.dev/dl/go#{GOVERSION}.$os-amd64.tar.gz
tar -C /usr/local -zxf go#{GOVERSION}.$os-amd64.tar.gz
ln -nsf /usr/local/go/bin/go /usr/local/bin/go
rm -rf go*.tar.gz
chown -R vagrant:vagrant /home/vagrant/go
cd /home/vagrant/go/src/github.com/mistifyio/go-zfs
go test -c
sudo ./go-zfs.test -test.v
CGO_ENABLED=0 go test -c
sudo ./go-zfs.test -test.v
EOF
end

75
vendor/github.com/mistifyio/go-zfs/v3/lint.mk generated vendored Normal file
View file

@ -0,0 +1,75 @@
# BEGIN: lint-install -makefile lint.mk .
# http://github.com/tinkerbell/lint-install
.PHONY: lint
lint: _lint
LINT_ARCH := $(shell uname -m)
LINT_OS := $(shell uname)
LINT_OS_LOWER := $(shell echo $(LINT_OS) | tr '[:upper:]' '[:lower:]')
LINT_ROOT := $(shell dirname $(realpath $(firstword $(MAKEFILE_LIST))))
# shellcheck and hadolint lack arm64 native binaries: rely on x86-64 emulation
ifeq ($(LINT_OS),Darwin)
ifeq ($(LINT_ARCH),arm64)
LINT_ARCH=x86_64
endif
endif
LINTERS :=
FIXERS :=
SHELLCHECK_VERSION ?= v0.8.0
SHELLCHECK_BIN := out/linters/shellcheck-$(SHELLCHECK_VERSION)-$(LINT_ARCH)
$(SHELLCHECK_BIN):
mkdir -p out/linters
rm -rf out/linters/shellcheck-*
curl -sSfL https://github.com/koalaman/shellcheck/releases/download/$(SHELLCHECK_VERSION)/shellcheck-$(SHELLCHECK_VERSION).$(LINT_OS_LOWER).$(LINT_ARCH).tar.xz | tar -C out/linters -xJf -
mv out/linters/shellcheck-$(SHELLCHECK_VERSION)/shellcheck $@
rm -rf out/linters/shellcheck-$(SHELLCHECK_VERSION)/shellcheck
LINTERS += shellcheck-lint
shellcheck-lint: $(SHELLCHECK_BIN)
$(SHELLCHECK_BIN) $(shell find . -name "*.sh")
FIXERS += shellcheck-fix
shellcheck-fix: $(SHELLCHECK_BIN)
$(SHELLCHECK_BIN) $(shell find . -name "*.sh") -f diff | { read -t 1 line || exit 0; { echo "$$line" && cat; } | git apply -p2; }
GOLANGCI_LINT_CONFIG := $(LINT_ROOT)/.golangci.yml
GOLANGCI_LINT_VERSION ?= v1.43.0
GOLANGCI_LINT_BIN := out/linters/golangci-lint-$(GOLANGCI_LINT_VERSION)-$(LINT_ARCH)
$(GOLANGCI_LINT_BIN):
mkdir -p out/linters
rm -rf out/linters/golangci-lint-*
curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b out/linters $(GOLANGCI_LINT_VERSION)
mv out/linters/golangci-lint $@
LINTERS += golangci-lint-lint
golangci-lint-lint: $(GOLANGCI_LINT_BIN)
find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLINT_CONFIG)" \;
FIXERS += golangci-lint-fix
golangci-lint-fix: $(GOLANGCI_LINT_BIN)
find . -name go.mod -execdir "$(GOLANGCI_LINT_BIN)" run -c "$(GOLINT_CONFIG)" --fix \;
YAMLLINT_VERSION ?= 1.26.3
YAMLLINT_ROOT := out/linters/yamllint-$(YAMLLINT_VERSION)
YAMLLINT_BIN := $(YAMLLINT_ROOT)/dist/bin/yamllint
$(YAMLLINT_BIN):
mkdir -p out/linters
rm -rf out/linters/yamllint-*
curl -sSfL https://github.com/adrienverge/yamllint/archive/refs/tags/v$(YAMLLINT_VERSION).tar.gz | tar -C out/linters -zxf -
cd $(YAMLLINT_ROOT) && pip3 install --target dist .
LINTERS += yamllint-lint
yamllint-lint: $(YAMLLINT_BIN)
PYTHONPATH=$(YAMLLINT_ROOT)/dist $(YAMLLINT_ROOT)/dist/bin/yamllint .
.PHONY: _lint $(LINTERS)
_lint: $(LINTERS)
.PHONY: fix $(FIXERS)
fix: $(FIXERS)
# END: lint-install -makefile lint.mk .

49
vendor/github.com/mistifyio/go-zfs/v3/rules.mk generated vendored Normal file
View file

@ -0,0 +1,49 @@
# Only use the recipes defined in these makefiles
MAKEFLAGS += --no-builtin-rules
.SUFFIXES:
# Delete target files if there's an error
# This avoids a failure to then skip building on next run if the output is created by shell redirection for example
# Not really necessary for now, but just good to have already if it becomes necessary later.
.DELETE_ON_ERROR:
# Treat the whole recipe as a one shell script/invocation instead of one-per-line
.ONESHELL:
# Use bash instead of plain sh
SHELL := bash
.SHELLFLAGS := -o pipefail -euc
version := $(shell git rev-parse --short HEAD)
tag := $(shell git tag --points-at HEAD)
ifneq (,$(tag))
version := $(tag)-$(version)
endif
LDFLAGS := -ldflags "-X main.version=$(version)"
export CGO_ENABLED := 0
ifeq ($(origin GOBIN), undefined)
GOBIN := ${PWD}/bin
export GOBIN
PATH := ${GOBIN}:${PATH}
export PATH
endif
toolsBins := $(addprefix bin/,$(notdir $(shell grep '^\s*_' tooling/tools.go | awk -F'"' '{print $$2}')))
# installs cli tools defined in tools.go
$(toolsBins): tooling/go.mod tooling/go.sum tooling/tools.go
$(toolsBins): CMD=$(shell awk -F'"' '/$(@F)"/ {print $$2}' tooling/tools.go)
$(toolsBins):
cd tooling && go install $(CMD)
.PHONY: gofumpt
gofumpt: bin/gofumpt
gofumpt -s -d .
gofumpt-fix: bin/gofumpt
gofumpt -s -w .
.PHONY: prettier prettier-fix
prettier:
prettier --list-different --ignore-path .gitignore .
prettier-fix:
prettier --write --ignore-path .gitignore .

26
vendor/github.com/mistifyio/go-zfs/v3/shell.nix generated vendored Normal file
View file

@ -0,0 +1,26 @@
let _pkgs = import <nixpkgs> { };
in { pkgs ? import (_pkgs.fetchFromGitHub {
owner = "NixOS";
repo = "nixpkgs";
#branch@date: 21.11@2022-02-13
rev = "560ad8a2f89586ab1a14290f128ad6a393046065";
sha256 = "0s0dv1clfpjyzy4p6ywxvzmwx9ddbr2yl77jf1wqdbr0x1206hb8";
}) { } }:
with pkgs;
mkShell {
buildInputs = [
git
gnumake
gnused
go
nixfmt
nodePackages.prettier
python3Packages.pip
python3Packages.setuptools
rufo
shfmt
vagrant
];
}

View file

@ -21,7 +21,6 @@ type command struct {
}
func (c *command) Run(arg ...string) ([][]string, error) {
cmd := exec.Command(c.Command, arg...)
var stdout, stderr bytes.Buffer
@ -34,24 +33,24 @@ func (c *command) Run(arg ...string) ([][]string, error) {
if c.Stdin != nil {
cmd.Stdin = c.Stdin
}
cmd.Stderr = &stderr
id := uuid.New().String()
joinedArgs := strings.Join(cmd.Args, " ")
joinedArgs := cmd.Path
if len(cmd.Args) > 1 {
joinedArgs = strings.Join(append([]string{cmd.Path}, cmd.Args[1:]...), " ")
}
logger.Log([]string{"ID:" + id, "START", joinedArgs})
err := cmd.Run()
logger.Log([]string{"ID:" + id, "FINISH"})
if err != nil {
if err := cmd.Run(); err != nil {
return nil, &Error{
Err: err,
Debug: strings.Join([]string{cmd.Path, joinedArgs[1:]}, " "),
Debug: joinedArgs,
Stderr: stderr.String(),
}
}
logger.Log([]string{"ID:" + id, "FINISH"})
// assume if you passed in something for stdout, that you know what to do with it
if c.Stdout != nil {
@ -60,12 +59,12 @@ func (c *command) Run(arg ...string) ([][]string, error) {
lines := strings.Split(stdout.String(), "\n")
//last line is always blank
// last line is always blank
lines = lines[0 : len(lines)-1]
output := make([][]string, len(lines))
for i, l := range lines {
output[i] = strings.Fields(l)
output[i] = strings.Split(l, "\t")
}
return output, nil
@ -92,33 +91,33 @@ func setUint(field *uint64, value string) error {
return nil
}
func (ds *Dataset) parseLine(line []string) error {
func (d *Dataset) parseLine(line []string) error {
var err error
if len(line) != len(dsPropList) {
return errors.New("Output does not match what is expected on this platform")
return errors.New("output does not match what is expected on this platform")
}
setString(&ds.Name, line[0])
setString(&ds.Origin, line[1])
setString(&d.Name, line[0])
setString(&d.Origin, line[1])
if err = setUint(&ds.Used, line[2]); err != nil {
if err = setUint(&d.Used, line[2]); err != nil {
return err
}
if err = setUint(&ds.Avail, line[3]); err != nil {
if err = setUint(&d.Avail, line[3]); err != nil {
return err
}
setString(&ds.Mountpoint, line[4])
setString(&ds.Compression, line[5])
setString(&ds.Type, line[6])
setString(&d.Mountpoint, line[4])
setString(&d.Compression, line[5])
setString(&d.Type, line[6])
if err = setUint(&ds.Volsize, line[7]); err != nil {
if err = setUint(&d.Volsize, line[7]); err != nil {
return err
}
if err = setUint(&ds.Quota, line[8]); err != nil {
if err = setUint(&d.Quota, line[8]); err != nil {
return err
}
if err = setUint(&ds.Referenced, line[9]); err != nil {
if err = setUint(&d.Referenced, line[9]); err != nil {
return err
}
@ -126,17 +125,13 @@ func (ds *Dataset) parseLine(line []string) error {
return nil
}
if err = setUint(&ds.Written, line[10]); err != nil {
if err = setUint(&d.Written, line[10]); err != nil {
return err
}
if err = setUint(&ds.Logicalused, line[11]); err != nil {
if err = setUint(&d.Logicalused, line[11]); err != nil {
return err
}
if err = setUint(&ds.Usedbydataset, line[12]); err != nil {
return err
}
return nil
return setUint(&d.Usedbydataset, line[12])
}
/*
@ -156,12 +151,12 @@ func unescapeFilepath(path string) (string, error) {
for i := 0; i < llen; {
if path[i] == '\\' {
if llen < i+4 {
return "", fmt.Errorf("Invalid octal code: too short")
return "", fmt.Errorf("invalid octal code: too short")
}
octalCode := path[(i + 1):(i + 4)]
val, err := strconv.ParseUint(octalCode, 8, 8)
if err != nil {
return "", fmt.Errorf("Invalid octal code: %v", err)
return "", fmt.Errorf("invalid octal code: %w", err)
}
buf = append(buf, byte(val))
i += 4
@ -179,6 +174,7 @@ var changeTypeMap = map[string]ChangeType{
"M": Modified,
"R": Renamed,
}
var inodeTypeMap = map[string]InodeType{
"B": BlockDevice,
"C": CharacterDevice,
@ -191,51 +187,51 @@ var inodeTypeMap = map[string]InodeType{
"F": File,
}
// matches (+1) or (-1)
var referenceCountRegex = regexp.MustCompile("\\(([+-]\\d+?)\\)")
// matches (+1) or (-1).
var referenceCountRegex = regexp.MustCompile(`\(([+-]\d+?)\)`)
func parseReferenceCount(field string) (int, error) {
matches := referenceCountRegex.FindStringSubmatch(field)
if matches == nil {
return 0, fmt.Errorf("Regexp does not match")
return 0, fmt.Errorf("regexp does not match")
}
return strconv.Atoi(matches[1])
}
func parseInodeChange(line []string) (*InodeChange, error) {
llen := len(line)
llen := len(line) // nolint:ifshort // llen *is* actually used
if llen < 1 {
return nil, fmt.Errorf("Empty line passed")
return nil, fmt.Errorf("empty line passed")
}
changeType := changeTypeMap[line[0]]
if changeType == 0 {
return nil, fmt.Errorf("Unknown change type '%s'", line[0])
return nil, fmt.Errorf("unknown change type '%s'", line[0])
}
switch changeType {
case Renamed:
if llen != 4 {
return nil, fmt.Errorf("Mismatching number of fields: expect 4, got: %d", llen)
return nil, fmt.Errorf("mismatching number of fields: expect 4, got: %d", llen)
}
case Modified:
if llen != 4 && llen != 3 {
return nil, fmt.Errorf("Mismatching number of fields: expect 3..4, got: %d", llen)
return nil, fmt.Errorf("mismatching number of fields: expect 3..4, got: %d", llen)
}
default:
if llen != 3 {
return nil, fmt.Errorf("Mismatching number of fields: expect 3, got: %d", llen)
return nil, fmt.Errorf("mismatching number of fields: expect 3, got: %d", llen)
}
}
inodeType := inodeTypeMap[line[1]]
if inodeType == 0 {
return nil, fmt.Errorf("Unknown inode type '%s'", line[1])
return nil, fmt.Errorf("unknown inode type '%s'", line[1])
}
path, err := unescapeFilepath(line[2])
if err != nil {
return nil, fmt.Errorf("Failed to parse filename: %v", err)
return nil, fmt.Errorf("failed to parse filename: %w", err)
}
var newPath string
@ -244,13 +240,13 @@ func parseInodeChange(line []string) (*InodeChange, error) {
case Renamed:
newPath, err = unescapeFilepath(line[3])
if err != nil {
return nil, fmt.Errorf("Failed to parse filename: %v", err)
return nil, fmt.Errorf("failed to parse filename: %w", err)
}
case Modified:
if llen == 4 {
referenceCount, err = parseReferenceCount(line[3])
if err != nil {
return nil, fmt.Errorf("Failed to parse reference count: %v", err)
return nil, fmt.Errorf("failed to parse reference count: %w", err)
}
}
default:
@ -266,18 +262,19 @@ func parseInodeChange(line []string) (*InodeChange, error) {
}, nil
}
// example input
//M / /testpool/bar/
//+ F /testpool/bar/hello.txt
//M / /testpool/bar/hello.txt (+1)
//M / /testpool/bar/hello-hardlink
// example input for parseInodeChanges
// M / /testpool/bar/
// + F /testpool/bar/hello.txt
// M / /testpool/bar/hello.txt (+1)
// M / /testpool/bar/hello-hardlink
func parseInodeChanges(lines [][]string) ([]*InodeChange, error) {
changes := make([]*InodeChange, len(lines))
for i, line := range lines {
c, err := parseInodeChange(line)
if err != nil {
return nil, fmt.Errorf("Failed to parse line %d of zfs diff: %v, got: '%s'", i, err, line)
return nil, fmt.Errorf("failed to parse line %d of zfs diff: %w, got: '%s'", i, err, line)
}
changes[i] = c
}
@ -290,7 +287,7 @@ func listByType(t, filter string) ([]*Dataset, error) {
if filter != "" {
args = append(args, filter)
}
out, err := zfs(args...)
out, err := zfsOutput(args...)
if err != nil {
return nil, err
}

View file

@ -0,0 +1,19 @@
//go:build !solaris
// +build !solaris
package zfs
import "strings"
var (
// List of ZFS properties to retrieve from zfs list command on a non-Solaris platform.
dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced", "written", "logicalused", "usedbydataset"}
dsPropListOptions = strings.Join(dsPropList, ",")
// List of Zpool properties to retrieve from zpool list command on a non-Solaris platform.
zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio", "fragmentation", "freeing", "leaked"}
zpoolPropListOptions = strings.Join(zpoolPropList, ",")
zpoolArgs = []string{"get", "-Hp", zpoolPropListOptions}
)

19
vendor/github.com/mistifyio/go-zfs/v3/utils_solaris.go generated vendored Normal file
View file

@ -0,0 +1,19 @@
//go:build solaris
// +build solaris
package zfs
import "strings"
var (
// List of ZFS properties to retrieve from zfs list command on a Solaris platform
dsPropList = []string{"name", "origin", "used", "available", "mountpoint", "compression", "type", "volsize", "quota", "referenced"}
dsPropListOptions = strings.Join(dsPropList, ",")
// List of Zpool properties to retrieve from zpool list command on a non-Solaris platform
zpoolPropList = []string{"name", "health", "allocated", "size", "free", "readonly", "dedupratio"}
zpoolPropListOptions = strings.Join(zpoolPropList, ",")
zpoolArgs = []string{"get", "-Hp", zpoolPropListOptions}
)

View file

@ -9,19 +9,18 @@ import (
"strings"
)
// ZFS dataset types, which can indicate if a dataset is a filesystem,
// snapshot, or volume.
// 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.
// 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:
// http://www.freebsd.org/cgi/man.cgi?zfs(8).
// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html.
type Dataset struct {
Name string
Origin string
@ -38,10 +37,10 @@ type Dataset struct {
Referenced uint64
}
// InodeType is the type of inode as reported by Diff
// InodeType is the type of inode as reported by Diff.
type InodeType int
// Types of Inodes
// Types of Inodes.
const (
_ = iota // 0 == unknown type
BlockDevice InodeType = iota
@ -55,10 +54,10 @@ const (
File
)
// ChangeType is the type of inode change as reported by Diff
// ChangeType is the type of inode change as reported by Diff.
type ChangeType int
// Types of Changes
// Types of Changes.
const (
_ = iota // 0 == unknown type
Removed ChangeType = iota
@ -67,10 +66,10 @@ const (
Renamed
)
// DestroyFlag is the options flag passed to Destroy
// DestroyFlag is the options flag passed to Destroy.
type DestroyFlag int
// Valid destroy options
// Valid destroy options.
const (
DestroyDefault DestroyFlag = 1 << iota
DestroyRecursive = 1 << iota
@ -79,7 +78,7 @@ const (
DestroyForceUmount = 1 << iota
)
// InodeChange represents a change as reported by Diff
// InodeChange represents a change as reported by Diff.
type InodeChange struct {
Change ChangeType
Type InodeType
@ -88,65 +87,65 @@ type InodeChange struct {
ReferenceCountChange int
}
// Logger can be used to log commands/actions
// Logger can be used to log commands/actions.
type Logger interface {
Log(cmd []string)
}
type defaultLogger struct{}
func (*defaultLogger) Log(cmd []string) {
return
func (*defaultLogger) Log([]string) {
}
var logger Logger = &defaultLogger{}
// SetLogger set a log handler to log all commands including arguments before
// they are executed
// 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 zfs(arg ...string) ([][]string, error) {
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.
// 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.
// 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.
// 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.
// 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.
// 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("list", "-Hp", "-o", dsPropListOptions, name)
out, err := zfsOutput("list", "-Hp", "-o", dsPropListOptions, name)
if err != nil {
return nil, err
}
@ -174,8 +173,7 @@ func (d *Dataset) Clone(dest string, properties map[string]string) (*Dataset, er
args = append(args, propsSlice(properties)...)
}
args = append(args, []string{d.Name, dest}...)
_, err := zfs(args...)
if err != nil {
if err := zfs(args...); err != nil {
return nil, err
}
return GetDataset(dest)
@ -192,8 +190,7 @@ func (d *Dataset) Unmount(force bool) (*Dataset, error) {
args = append(args, "-f")
}
args = append(args, d.Name)
_, err := zfs(args...)
if err != nil {
if err := zfs(args...); err != nil {
return nil, err
}
return GetDataset(d.Name)
@ -214,20 +211,17 @@ func (d *Dataset) Mount(overlay bool, options []string) (*Dataset, error) {
args = append(args, strings.Join(options, ","))
}
args = append(args, d.Name)
_, err := zfs(args...)
if err != nil {
if err := zfs(args...); 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.
// 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}
_, err := c.Run("receive", name)
if err != nil {
if _, err := c.Run("receive", name); err != nil {
return nil, err
}
return GetDataset(name)
@ -245,10 +239,21 @@ func (d *Dataset) SendSnapshot(output io.Writer) error {
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 here:
// https://www.freebsd.org/cgi/man.cgi?zfs(8).
// 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"
@ -259,17 +264,15 @@ func CreateVolume(name string, size uint64, properties map[string]string) (*Data
args = append(args, propsSlice(properties)...)
}
args = append(args, name)
_, err := zfs(args...)
if err != nil {
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.
// 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"
@ -290,25 +293,26 @@ func (d *Dataset) Destroy(flags DestroyFlag) error {
}
args = append(args, d.Name)
_, err := zfs(args...)
err := zfs(args...)
return err
}
// SetProperty sets a ZFS property on the receiving dataset.
// A full list of available ZFS properties may be found here:
// https://www.freebsd.org/cgi/man.cgi?zfs(8).
//
// 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)
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 here:
// https://www.freebsd.org/cgi/man.cgi?zfs(8).
// 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 := zfs("get", "-H", key, d.Name)
out, err := zfsOutput("get", "-H", key, d.Name)
if err != nil {
return "", err
}
@ -317,7 +321,7 @@ func (d *Dataset) GetProperty(key string) (string, error) {
}
// Rename renames a dataset.
func (d *Dataset) Rename(name string, createParent bool, recursiveRenameSnapshots bool) (*Dataset, error) {
func (d *Dataset) Rename(name string, createParent, recursiveRenameSnapshots bool) (*Dataset, error) {
args := make([]string, 3, 5)
args[0] = "rename"
args[1] = d.Name
@ -328,8 +332,7 @@ func (d *Dataset) Rename(name string, createParent bool, recursiveRenameSnapshot
if recursiveRenameSnapshots {
args = append(args, "-r")
}
_, err := zfs(args...)
if err != nil {
if err := zfs(args...); err != nil {
return d, err
}
@ -341,10 +344,10 @@ 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 here:
// https://www.freebsd.org/cgi/man.cgi?zfs(8).
// 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"
@ -354,16 +357,14 @@ func CreateFilesystem(name string, properties map[string]string) (*Dataset, erro
}
args = append(args, name)
_, err := zfs(args...)
if err != nil {
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.
// 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"
@ -372,17 +373,15 @@ func (d *Dataset) Snapshot(name string, recursive bool) (*Dataset, error) {
}
snapName := fmt.Sprintf("%s@%s", d.Name, name)
args = append(args, snapName)
_, err := zfs(args...)
if err != nil {
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.
// 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 {
@ -396,13 +395,12 @@ func (d *Dataset) Rollback(destroyMoreRecent bool) error {
}
args = append(args, d.Name)
_, err := zfs(args...)
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.
// 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 {
@ -414,7 +412,7 @@ func (d *Dataset) Children(depth uint64) ([]*Dataset, error) {
args = append(args, "-t", "all", "-Hp", "-o", dsPropListOptions)
args = append(args, d.Name)
out, err := zfs(args...)
out, err := zfsOutput(args...)
if err != nil {
return nil, err
}
@ -436,11 +434,10 @@ func (d *Dataset) Children(depth uint64) ([]*Dataset, error) {
}
// 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.
// 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 := zfs(args...)
args := []string{"diff", "-FH", snapshot, d.Name}
out, err := zfsOutput(args...)
if err != nil {
return nil, err
}

View file

@ -1,8 +1,9 @@
package zfs
// ZFS zpool states, which can indicate if a pool is online, offline,
// degraded, etc. More information regarding zpool states can be found here:
// https://docs.oracle.com/cd/E19253-01/819-5461/gamno/index.html.
// ZFS zpool states, which can indicate if a pool is online, offline, degraded, etc.
//
// More information regarding zpool states can be found in the ZFS manual:
// https://openzfs.github.io/openzfs-docs/man/7/zpoolconcepts.7.html#Device_Failure_and_Recovery
const (
ZpoolOnline = "ONLINE"
ZpoolDegraded = "DEGRADED"
@ -12,8 +13,8 @@ const (
ZpoolRemoved = "REMOVED"
)
// Zpool is a ZFS zpool. A pool is a top-level structure in ZFS, and can
// contain many descendent datasets.
// 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
@ -27,8 +28,14 @@ type Zpool struct {
DedupRatio float64
}
// zpool is a helper function to wrap typical calls to zpool and ignores stdout.
func zpool(arg ...string) error {
_, err := zpoolOutput(arg...)
return err
}
// zpool is a helper function to wrap typical calls to zpool.
func zpool(arg ...string) ([][]string, error) {
func zpoolOutput(arg ...string) ([][]string, error) {
c := command{Command: "zpool"}
return c.Run(arg...)
}
@ -37,14 +44,11 @@ func zpool(arg ...string) ([][]string, error) {
func GetZpool(name string) (*Zpool, error) {
args := zpoolArgs
args = append(args, name)
out, err := zpool(args...)
out, err := zpoolOutput(args...)
if err != nil {
return nil, err
}
// there is no -H
out = out[1:]
z := &Zpool{Name: name}
for _, line := range out {
if err := z.parseLine(line); err != nil {
@ -65,10 +69,11 @@ func (z *Zpool) Snapshots() ([]*Dataset, error) {
return Snapshots(z.Name)
}
// CreateZpool creates a new ZFS zpool with the specified name, properties,
// and optional arguments.
// A full list of available ZFS properties and command-line arguments may be
// found here: https://www.freebsd.org/cgi/man.cgi?zfs(8).
// CreateZpool creates a new ZFS zpool with the specified name, properties, and optional arguments.
//
// A full list of available ZFS properties and command-line arguments may be found in the ZFS manual:
// https://openzfs.github.io/openzfs-docs/man/7/zfsprops.7.html.
// https://openzfs.github.io/openzfs-docs/man/8/zpool-create.8.html
func CreateZpool(name string, properties map[string]string, args ...string) (*Zpool, error) {
cli := make([]string, 1, 4)
cli[0] = "create"
@ -77,8 +82,7 @@ func CreateZpool(name string, properties map[string]string, args ...string) (*Zp
}
cli = append(cli, name)
cli = append(cli, args...)
_, err := zpool(cli...)
if err != nil {
if err := zpool(cli...); err != nil {
return nil, err
}
@ -87,14 +91,14 @@ func CreateZpool(name string, properties map[string]string, args ...string) (*Zp
// Destroy destroys a ZFS zpool by name.
func (z *Zpool) Destroy() error {
_, err := zpool("destroy", z.Name)
err := zpool("destroy", z.Name)
return err
}
// ListZpools list all ZFS zpools accessible on the current system.
func ListZpools() ([]*Zpool, error) {
args := []string{"list", "-Ho", "name"}
out, err := zpool(args...)
out, err := zpoolOutput(args...)
if err != nil {
return nil, err
}

6
vendor/modules.txt vendored
View file

@ -570,9 +570,9 @@ github.com/matttproud/golang_protobuf_extensions/pbutil
# github.com/miekg/dns v1.1.43
## explicit; go 1.14
github.com/miekg/dns
# github.com/mistifyio/go-zfs v2.1.2-0.20190413222219-f784269be439+incompatible
## explicit
github.com/mistifyio/go-zfs
# github.com/mistifyio/go-zfs/v3 v3.0.1
## explicit; go 1.14
github.com/mistifyio/go-zfs/v3
# github.com/mitchellh/hashstructure/v2 v2.0.2
## explicit; go 1.14
github.com/mitchellh/hashstructure/v2