Skip to content

Commit 5d399b5

Browse files
committed
Improve Plugin
1 parent 757eb58 commit 5d399b5

File tree

11 files changed

+336
-23
lines changed

11 files changed

+336
-23
lines changed

.gitignore

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,38 @@
1-
*~
1+
# Binaries for programs and plugins
2+
*.exe
3+
*.exe~
4+
*.dll
5+
*.so
6+
*.dylib
27
docker-volume-moosefs
3-
*.rpm
8+
9+
# Test binary, built with `go test -c`
10+
*.test
11+
12+
# Output of the go coverage tool
13+
*.out
14+
15+
# Dependency directories (remove the comment below to include it)
16+
vendor/
17+
18+
# Plugin build artifacts
19+
plugin/rootfs/
420
*.deb
5-
obj
6-
.idea
7-
vendor/*/
21+
*.rpm
22+
obj/
23+
24+
# IDE specific files
25+
.idea/
26+
.vscode/
27+
*.swp
28+
*.swo
29+
30+
# OS generated files
31+
.DS_Store
32+
.DS_Store?
33+
._*
34+
.Spotlight-V100
35+
.Trashes
36+
ehthumbs.db
37+
Thumbs.db
38+

Makefile

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,4 +44,19 @@ deb: compile
4444
clean:
4545
rm -fr obj *.deb *.rpm docker-volume-moosefs
4646

47-
.PHONY: clean rpm-deps deb-deps fmt deps compile
47+
plugin: compile
48+
mkdir -p plugin/rootfs
49+
docker build -t moosefs-plugin-build -f plugin/Dockerfile .
50+
docker create --name tmp moosefs-plugin-build
51+
docker export tmp | tar -x -C plugin/rootfs
52+
docker rm -vf tmp
53+
docker rmi moosefs-plugin-build
54+
55+
plugin-enable:
56+
docker plugin create moosefs/docker-volume-moosefs:$(VERSION) plugin
57+
docker plugin enable moosefs/docker-volume-moosefs:$(VERSION)
58+
59+
plugin-push: plugin plugin-enable
60+
docker plugin push moosefs/docker-volume-moosefs:$(VERSION)
61+
62+
.PHONY: clean rpm-deps deb-deps fmt deps compile plugin plugin-enable plugin-push

build.sh

Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
#!/usr/bin/env bash
2+
3+
# Colors for output
4+
RED='\033[0;31m'
5+
GREEN='\033[0;32m'
6+
YELLOW='\033[1;33m'
7+
NC='\033[0m'
8+
9+
# Version
10+
VERSION="0.2.0"
11+
PLUGIN_NAME="moosefs/docker-volume-moosefs:${VERSION}"
12+
13+
# Function to print step
14+
print_step() {
15+
echo -e "${YELLOW}[*] $1${NC}"
16+
}
17+
18+
# Function to print success
19+
print_success() {
20+
echo -e "${GREEN}[+] $1${NC}"
21+
}
22+
23+
# Function to print error and exit
24+
print_error() {
25+
echo -e "${RED}[-] $1${NC}"
26+
exit 1
27+
}
28+
29+
# Clean previous build
30+
print_step "Cleaning previous build..."
31+
rm -rf plugin/rootfs *.deb *.rpm docker-volume-moosefs obj
32+
print_success "Clean completed"
33+
34+
# Clean existing plugin if it exists
35+
print_step "Checking for existing plugin..."
36+
if docker plugin inspect ${PLUGIN_NAME} >/dev/null 2>&1; then
37+
print_step "Disabling existing plugin..."
38+
docker plugin disable ${PLUGIN_NAME} >/dev/null 2>&1
39+
print_step "Removing existing plugin..."
40+
docker plugin rm ${PLUGIN_NAME} >/dev/null 2>&1
41+
fi
42+
print_success "Plugin cleanup completed"
43+
44+
# Build Go binary
45+
print_step "Building Go binary..."
46+
go build || print_error "Go build failed"
47+
print_success "Binary built successfully"
48+
49+
# Create plugin
50+
print_step "Creating Docker plugin..."
51+
mkdir -p plugin/rootfs || print_error "Failed to create plugin directory"
52+
53+
# Build Docker image
54+
print_step "Building Docker image..."
55+
docker build -t moosefs-plugin-build -f plugin/Dockerfile . || print_error "Docker build failed"
56+
57+
print_step "Creating temporary container..."
58+
docker create --name tmp moosefs-plugin-build || print_error "Failed to create temporary container"
59+
60+
print_step "Extracting rootfs..."
61+
docker export tmp | tar -x -C plugin/rootfs || print_error "Failed to extract rootfs"
62+
63+
print_step "Cleaning up temporary container..."
64+
docker rm -vf tmp
65+
docker rmi moosefs-plugin-build
66+
67+
# Create and enable plugin
68+
print_step "Creating Docker plugin..."
69+
docker plugin create ${PLUGIN_NAME} plugin || print_error "Failed to create plugin"
70+
71+
print_step "Enabling Docker plugin..."
72+
docker plugin enable ${PLUGIN_NAME} || print_error "Failed to enable plugin"
73+
74+
print_success "Build completed successfully!"
75+
echo -e "${GREEN}Plugin ${PLUGIN_NAME} is now ready to use${NC}"
76+
echo -e "${YELLOW}You can create a volume with:${NC}"
77+
echo -e "docker volume create -d ${PLUGIN_NAME} --name test_volume"

driver.go

Lines changed: 26 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -3,13 +3,13 @@ package main
33
import (
44
"errors"
55
"fmt"
6-
"os"
6+
"os"
77
"path"
88
"path/filepath"
99
"sync"
1010
"syscall"
1111

12-
log "github.com/Sirupsen/logrus"
12+
log "github.com/sirupsen/logrus"
1313

1414
"github.com/davecgh/go-spew/spew"
1515
"github.com/docker/go-plugins-helpers/volume"
@@ -18,7 +18,7 @@ import (
1818
// A single volume instance
1919
type moosefsMount struct {
2020
name string
21-
path string
21+
path string
2222
root string
2323
}
2424

@@ -27,16 +27,21 @@ type moosefsDriver struct {
2727
m *sync.Mutex
2828
}
2929

30-
func newMooseFSDriver(root string) moosefsDriver {
31-
d := moosefsDriver{
30+
func newMooseFSDriver(root string) (*moosefsDriver, error) {
31+
d := &moosefsDriver{
3232
mounts: make(map[string]*moosefsMount),
3333
m: &sync.Mutex{},
3434
}
35-
return d
35+
36+
if err := d.loadState(); err != nil {
37+
return nil, err
38+
}
39+
40+
return d, nil
3641
}
3742

3843
func (d moosefsDriver) Create(r *volume.CreateRequest) error {
39-
var volumeRoot string
44+
var volumeRoot string
4045

4146
d.m.Lock()
4247
defer d.m.Unlock()
@@ -45,15 +50,15 @@ func (d moosefsDriver) Create(r *volume.CreateRequest) error {
4550
volumeRoot = optsRoot
4651
} else {
4752
// Assume the default root
48-
volumeRoot = *root
53+
volumeRoot = *root
4954
}
5055

51-
volumePath := filepath.Join(volumeRoot, r.Name)
56+
volumePath := filepath.Join(volumeRoot, r.Name)
5257

53-
if err := mkdir(volumePath); err != nil {
58+
if err := mkdir(volumePath); err != nil {
5459
return err
5560
}
56-
61+
5762
if !ismoosefs(volumePath) {
5863
emsg := fmt.Sprintf("Cannot create volume %s as it's not a valid MooseFS mount", volumePath)
5964
log.Error(emsg)
@@ -66,19 +71,22 @@ func (d moosefsDriver) Create(r *volume.CreateRequest) error {
6671
return errors.New(emsg)
6772
}
6873

69-
if err := mkdir(volumePath); err != nil {
70-
return err
71-
}
7274
d.mounts[r.Name] = &moosefsMount{
7375
name: r.Name,
74-
path: volumePath,
76+
path: volumePath,
7577
root: volumeRoot,
7678
}
7779

7880
if *verbose {
7981
spew.Dump(d.mounts)
8082
}
8183

84+
if err := d.saveState(); err != nil {
85+
// If we can't save state, remove the volume from memory
86+
delete(d.mounts, r.Name)
87+
return err
88+
}
89+
8290
return nil
8391
}
8492

@@ -87,6 +95,9 @@ func (d moosefsDriver) Remove(r *volume.RemoveRequest) error {
8795
defer d.m.Unlock()
8896
if _, ok := d.mounts[r.Name]; ok {
8997
delete(d.mounts, r.Name)
98+
if err := d.saveState(); err != nil {
99+
return err
100+
}
90101
}
91102
return nil
92103
}

go.mod

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
module github.com/liberodark/docker-volume-moosefs
2+
3+
go 1.21
4+
5+
toolchain go1.23.3
6+
7+
require (
8+
github.com/davecgh/go-spew v1.1.1
9+
github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651
10+
github.com/sirupsen/logrus v1.9.3
11+
)
12+
13+
require (
14+
github.com/Microsoft/go-winio v0.6.2 // indirect
15+
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf // indirect
16+
github.com/docker/go-connections v0.5.0 // indirect
17+
golang.org/x/sys v0.10.0 // indirect
18+
)

go.sum

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
github.com/Microsoft/go-winio v0.6.2 h1:F2VQgta7ecxGYO8k3ZZz3RS8fVIXVxONVUPlNERoyfY=
2+
github.com/Microsoft/go-winio v0.6.2/go.mod h1:yd8OoFMLzJbo9gZq8j5qaps8bJ9aShtEA8Ipt1oGCvU=
3+
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf h1:iW4rZ826su+pqaw19uhpSCzhj44qo35pNgKFGqzDKkU=
4+
github.com/coreos/go-systemd v0.0.0-20191104093116-d3cd4ed1dbcf/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4=
5+
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
6+
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
7+
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
8+
github.com/docker/go-connections v0.5.0 h1:USnMq7hx7gwdVZq1L49hLXaFtUdTADjXGp+uj1Br63c=
9+
github.com/docker/go-connections v0.5.0/go.mod h1:ov60Kzw0kKElRwhNs9UlUHAE/F9Fe6GLaXnqyDdmEXc=
10+
github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651 h1:YcvzLmdrP/b8kLAGJ8GT7bdncgCAiWxJZIlt84D+RJg=
11+
github.com/docker/go-plugins-helpers v0.0.0-20211224144127-6eecb7beb651/go.mod h1:LFyLie6XcDbyKGeVK6bHe+9aJTYCxWLBg5IrJZOaXKA=
12+
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
13+
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
14+
github.com/sirupsen/logrus v1.9.3 h1:dueUQJ1C2q9oE3F7wvmSGAaVtTmUizReu6fjN8uqzbQ=
15+
github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVsIT4qYEQ=
16+
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
17+
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
18+
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
19+
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
20+
golang.org/x/sys v0.10.0 h1:SqMFp9UcQJZa+pmYuAKjd9xq1f0j5rLcDIk0mj4qAsA=
21+
golang.org/x/sys v0.10.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
22+
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
23+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
24+
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=

main.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import (
44
"flag"
55
"fmt"
66

7-
log "github.com/Sirupsen/logrus"
7+
log "github.com/sirupsen/logrus"
88

99
"os/user"
1010
"strconv"
@@ -29,7 +29,10 @@ func main() {
2929
u, _ := user.Lookup("root")
3030
gid, _ := strconv.Atoi(u.Gid)
3131

32-
d := newMooseFSDriver(*root)
32+
d, err := newMooseFSDriver(*root)
33+
if err != nil {
34+
log.Fatalf("Failed to initialize driver: %v", err)
35+
}
3336
h := volume.NewHandler(d)
3437
fmt.Println(h.ServeUnix("moosefs", gid))
3538
}

persistence.go

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
package main
2+
3+
import (
4+
"encoding/json"
5+
"io/ioutil"
6+
"os"
7+
"path/filepath"
8+
)
9+
10+
const stateFile = "/var/lib/docker-volume-moosefs/state.json"
11+
12+
type State struct {
13+
Mounts map[string]*moosefsMount `json:"mounts"`
14+
}
15+
16+
func ensureStateDir() error {
17+
dir := filepath.Dir(stateFile)
18+
return os.MkdirAll(dir, 0755)
19+
}
20+
21+
func (d *moosefsDriver) saveState() error {
22+
d.m.Lock()
23+
defer d.m.Unlock()
24+
25+
if err := ensureStateDir(); err != nil {
26+
return err
27+
}
28+
29+
state := State{
30+
Mounts: d.mounts,
31+
}
32+
33+
data, err := json.Marshal(state)
34+
if err != nil {
35+
return err
36+
}
37+
38+
return ioutil.WriteFile(stateFile, data, 0644)
39+
}
40+
41+
func (d *moosefsDriver) loadState() error {
42+
d.m.Lock()
43+
defer d.m.Unlock()
44+
45+
data, err := ioutil.ReadFile(stateFile)
46+
if os.IsNotExist(err) {
47+
// No state file exists yet, start with empty state
48+
return nil
49+
}
50+
if err != nil {
51+
return err
52+
}
53+
54+
var state State
55+
if err := json.Unmarshal(data, &state); err != nil {
56+
return err
57+
}
58+
59+
d.mounts = state.Mounts
60+
return nil
61+
}

0 commit comments

Comments
 (0)