Skip to content

Commit 848a26a

Browse files
committed
fix: add label to divide clones by pool name (#156)
1 parent 0b1f734 commit 848a26a

File tree

7 files changed

+133
-21
lines changed

7 files changed

+133
-21
lines changed

pkg/services/provision/databases/postgres/postgres.go

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -115,23 +115,20 @@ func Start(r runners.Runner, c *resources.AppConfig) error {
115115
func Stop(r runners.Runner, c *resources.AppConfig) error {
116116
log.Dbg("Stopping Postgres container...")
117117

118-
_, err := docker.RemoveContainer(r, c)
119-
if err != nil {
118+
if _, err := docker.RemoveContainer(r, c); err != nil {
120119
return errors.Wrap(err, "failed to remove container")
121120
}
122121

123-
//err = os.RemoveAll(c.UnixSocketCloneDir)
124-
_, err = r.Run("rm -rf " + c.UnixSocketCloneDir + "/*")
125-
if err != nil {
122+
if _, err := r.Run("rm -rf " + c.UnixSocketCloneDir + "/*"); err != nil {
126123
return errors.Wrap(err, "failed to clean unix socket directory")
127124
}
128125

129126
return nil
130127
}
131128

132-
// List gets started Postgres instances.
133-
func List(r runners.Runner, prefix string) ([]string, error) {
134-
return docker.ListContainers(r)
129+
// List gets started Postgres instances filtered by label.
130+
func List(r runners.Runner, label string) ([]string, error) {
131+
return docker.ListContainers(r, label)
135132
}
136133

137134
func pgctlPromote(r runners.Runner, c *resources.AppConfig) (string, error) {

pkg/services/provision/docker/docker.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ func RunContainer(r runners.Runner, c *resources.AppConfig) (string, error) {
4747
"--publish " + strconv.Itoa(int(c.Port)) + ":5432 " +
4848
"--env PGDATA=" + c.Datadir + " " + socketVolume + " " +
4949
"--label " + labelClone + " " +
50+
"--label " + c.ClonePool + " " +
5051
c.DockerImage + " -k " + c.UnixSocketCloneDir
5152

5253
return r.Run(dockerRunCmd, true)
@@ -79,10 +80,9 @@ func RemoveContainer(r runners.Runner, c *resources.AppConfig) (string, error) {
7980
}
8081

8182
// ListContainers lists containers.
82-
func ListContainers(r runners.Runner) ([]string, error) {
83-
dockerListCmd := "docker container ls " +
84-
"--filter \"label=" + labelClone + "\" " +
85-
"--all --quiet"
83+
func ListContainers(r runners.Runner, clonePool string) ([]string, error) {
84+
dockerListCmd := fmt.Sprintf(`docker container ls --filter "label=%s" --filter "label=%s" --all --quiet`,
85+
labelClone, clonePool)
8686

8787
out, err := r.Run(dockerListCmd, true)
8888
if err != nil {

pkg/services/provision/mode_local.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -418,7 +418,7 @@ func (j *provisionModeLocal) setPortStatus(port uint, bind bool) error {
418418
}
419419

420420
func (j *provisionModeLocal) stopAllSessions() error {
421-
instances, err := postgres.List(j.runner, ClonePrefix)
421+
instances, err := postgres.List(j.runner, j.config.Options.ClonePool)
422422
if err != nil {
423423
return errors.Wrap(err, "failed to list containers")
424424
}
@@ -464,6 +464,7 @@ func (j *provisionModeLocal) getAppConfig(name string, port uint) *resources.App
464464

465465
appConfig := &resources.AppConfig{
466466
CloneName: name,
467+
ClonePool: j.config.Options.ClonePool,
467468
DockerImage: j.config.Options.DockerImage,
468469
Datadir: path.Clean(j.config.Options.ClonesMountDir + name),
469470
Host: host,

pkg/services/provision/resources/appconfig.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ package resources
77
// AppConfig currently stores Postgres configuration (other application in the future too).
88
type AppConfig struct {
99
CloneName string
10+
ClonePool string
1011

1112
DockerImage string
1213

pkg/services/provision/thinclones/manager_zfs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ func (m *managerZFS) DestroyClone(name string) error {
6363
}
6464

6565
func (m *managerZFS) ListClonesNames() ([]string, error) {
66-
return zfs.ListClones(m.runner, m.config.ClonePrefix)
66+
return zfs.ListClones(m.runner, m.config.Pool, m.config.ClonePrefix)
6767
}
6868

6969
func (m *managerZFS) GetSessionState(name string) (*resources.SessionState, error) {

pkg/services/provision/thinclones/zfs/zfs.go

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ package zfs
77

88
import (
99
"fmt"
10-
"regexp"
1110
"strconv"
1211
"strings"
1312
"time"
@@ -171,17 +170,26 @@ func CloneExists(r runners.Runner, name string) (bool, error) {
171170
}
172171

173172
// ListClones lists ZFS clones.
174-
func ListClones(r runners.Runner, prefix string) ([]string, error) {
175-
listZfsClonesCmd := "zfs list"
176-
177-
re := regexp.MustCompile(fmt.Sprintf(`(%s[0-9]+)`, prefix))
173+
func ListClones(r runners.Runner, pool, prefix string) ([]string, error) {
174+
listZfsClonesCmd := "zfs list -o name -H"
178175

179-
out, err := r.Run(listZfsClonesCmd, false)
176+
cmdOutput, err := r.Run(listZfsClonesCmd, false)
180177
if err != nil {
181178
return nil, errors.Wrap(err, "failed to list clones")
182179
}
183180

184-
return util.Unique(re.FindAllString(out, -1)), nil
181+
cloneNames := []string{}
182+
poolPrefix := pool + "/"
183+
clonePoolPrefix := pool + "/" + prefix
184+
lines := strings.Split(strings.TrimSpace(cmdOutput), "\n")
185+
186+
for _, line := range lines {
187+
if strings.HasPrefix(line, clonePoolPrefix) {
188+
cloneNames = append(cloneNames, strings.TrimPrefix(line, poolPrefix))
189+
}
190+
}
191+
192+
return util.Unique(cloneNames), nil
185193
}
186194

187195
// CreateSnapshot creates ZFS snapshot.
Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
package zfs
2+
3+
import (
4+
"errors"
5+
"testing"
6+
7+
"github.com/stretchr/testify/assert"
8+
"github.com/stretchr/testify/require"
9+
)
10+
11+
type runnerMock struct {
12+
cmdOutput string
13+
err error
14+
}
15+
16+
func (r runnerMock) Run(string, ...bool) (string, error) {
17+
return r.cmdOutput, r.err
18+
}
19+
20+
func TestListClones(t *testing.T) {
21+
const (
22+
pool = "datastore"
23+
clonePrefix = "dblab_clone_"
24+
)
25+
26+
testCases := []struct {
27+
caseName string
28+
cmdOutput string
29+
cloneNames []string
30+
}{
31+
{
32+
caseName: "empty output",
33+
cloneNames: []string{},
34+
},
35+
{
36+
caseName: "single clone",
37+
cmdOutput: `datastore/clone_pre_20200831030000
38+
datastore/dblab_clone_6000
39+
`,
40+
cloneNames: []string{
41+
"dblab_clone_6000",
42+
},
43+
},
44+
{
45+
caseName: "multiple clones",
46+
cmdOutput: `datastore/clone_pre_20200831030000
47+
datastore/dblab_clone_6000
48+
datastore/dblab_clone_6001
49+
`,
50+
cloneNames: []string{
51+
"dblab_clone_6000",
52+
"dblab_clone_6001",
53+
},
54+
},
55+
{
56+
caseName: "clone duplicate",
57+
cmdOutput: `datastore/clone_pre_20200831030000
58+
datastore/dblab_clone_6000
59+
datastore/dblab_clone_6000
60+
`,
61+
cloneNames: []string{
62+
"dblab_clone_6000",
63+
},
64+
},
65+
{
66+
caseName: "different pool",
67+
cmdOutput: `datastore/clone_pre_20200831030000
68+
dblab_pool/dblab_clone_6001
69+
datastore/dblab_clone_6000
70+
`,
71+
cloneNames: []string{
72+
"dblab_clone_6000",
73+
},
74+
},
75+
{
76+
caseName: "no matched clone",
77+
cmdOutput: `datastore/clone_pre_20200831030000
78+
dblab_pool/dblab_clone_6001
79+
`,
80+
cloneNames: []string{},
81+
},
82+
}
83+
84+
for _, testCase := range testCases {
85+
runner := runnerMock{
86+
cmdOutput: testCase.cmdOutput,
87+
}
88+
89+
listClones, err := ListClones(runner, pool, clonePrefix)
90+
91+
require.NoError(t, err, testCase.caseName)
92+
assert.Equal(t, testCase.cloneNames, listClones, testCase.caseName)
93+
}
94+
}
95+
96+
func TestFailedListClones(t *testing.T) {
97+
runner := runnerMock{
98+
err: errors.New("runner error"),
99+
}
100+
101+
cloneNames, err := ListClones(runner, "pool", "dblab_clone_")
102+
103+
assert.Nil(t, cloneNames)
104+
assert.EqualError(t, err, "failed to list clones: runner error")
105+
}

0 commit comments

Comments
 (0)