Skip to content

Commit

Permalink
Add support for volume scope + autodetection
Browse files Browse the repository at this point in the history
Since Docker 1.12, volumes can report their scope as either "global"
or "local". Global scope means volumes are available on all nodes in
a Docker Swarm cluster (so Swarm should act accordingly, for example
it should not try to remove a global volume on each node).

By default (or when started with -scope auto), scope is autodetected,
meaning if driver's home is on Virtuozzo Storage, global scope is set
and reported, otherwise it's assumed as local. This can be overriden
from the command line ("-scope local" or "-scope global").

For more details, see moby/moby#22077

Signed-off-by: Kir Kolyshkin <[email protected]>
  • Loading branch information
kolyshkin committed Nov 15, 2016
1 parent 0fd6b02 commit 7637fe1
Show file tree
Hide file tree
Showing 4 changed files with 42 additions and 5 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
SOURCES = driver.go main.go paths.go vstorage.go
SOURCES = driver.go main.go paths.go vstorage.go fstype.go
WORKPLACE = $(abspath Godeps/_workspace)

BIN = docker-volume-ploop
Expand Down
30 changes: 26 additions & 4 deletions driver.go
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,11 @@ import (
*/

type volumeOptions struct {
size uint64 // ploop image size, in kilobytes
mode ploop.ImageMode // ploop image format (expanded/prealloc/raw)
clog uint // cluster block log size in 512-byte sectors
tier int8 // Virtuozzo storage tier (-1: use default)
size uint64 // ploop image size, in kilobytes
mode ploop.ImageMode // ploop image format (expanded/prealloc/raw)
clog uint // cluster block log size in 512-byte sectors
tier int8 // Virtuozzo storage tier (-1: use default)
scope string // Volume scope (global/local/auto)
}

type mount struct {
Expand Down Expand Up @@ -87,6 +88,12 @@ func (o *volumeOptions) setTier(str string) error {
return nil
}

func (o *volumeOptions) setScope(str string) error {
// FIXME: check for local/global/auto?
o.scope = str
return nil
}

func newPloopDriver(home string, opts *volumeOptions) *ploopDriver {
// home must exist
_, err := os.Stat(home)
Expand All @@ -98,6 +105,16 @@ func newPloopDriver(home string, opts *volumeOptions) *ploopDriver {
}
}

// Autodetect scope: global if home is on vstorage, local otherwise
if opts.scope == "auto" {
if isOnVstorage(home) {
opts.scope = "global"
} else {
opts.scope = "local"
}
logrus.Infof("Autodetecting driver scope: %s", opts.scope)
}

d := ploopDriver{
home: home,
opts: *opts,
Expand Down Expand Up @@ -346,6 +363,11 @@ func (d *ploopDriver) Path(r volume.Request) volume.Response {
// TODO: check if mounted?
return volume.Response{Mountpoint: d.mnt(r.Name)}
}
func (d *ploopDriver) Capabilities(r volume.Request) volume.Response {
return volume.Response{
Capabilities: volume.Capability{
Scope: d.opts.scope}}
}

// Check if a given volume exist
func (d *ploopDriver) volExist(name string) (bool, error) {
Expand Down
4 changes: 4 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import (
// Options and their default values
var (
home = flag.String("home", "/pcs", "Base directory where volumes are created")
scope = flag.String("scope", "auto", "Volumes scope (local or global)")
size = flag.String("size", "16GB", "Default image size")
mode = flag.String("mode", "expanded", "Default ploop image mode")
clog = flag.String("clog", "0", "Cluster block log size in 512-byte sectors")
Expand Down Expand Up @@ -52,6 +53,9 @@ func main() {
if err := opts.setTier(*tier); err != nil {
logrus.Fatalf(err.Error())
}
if err := opts.setScope(*scope); err != nil {
logrus.Fatalf(err.Error())
}

// Set log level
if *debug {
Expand Down
11 changes: 11 additions & 0 deletions vstorage.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,3 +74,14 @@ func vstorageSetTier(path string, tier int8) error {

return err
}

// Check if a file/directory is actually on vstorage
func isOnVstorage(path string) bool {
fs, err := GetFilesystemType(path)
if err != nil {
logrus.Errorf("Can't figure %s fs: %v", err)
return false
}

return fs == "fuse.vstorage"
}

0 comments on commit 7637fe1

Please sign in to comment.