github.com/rsampaio/docker@v0.7.2-0.20150827203920-fdc73cc3fc31/integration-cli/docker_cli_start_volume_driver_unix_test.go (about)

     1  // +build !windows
     2  
     3  package main
     4  
     5  import (
     6  	"encoding/json"
     7  	"fmt"
     8  	"io/ioutil"
     9  	"net/http"
    10  	"net/http/httptest"
    11  	"os"
    12  	"path/filepath"
    13  	"strings"
    14  
    15  	"github.com/go-check/check"
    16  )
    17  
    18  func init() {
    19  	check.Suite(&DockerExternalVolumeSuite{
    20  		ds: &DockerSuite{},
    21  	})
    22  }
    23  
    24  type eventCounter struct {
    25  	activations int
    26  	creations   int
    27  	removals    int
    28  	mounts      int
    29  	unmounts    int
    30  	paths       int
    31  }
    32  
    33  type DockerExternalVolumeSuite struct {
    34  	server *httptest.Server
    35  	ds     *DockerSuite
    36  	d      *Daemon
    37  	ec     *eventCounter
    38  }
    39  
    40  func (s *DockerExternalVolumeSuite) SetUpTest(c *check.C) {
    41  	s.d = NewDaemon(c)
    42  	s.ec = &eventCounter{}
    43  }
    44  
    45  func (s *DockerExternalVolumeSuite) TearDownTest(c *check.C) {
    46  	s.d.Stop()
    47  	s.ds.TearDownTest(c)
    48  }
    49  
    50  func (s *DockerExternalVolumeSuite) SetUpSuite(c *check.C) {
    51  	mux := http.NewServeMux()
    52  	s.server = httptest.NewServer(mux)
    53  
    54  	type pluginRequest struct {
    55  		name string
    56  	}
    57  
    58  	mux.HandleFunc("/Plugin.Activate", func(w http.ResponseWriter, r *http.Request) {
    59  		s.ec.activations++
    60  
    61  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
    62  		fmt.Fprintln(w, `{"Implements": ["VolumeDriver"]}`)
    63  	})
    64  
    65  	mux.HandleFunc("/VolumeDriver.Create", func(w http.ResponseWriter, r *http.Request) {
    66  		s.ec.creations++
    67  
    68  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
    69  		fmt.Fprintln(w, `{}`)
    70  	})
    71  
    72  	mux.HandleFunc("/VolumeDriver.Remove", func(w http.ResponseWriter, r *http.Request) {
    73  		s.ec.removals++
    74  
    75  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
    76  		fmt.Fprintln(w, `{}`)
    77  	})
    78  
    79  	mux.HandleFunc("/VolumeDriver.Path", func(w http.ResponseWriter, r *http.Request) {
    80  		s.ec.paths++
    81  
    82  		var pr pluginRequest
    83  		if err := json.NewDecoder(r.Body).Decode(&pr); err != nil {
    84  			http.Error(w, err.Error(), 500)
    85  		}
    86  
    87  		p := hostVolumePath(pr.name)
    88  
    89  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
    90  		fmt.Fprintln(w, fmt.Sprintf("{\"Mountpoint\": \"%s\"}", p))
    91  	})
    92  
    93  	mux.HandleFunc("/VolumeDriver.Mount", func(w http.ResponseWriter, r *http.Request) {
    94  		s.ec.mounts++
    95  
    96  		var pr pluginRequest
    97  		if err := json.NewDecoder(r.Body).Decode(&pr); err != nil {
    98  			http.Error(w, err.Error(), 500)
    99  		}
   100  
   101  		p := hostVolumePath(pr.name)
   102  		if err := os.MkdirAll(p, 0755); err != nil {
   103  			http.Error(w, err.Error(), 500)
   104  		}
   105  
   106  		if err := ioutil.WriteFile(filepath.Join(p, "test"), []byte(s.server.URL), 0644); err != nil {
   107  			http.Error(w, err.Error(), 500)
   108  		}
   109  
   110  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
   111  		fmt.Fprintln(w, fmt.Sprintf("{\"Mountpoint\": \"%s\"}", p))
   112  	})
   113  
   114  	mux.HandleFunc("/VolumeDriver.Unmount", func(w http.ResponseWriter, r *http.Request) {
   115  		s.ec.unmounts++
   116  
   117  		var pr pluginRequest
   118  		if err := json.NewDecoder(r.Body).Decode(&pr); err != nil {
   119  			http.Error(w, err.Error(), 500)
   120  		}
   121  
   122  		w.Header().Set("Content-Type", "application/vnd.docker.plugins.v1+json")
   123  		fmt.Fprintln(w, `{}`)
   124  	})
   125  
   126  	if err := os.MkdirAll("/etc/docker/plugins", 0755); err != nil {
   127  		c.Fatal(err)
   128  	}
   129  
   130  	if err := ioutil.WriteFile("/etc/docker/plugins/test-external-volume-driver.spec", []byte(s.server.URL), 0644); err != nil {
   131  		c.Fatal(err)
   132  	}
   133  }
   134  
   135  func (s *DockerExternalVolumeSuite) TearDownSuite(c *check.C) {
   136  	s.server.Close()
   137  
   138  	if err := os.RemoveAll("/etc/docker/plugins"); err != nil {
   139  		c.Fatal(err)
   140  	}
   141  }
   142  
   143  func (s *DockerExternalVolumeSuite) TestStartExternalNamedVolumeDriver(c *check.C) {
   144  	if err := s.d.StartWithBusybox(); err != nil {
   145  		c.Fatal(err)
   146  	}
   147  
   148  	out, err := s.d.Cmd("run", "--rm", "--name", "test-data", "-v", "external-volume-test:/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", "busybox:latest", "cat", "/tmp/external-volume-test/test")
   149  	if err != nil {
   150  		c.Fatal(out, err)
   151  	}
   152  
   153  	if !strings.Contains(out, s.server.URL) {
   154  		c.Fatalf("External volume mount failed. Output: %s\n", out)
   155  	}
   156  
   157  	p := hostVolumePath("external-volume-test")
   158  	_, err = os.Lstat(p)
   159  	if err == nil {
   160  		c.Fatalf("Expected error checking volume path in host: %s\n", p)
   161  	}
   162  
   163  	if !os.IsNotExist(err) {
   164  		c.Fatalf("Expected volume path in host to not exist: %s, %v\n", p, err)
   165  	}
   166  
   167  	c.Assert(s.ec.activations, check.Equals, 1)
   168  	c.Assert(s.ec.creations, check.Equals, 1)
   169  	c.Assert(s.ec.removals, check.Equals, 1)
   170  	c.Assert(s.ec.mounts, check.Equals, 1)
   171  	c.Assert(s.ec.unmounts, check.Equals, 1)
   172  }
   173  
   174  func (s *DockerExternalVolumeSuite) TestStartExternalVolumeUnnamedDriver(c *check.C) {
   175  	if err := s.d.StartWithBusybox(); err != nil {
   176  		c.Fatal(err)
   177  	}
   178  
   179  	out, err := s.d.Cmd("run", "--rm", "--name", "test-data", "-v", "/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", "busybox:latest", "cat", "/tmp/external-volume-test/test")
   180  	if err != nil {
   181  		c.Fatal(err)
   182  	}
   183  
   184  	if !strings.Contains(out, s.server.URL) {
   185  		c.Fatalf("External volume mount failed. Output: %s\n", out)
   186  	}
   187  
   188  	c.Assert(s.ec.activations, check.Equals, 1)
   189  	c.Assert(s.ec.creations, check.Equals, 1)
   190  	c.Assert(s.ec.removals, check.Equals, 1)
   191  	c.Assert(s.ec.mounts, check.Equals, 1)
   192  	c.Assert(s.ec.unmounts, check.Equals, 1)
   193  }
   194  
   195  func (s DockerExternalVolumeSuite) TestStartExternalVolumeDriverVolumesFrom(c *check.C) {
   196  	if err := s.d.StartWithBusybox(); err != nil {
   197  		c.Fatal(err)
   198  	}
   199  
   200  	out, err := s.d.Cmd("run", "-d", "--name", "vol-test1", "-v", "/foo", "--volume-driver", "test-external-volume-driver", "busybox:latest")
   201  	c.Assert(err, check.IsNil, check.Commentf(out))
   202  
   203  	out, err = s.d.Cmd("run", "--rm", "--volumes-from", "vol-test1", "--name", "vol-test2", "busybox", "ls", "/tmp")
   204  	c.Assert(err, check.IsNil, check.Commentf(out))
   205  
   206  	out, err = s.d.Cmd("rm", "-fv", "vol-test1")
   207  	c.Assert(err, check.IsNil, check.Commentf(out))
   208  
   209  	c.Assert(s.ec.activations, check.Equals, 1)
   210  	c.Assert(s.ec.creations, check.Equals, 1)
   211  	c.Assert(s.ec.removals, check.Equals, 1)
   212  	c.Assert(s.ec.mounts, check.Equals, 2)
   213  	c.Assert(s.ec.unmounts, check.Equals, 2)
   214  }
   215  
   216  func (s DockerExternalVolumeSuite) TestStartExternalVolumeDriverDeleteContainer(c *check.C) {
   217  	if err := s.d.StartWithBusybox(); err != nil {
   218  		c.Fatal(err)
   219  	}
   220  
   221  	if out, err := s.d.Cmd("run", "-d", "--name", "vol-test1", "-v", "/foo", "--volume-driver", "test-external-volume-driver", "busybox:latest"); err != nil {
   222  		c.Fatal(out, err)
   223  	}
   224  
   225  	if out, err := s.d.Cmd("rm", "-fv", "vol-test1"); err != nil {
   226  		c.Fatal(out, err)
   227  	}
   228  
   229  	c.Assert(s.ec.activations, check.Equals, 1)
   230  	c.Assert(s.ec.creations, check.Equals, 1)
   231  	c.Assert(s.ec.removals, check.Equals, 1)
   232  	c.Assert(s.ec.mounts, check.Equals, 1)
   233  	c.Assert(s.ec.unmounts, check.Equals, 1)
   234  }
   235  
   236  func hostVolumePath(name string) string {
   237  	return fmt.Sprintf("/var/lib/docker/volumes/%s", name)
   238  }
   239  
   240  func (s *DockerExternalVolumeSuite) TestStartExternalNamedVolumeDriverCheckBindLocalVolume(c *check.C) {
   241  	if err := s.d.StartWithBusybox(); err != nil {
   242  		c.Fatal(err)
   243  	}
   244  
   245  	expected := s.server.URL
   246  
   247  	dockerfile := fmt.Sprintf(`FROM busybox:latest
   248  	RUN mkdir /nobindthenlocalvol
   249  	RUN echo %s > /nobindthenlocalvol/test
   250  	VOLUME ["/nobindthenlocalvol"]`, expected)
   251  
   252  	img := "test-checkbindlocalvolume"
   253  
   254  	args := []string{"--host", s.d.sock()}
   255  	buildOut, err := buildImageArgs(args, img, dockerfile, true)
   256  	fmt.Println(buildOut)
   257  
   258  	out, err := s.d.Cmd("run", "--rm", "--name", "test-data-nobind", "-v", "external-volume-test:/tmp/external-volume-test", "--volume-driver", "test-external-volume-driver", img, "cat", "/nobindthenlocalvol/test")
   259  	if err != nil {
   260  		fmt.Println(out)
   261  		c.Fatal(err)
   262  	}
   263  
   264  	if !strings.Contains(out, expected) {
   265  		c.Fatalf("External volume mount failed. Output: %s\n", out)
   266  	}
   267  
   268  	c.Assert(s.ec.activations, check.Equals, 1)
   269  	c.Assert(s.ec.creations, check.Equals, 1)
   270  	c.Assert(s.ec.removals, check.Equals, 1)
   271  	c.Assert(s.ec.mounts, check.Equals, 1)
   272  	c.Assert(s.ec.unmounts, check.Equals, 1)
   273  }