فهرست منبع

api: fix ReadOnly support for tmpfs

For `--mount type=tmpfs,target=/foo,readonly`, the `readonly` flag was just ignored.

Signed-off-by: Akihiro Suda <suda.akihiro@lab.ntt.co.jp>
Akihiro Suda 8 سال پیش
والد
کامیت
3e3d3c8086
5فایلهای تغییر یافته به همراه42 افزوده شده و 13 حذف شده
  1. 1 1
      container/container_unix.go
  2. 1 1
      volume/validate.go
  3. 7 6
      volume/volume_linux.go
  4. 32 4
      volume/volume_linux_test.go
  5. 1 1
      volume/volume_unsupported.go

+ 1 - 1
container/container_unix.go

@@ -414,7 +414,7 @@ func (container *Container) TmpfsMounts() ([]Mount, error) {
 	}
 	for dest, mnt := range container.MountPoints {
 		if mnt.Type == mounttypes.TypeTmpfs {
-			data, err := volume.ConvertTmpfsOptions(mnt.Spec.TmpfsOptions)
+			data, err := volume.ConvertTmpfsOptions(mnt.Spec.TmpfsOptions, mnt.Spec.ReadOnly)
 			if err != nil {
 				return nil, err
 			}

+ 1 - 1
volume/validate.go

@@ -91,7 +91,7 @@ func validateMountConfig(mnt *mount.Mount, options ...func(*validateOpts)) error
 		if len(mnt.Source) != 0 {
 			return &errMountConfig{mnt, errExtraField("Source")}
 		}
-		if _, err := ConvertTmpfsOptions(mnt.TmpfsOptions); err != nil {
+		if _, err := ConvertTmpfsOptions(mnt.TmpfsOptions, mnt.ReadOnly); err != nil {
 			return &errMountConfig{mnt, err}
 		}
 	default:

+ 7 - 6
volume/volume_linux.go

@@ -13,16 +13,17 @@ import (
 // for mount(2).
 // The logic is copy-pasted from daemon/cluster/executer/container.getMountMask.
 // It will be deduplicated when we migrated the cluster to the new mount scheme.
-func ConvertTmpfsOptions(opt *mounttypes.TmpfsOptions) (string, error) {
-	if opt == nil {
-		return "", nil
-	}
+func ConvertTmpfsOptions(opt *mounttypes.TmpfsOptions, readOnly bool) (string, error) {
 	var rawOpts []string
-	if opt.Mode != 0 {
+	if readOnly {
+		rawOpts = append(rawOpts, "ro")
+	}
+
+	if opt != nil && opt.Mode != 0 {
 		rawOpts = append(rawOpts, fmt.Sprintf("mode=%o", opt.Mode))
 	}
 
-	if opt.SizeBytes != 0 {
+	if opt != nil && opt.SizeBytes != 0 {
 		// calculate suffix here, making this linux specific, but that is
 		// okay, since API is that way anyways.
 

+ 32 - 4
volume/volume_linux_test.go

@@ -3,6 +3,7 @@
 package volume
 
 import (
+	"strings"
 	"testing"
 
 	mounttypes "github.com/docker/docker/api/types/mount"
@@ -10,14 +11,41 @@ import (
 
 func TestConvertTmpfsOptions(t *testing.T) {
 	type testCase struct {
-		opt mounttypes.TmpfsOptions
+		opt                  mounttypes.TmpfsOptions
+		readOnly             bool
+		expectedSubstrings   []string
+		unexpectedSubstrings []string
 	}
 	cases := []testCase{
-		{mounttypes.TmpfsOptions{SizeBytes: 1024 * 1024, Mode: 0700}},
+		{
+			opt:                  mounttypes.TmpfsOptions{SizeBytes: 1024 * 1024, Mode: 0700},
+			readOnly:             false,
+			expectedSubstrings:   []string{"size=1m", "mode=700"},
+			unexpectedSubstrings: []string{"ro"},
+		},
+		{
+			opt:                  mounttypes.TmpfsOptions{},
+			readOnly:             true,
+			expectedSubstrings:   []string{"ro"},
+			unexpectedSubstrings: []string{},
+		},
 	}
 	for _, c := range cases {
-		if _, err := ConvertTmpfsOptions(&c.opt); err != nil {
-			t.Fatalf("could not convert %+v to string: %v", c.opt, err)
+		data, err := ConvertTmpfsOptions(&c.opt, c.readOnly)
+		if err != nil {
+			t.Fatalf("could not convert %+v (readOnly: %v) to string: %v",
+				c.opt, c.readOnly, err)
+		}
+		t.Logf("data=%q", data)
+		for _, s := range c.expectedSubstrings {
+			if !strings.Contains(data, s) {
+				t.Fatalf("expected substring: %s, got %v (case=%+v)", s, data, c)
+			}
+		}
+		for _, s := range c.unexpectedSubstrings {
+			if strings.Contains(data, s) {
+				t.Fatalf("unexpected substring: %s, got %v (case=%+v)", s, data, c)
+			}
 		}
 	}
 }

+ 1 - 1
volume/volume_unsupported.go

@@ -11,6 +11,6 @@ import (
 
 // ConvertTmpfsOptions converts *mounttypes.TmpfsOptions to the raw option string
 // for mount(2).
-func ConvertTmpfsOptions(opt *mounttypes.TmpfsOptions) (string, error) {
+func ConvertTmpfsOptions(opt *mounttypes.TmpfsOptions, readOnly bool) (string, error) {
 	return "", fmt.Errorf("%s does not support tmpfs", runtime.GOOS)
 }