Merge pull request #25830 from tiborvass/cherry-pick-25825
[1.12] Fix volume not working after daemon restart
diff --git a/volume/local/local.go b/volume/local/local.go
index 30aa9de..498f4db 100644
--- a/volume/local/local.go
+++ b/volume/local/local.go
@@ -9,6 +9,7 @@
"io/ioutil"
"os"
"path/filepath"
+ "reflect"
"sync"
"github.com/Sirupsen/logrus"
@@ -90,10 +91,13 @@
r.volumes[name] = v
optsFilePath := filepath.Join(rootDirectory, name, "opts.json")
if b, err := ioutil.ReadFile(optsFilePath); err == nil {
- v.opts = &optsConfig{}
- if err := json.Unmarshal(b, v.opts); err != nil {
+ opts := optsConfig{}
+ if err := json.Unmarshal(b, &opts); err != nil {
return nil, err
}
+ if !reflect.DeepEqual(opts, optsConfig{}) {
+ v.opts = &opts
+ }
// unmount anything that may still be mounted (for example, from an unclean shutdown)
for _, info := range mountInfos {
@@ -178,7 +182,7 @@
path: path,
}
- if opts != nil {
+ if len(opts) != 0 {
if err = setOpts(v, opts); err != nil {
return nil, err
}
diff --git a/volume/local/local_test.go b/volume/local/local_test.go
index 6b9ce55..a21f5f7 100644
--- a/volume/local/local_test.go
+++ b/volume/local/local_test.go
@@ -3,6 +3,7 @@
import (
"io/ioutil"
"os"
+ "path/filepath"
"reflect"
"runtime"
"strings"
@@ -133,6 +134,11 @@
}
}
}
+
+ r, err = New(rootDir, 0, 0)
+ if err != nil {
+ t.Fatal(err)
+ }
}
func TestValidateName(t *testing.T) {
@@ -262,3 +268,61 @@
t.Fatal("missing volume options on restart")
}
}
+
+func TestRealodNoOpts(t *testing.T) {
+ rootDir, err := ioutil.TempDir("", "volume-test-reload-no-opts")
+ if err != nil {
+ t.Fatal(err)
+ }
+ defer os.RemoveAll(rootDir)
+
+ r, err := New(rootDir, 0, 0)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ if _, err := r.Create("test1", nil); err != nil {
+ t.Fatal(err)
+ }
+ if _, err := r.Create("test2", nil); err != nil {
+ t.Fatal(err)
+ }
+ // make sure a file with `null` (.e.g. empty opts map from older daemon) is ok
+ if err := ioutil.WriteFile(filepath.Join(rootDir, "test2"), []byte("null"), 600); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, err := r.Create("test3", nil); err != nil {
+ t.Fatal(err)
+ }
+ // make sure an empty opts file doesn't break us too
+ if err := ioutil.WriteFile(filepath.Join(rootDir, "test3"), nil, 600); err != nil {
+ t.Fatal(err)
+ }
+
+ if _, err := r.Create("test4", map[string]string{}); err != nil {
+ t.Fatal(err)
+ }
+
+ r, err = New(rootDir, 0, 0)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ for _, name := range []string{"test1", "test2", "test3", "test4"} {
+ v, err := r.Get(name)
+ if err != nil {
+ t.Fatal(err)
+ }
+ lv, ok := v.(*localVolume)
+ if !ok {
+ t.Fatalf("expected *localVolume got: %v", reflect.TypeOf(v))
+ }
+ if lv.opts != nil {
+ t.Fatalf("expected opts to be nil, got: %v", lv.opts)
+ }
+ if _, err := lv.Mount("1234"); err != nil {
+ t.Fatal(err)
+ }
+ }
+}