-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathutils.go
103 lines (89 loc) · 2.03 KB
/
utils.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
102
103
package zfs
import (
"bytes"
"context"
"fmt"
"io"
"os/exec"
"strings"
)
// List of HTTPConfig properties to retrieve from zfs list command by default
var dsPropList = []string{
PropertyName,
PropertyType,
PropertyOrigin,
PropertyUsed,
PropertyAvailable,
PropertyMounted,
PropertyMountPoint,
PropertyCompression,
PropertyVolSize,
PropertyQuota,
PropertyRefQuota,
PropertyReferenced,
PropertyWritten,
PropertyLogicalUsed,
PropertyUsedByDataset,
}
const (
fieldSeparator = "\t"
)
// zfs is a helper function to wrap typical calls to zfs that ignores stdout.
func zfs(ctx context.Context, arg ...string) error {
_, err := zfsOutput(ctx, arg...)
return err
}
// zfs is a helper function to wrap typical calls to zfs.
func zfsOutput(ctx context.Context, arg ...string) ([][]string, error) {
c := command{
cmd: Binary,
ctx: ctx,
}
return c.Run(arg...)
}
type command struct {
ctx context.Context
cmd string
stdin io.Reader
stdout io.Writer
}
func (c *command) Run(arg ...string) ([][]string, error) {
cmd := exec.CommandContext(c.ctx, c.cmd, arg...)
cmd.SysProcAttr = procAttributes()
var stdout, stderr bytes.Buffer
cmd.Stdout = c.stdout
cmd.Stderr = &stderr
if c.stdout == nil {
cmd.Stdout = &stdout
}
if c.stdin != nil {
cmd.Stdin = c.stdin
}
err := cmd.Run()
if err != nil {
return nil, createError(cmd, stderr.String(), err)
}
// assume if you passed in something for stdout, that you know what to do with it
if c.stdout != nil {
return nil, nil
}
return splitOutput(stdout.String()), nil
}
func splitOutput(out string) [][]string {
lines := strings.Split(out, "\n")
// last line is always blank
lines = lines[0 : len(lines)-1]
output := make([][]string, len(lines))
for i, l := range lines {
output[i] = strings.Split(l, fieldSeparator)
}
return output
}
func propsSlice(properties map[string]string) []string {
args := make([]string, 0, len(properties)*2)
for k, v := range properties {
args = append(args, "-o")
args = append(args, fmt.Sprintf("%s=%s", k, v))
}
return args
}