Make zfs.DatasetPath json.Marshaler and json.Unmarshaler
Had to resort to using pointers to zfs.DatasetPath everywhere... Should find a better solution for that.
This commit is contained in:
@@ -10,7 +10,7 @@ func NewDatasetPathForest() *DatasetPathForest {
|
||||
}
|
||||
}
|
||||
|
||||
func (f *DatasetPathForest) Add(p DatasetPath) {
|
||||
func (f *DatasetPathForest) Add(p *DatasetPath) {
|
||||
if len(p.comps) <= 0 {
|
||||
panic("dataset path too short. must have length > 0")
|
||||
}
|
||||
@@ -30,7 +30,7 @@ func (f *DatasetPathForest) Add(p DatasetPath) {
|
||||
}
|
||||
|
||||
type DatasetPathVisit struct {
|
||||
Path DatasetPath
|
||||
Path *DatasetPath
|
||||
// If true, the dataset referenced by Path was not in the list of datasets to traverse
|
||||
FilledIn bool
|
||||
}
|
||||
@@ -93,7 +93,7 @@ func (t *datasetPathTree) WalkTopDown(parent []string, visitor DatasetPathsVisit
|
||||
this := append(parent, t.Component)
|
||||
|
||||
thisVisit := DatasetPathVisit{
|
||||
DatasetPath{this},
|
||||
&DatasetPath{this},
|
||||
t.FilledIn,
|
||||
}
|
||||
visitChildTree := visitor(thisVisit)
|
||||
|
||||
@@ -34,7 +34,7 @@ func makeVisitRecorder() (v DatasetPathsVisitor, rec *visitRecorder) {
|
||||
return
|
||||
}
|
||||
|
||||
func buildForest(paths []DatasetPath) (f *DatasetPathForest) {
|
||||
func buildForest(paths []*DatasetPath) (f *DatasetPathForest) {
|
||||
f = NewDatasetPathForest()
|
||||
for _, p := range paths {
|
||||
f.Add(p)
|
||||
@@ -44,7 +44,7 @@ func buildForest(paths []DatasetPath) (f *DatasetPathForest) {
|
||||
|
||||
func TestDatasetPathForestWalkTopDown(t *testing.T) {
|
||||
|
||||
paths := []DatasetPath{
|
||||
paths := []*DatasetPath{
|
||||
toDatasetPath("pool1"),
|
||||
toDatasetPath("pool1/foo/bar"),
|
||||
toDatasetPath("pool1/foo/bar/looloo"),
|
||||
@@ -70,7 +70,7 @@ func TestDatasetPathForestWalkTopDown(t *testing.T) {
|
||||
|
||||
func TestDatasetPathWalkTopDownWorksUnordered(t *testing.T) {
|
||||
|
||||
paths := []DatasetPath{
|
||||
paths := []*DatasetPath{
|
||||
toDatasetPath("pool1"),
|
||||
toDatasetPath("pool1/foo/bar/looloo"),
|
||||
toDatasetPath("pool1/foo/bar"),
|
||||
|
||||
+3
-3
@@ -208,13 +208,13 @@ func ZFSListFilesystemState() (localState map[string]FilesystemState, err error)
|
||||
// move.
|
||||
//
|
||||
// TODO better solution available?
|
||||
func PlaceholderPropertyValue(p DatasetPath) string {
|
||||
func PlaceholderPropertyValue(p *DatasetPath) string {
|
||||
ps := []byte(p.ToString())
|
||||
sum := sha512.Sum512_256(ps)
|
||||
return hex.EncodeToString(sum[:])
|
||||
}
|
||||
|
||||
func IsPlaceholder(p DatasetPath, placeholderPropertyValue string) (isPlaceholder bool, err error) {
|
||||
func IsPlaceholder(p *DatasetPath, placeholderPropertyValue string) (isPlaceholder bool, err error) {
|
||||
expected := PlaceholderPropertyValue(p)
|
||||
isPlaceholder = expected == placeholderPropertyValue
|
||||
if !isPlaceholder {
|
||||
@@ -223,7 +223,7 @@ func IsPlaceholder(p DatasetPath, placeholderPropertyValue string) (isPlaceholde
|
||||
return
|
||||
}
|
||||
|
||||
func ZFSCreatePlaceholderFilesystem(p DatasetPath) (err error) {
|
||||
func ZFSCreatePlaceholderFilesystem(p *DatasetPath) (err error) {
|
||||
v := PlaceholderPropertyValue(p)
|
||||
cmd := exec.Command(ZFS_BINARY, "create",
|
||||
"-o", fmt.Sprintf("%s=%s", ZREPL_PLACEHOLDER_PROPERTY_NAME, v),
|
||||
|
||||
+4
-4
@@ -3,10 +3,10 @@ package zfs
|
||||
import "fmt"
|
||||
|
||||
type DatasetFilter interface {
|
||||
Filter(p DatasetPath) (pass bool, err error)
|
||||
Filter(p *DatasetPath) (pass bool, err error)
|
||||
}
|
||||
|
||||
func ZFSListMapping(filter DatasetFilter) (datasets []DatasetPath, err error) {
|
||||
func ZFSListMapping(filter DatasetFilter) (datasets []*DatasetPath, err error) {
|
||||
|
||||
if filter == nil {
|
||||
panic("filter must not be nil")
|
||||
@@ -15,11 +15,11 @@ func ZFSListMapping(filter DatasetFilter) (datasets []DatasetPath, err error) {
|
||||
var lines [][]string
|
||||
lines, err = ZFSList([]string{"name"}, "-r", "-t", "filesystem,volume")
|
||||
|
||||
datasets = make([]DatasetPath, 0, len(lines))
|
||||
datasets = make([]*DatasetPath, 0, len(lines))
|
||||
|
||||
for _, line := range lines {
|
||||
|
||||
var path DatasetPath
|
||||
var path *DatasetPath
|
||||
if path, err = NewDatasetPath(line[0]); err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
+3
-3
@@ -45,7 +45,7 @@ type FilesystemVersion struct {
|
||||
Creation time.Time
|
||||
}
|
||||
|
||||
func (v FilesystemVersion) ToAbsPath(p DatasetPath) string {
|
||||
func (v FilesystemVersion) ToAbsPath(p *DatasetPath) string {
|
||||
var b bytes.Buffer
|
||||
b.WriteString(p.ToString())
|
||||
b.WriteString(v.Type.DelimiterChar())
|
||||
@@ -57,7 +57,7 @@ type FilesystemVersionFilter interface {
|
||||
Filter(fsv FilesystemVersion) (accept bool, err error)
|
||||
}
|
||||
|
||||
func ZFSListFilesystemVersions(fs DatasetPath, filter FilesystemVersionFilter) (res []FilesystemVersion, err error) {
|
||||
func ZFSListFilesystemVersions(fs *DatasetPath, filter FilesystemVersionFilter) (res []FilesystemVersion, err error) {
|
||||
var fieldLines [][]string
|
||||
fieldLines, err = ZFSList(
|
||||
[]string{"name", "guid", "createtxg", "creation"},
|
||||
@@ -125,7 +125,7 @@ func ZFSListFilesystemVersions(fs DatasetPath, filter FilesystemVersionFilter) (
|
||||
return
|
||||
}
|
||||
|
||||
func ZFSDestroyFilesystemVersion(filesystem DatasetPath, version FilesystemVersion) (err error) {
|
||||
func ZFSDestroyFilesystemVersion(filesystem *DatasetPath, version FilesystemVersion) (err error) {
|
||||
|
||||
datasetPath := version.ToAbsPath(filesystem)
|
||||
|
||||
|
||||
+28
-15
@@ -3,31 +3,33 @@ package zfs
|
||||
import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/zrepl/zrepl/util"
|
||||
"io"
|
||||
"os/exec"
|
||||
"strings"
|
||||
|
||||
"github.com/zrepl/zrepl/util"
|
||||
)
|
||||
|
||||
type DatasetPath struct {
|
||||
comps []string
|
||||
}
|
||||
|
||||
func (p DatasetPath) ToString() string {
|
||||
func (p *DatasetPath) ToString() string {
|
||||
return strings.Join(p.comps, "/")
|
||||
}
|
||||
|
||||
func (p DatasetPath) Empty() bool {
|
||||
func (p *DatasetPath) Empty() bool {
|
||||
return len(p.comps) == 0
|
||||
}
|
||||
|
||||
func (p *DatasetPath) Extend(extend DatasetPath) {
|
||||
func (p *DatasetPath) Extend(extend *DatasetPath) {
|
||||
p.comps = append(p.comps, extend.comps...)
|
||||
}
|
||||
|
||||
func (p DatasetPath) HasPrefix(prefix DatasetPath) bool {
|
||||
func (p *DatasetPath) HasPrefix(prefix *DatasetPath) bool {
|
||||
if len(prefix.comps) > len(p.comps) {
|
||||
return false
|
||||
}
|
||||
@@ -39,7 +41,7 @@ func (p DatasetPath) HasPrefix(prefix DatasetPath) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (p *DatasetPath) TrimPrefix(prefix DatasetPath) {
|
||||
func (p *DatasetPath) TrimPrefix(prefix *DatasetPath) {
|
||||
if !p.HasPrefix(prefix) {
|
||||
return
|
||||
}
|
||||
@@ -64,7 +66,7 @@ func (p *DatasetPath) TrimNPrefixComps(n int) {
|
||||
|
||||
}
|
||||
|
||||
func (p DatasetPath) Equal(q DatasetPath) bool {
|
||||
func (p DatasetPath) Equal(q *DatasetPath) bool {
|
||||
if len(p.comps) != len(q.comps) {
|
||||
return false
|
||||
}
|
||||
@@ -76,17 +78,28 @@ func (p DatasetPath) Equal(q DatasetPath) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func (p DatasetPath) Length() int {
|
||||
func (p *DatasetPath) Length() int {
|
||||
return len(p.comps)
|
||||
}
|
||||
|
||||
func (p DatasetPath) Copy() (c DatasetPath) {
|
||||
func (p *DatasetPath) Copy() (c *DatasetPath) {
|
||||
c = &DatasetPath{}
|
||||
c.comps = make([]string, len(p.comps))
|
||||
copy(c.comps, p.comps)
|
||||
return
|
||||
}
|
||||
|
||||
func NewDatasetPath(s string) (p DatasetPath, err error) {
|
||||
func (p *DatasetPath) MarshalJSON() ([]byte, error) {
|
||||
return json.Marshal(p.comps)
|
||||
}
|
||||
|
||||
func (p *DatasetPath) UnmarshalJSON(b []byte) error {
|
||||
p.comps = make([]string, 0)
|
||||
return json.Unmarshal(b, &p.comps)
|
||||
}
|
||||
|
||||
func NewDatasetPath(s string) (p *DatasetPath, err error) {
|
||||
p = &DatasetPath{}
|
||||
if s == "" {
|
||||
p.comps = make([]string, 0)
|
||||
return p, nil // the empty dataset path
|
||||
@@ -104,7 +117,7 @@ func NewDatasetPath(s string) (p DatasetPath, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func toDatasetPath(s string) DatasetPath {
|
||||
func toDatasetPath(s string) *DatasetPath {
|
||||
p, err := NewDatasetPath(s)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
@@ -172,7 +185,7 @@ func ZFSList(properties []string, zfsArgs ...string) (res [][]string, err error)
|
||||
return
|
||||
}
|
||||
|
||||
func ZFSSend(fs DatasetPath, from, to *FilesystemVersion) (stream io.Reader, err error) {
|
||||
func ZFSSend(fs *DatasetPath, from, to *FilesystemVersion) (stream io.Reader, err error) {
|
||||
|
||||
args := make([]string, 0)
|
||||
args = append(args, "send")
|
||||
@@ -188,7 +201,7 @@ func ZFSSend(fs DatasetPath, from, to *FilesystemVersion) (stream io.Reader, err
|
||||
return
|
||||
}
|
||||
|
||||
func ZFSRecv(fs DatasetPath, stream io.Reader, additionalArgs ...string) (err error) {
|
||||
func ZFSRecv(fs *DatasetPath, stream io.Reader, additionalArgs ...string) (err error) {
|
||||
|
||||
args := make([]string, 0)
|
||||
args = append(args, "recv")
|
||||
@@ -226,7 +239,7 @@ func ZFSRecv(fs DatasetPath, stream io.Reader, additionalArgs ...string) (err er
|
||||
return nil
|
||||
}
|
||||
|
||||
func ZFSSet(fs DatasetPath, prop, val string) (err error) {
|
||||
func ZFSSet(fs *DatasetPath, prop, val string) (err error) {
|
||||
|
||||
if strings.ContainsRune(prop, '=') {
|
||||
panic("prop contains rune '=' which is the delimiter between property name and value")
|
||||
@@ -273,7 +286,7 @@ func ZFSDestroy(dataset string) (err error) {
|
||||
|
||||
}
|
||||
|
||||
func ZFSSnapshot(fs DatasetPath, name string, recursive bool) (err error) {
|
||||
func ZFSSnapshot(fs *DatasetPath, name string, recursive bool) (err error) {
|
||||
|
||||
snapname := fmt.Sprintf("%s@%s", fs.ToString(), name)
|
||||
cmd := exec.Command(ZFS_BINARY, "snapshot", snapname)
|
||||
|
||||
Reference in New Issue
Block a user