-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathzfs.go
101 lines (83 loc) · 1.91 KB
/
zfs.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package zfs
import (
"encoding/csv"
"errors"
"io"
"os/exec"
)
var (
// ErrInvalidOutput is returned on unparseable CLI output
ErrInvalidOutput = errors.New(`Invalid output executing command`)
)
// Client is the primary entrypoint
type Client interface {
PoolNames() ([]string, error)
Pool(name string) Pool
Datasets(pool string, kind DatasetKind) Datasets
}
// Pool allows querying pool properties
type Pool interface {
Name() string
Properties(props ...string) (PoolProperties, error)
}
// PoolProperties provides access to the properties for a pool
type PoolProperties interface {
Properties() map[string]string
}
// Datasets allows querying properties for datasets in a pool
type Datasets interface {
Pool() string
Kind() DatasetKind
Properties(props ...string) ([]DatasetProperties, error)
}
// DatasetProperties provides access to the properties for a dataset
type DatasetProperties interface {
DatasetName() string
Properties() map[string]string
}
type handler interface {
processLine(pool string, line []string) error
}
type clientImpl struct {
}
func (z clientImpl) PoolNames() ([]string, error) {
return poolNames()
}
func (z clientImpl) Pool(name string) Pool {
return newPoolImpl(name)
}
func (z clientImpl) Datasets(pool string, kind DatasetKind) Datasets {
return newDatasetsImpl(pool, kind)
}
func execute(pool string, h handler, cmd string, args ...string) error {
c := exec.Command(cmd, append(args, pool)...)
out, err := c.StdoutPipe()
if err != nil {
return err
}
r := csv.NewReader(out)
r.Comma = '\t'
r.LazyQuotes = true
r.ReuseRecord = true
r.FieldsPerRecord = 3
if err = c.Start(); err != nil {
return err
}
for {
line, err := r.Read()
if err == io.EOF {
break
}
if err != nil {
return err
}
if err = h.processLine(pool, line); err != nil {
return err
}
}
return c.Wait()
}
// New instantiates a ZFS Client
func New() Client {
return clientImpl{}
}