github.com/flavio/docker@v0.1.3-0.20170117145210-f63d1a6eec47/integration-cli/docker_cli_daemon_plugins_test.go (about)

     1  // +build linux
     2  
     3  package main
     4  
     5  import (
     6  	"os"
     7  	"path/filepath"
     8  	"strings"
     9  	"syscall"
    10  
    11  	"github.com/docker/docker/integration-cli/checker"
    12  	"github.com/docker/docker/pkg/mount"
    13  	icmd "github.com/docker/docker/pkg/testutil/cmd"
    14  	"github.com/go-check/check"
    15  )
    16  
    17  // TestDaemonRestartWithPluginEnabled tests state restore for an enabled plugin
    18  func (s *DockerDaemonSuite) TestDaemonRestartWithPluginEnabled(c *check.C) {
    19  	testRequires(c, IsAmd64, Network)
    20  
    21  	s.d.Start(c)
    22  
    23  	if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName); err != nil {
    24  		c.Fatalf("Could not install plugin: %v %s", err, out)
    25  	}
    26  
    27  	defer func() {
    28  		if out, err := s.d.Cmd("plugin", "disable", pName); err != nil {
    29  			c.Fatalf("Could not disable plugin: %v %s", err, out)
    30  		}
    31  		if out, err := s.d.Cmd("plugin", "remove", pName); err != nil {
    32  			c.Fatalf("Could not remove plugin: %v %s", err, out)
    33  		}
    34  	}()
    35  
    36  	s.d.Restart(c)
    37  
    38  	out, err := s.d.Cmd("plugin", "ls")
    39  	if err != nil {
    40  		c.Fatalf("Could not list plugins: %v %s", err, out)
    41  	}
    42  	c.Assert(out, checker.Contains, pName)
    43  	c.Assert(out, checker.Contains, "true")
    44  }
    45  
    46  // TestDaemonRestartWithPluginDisabled tests state restore for a disabled plugin
    47  func (s *DockerDaemonSuite) TestDaemonRestartWithPluginDisabled(c *check.C) {
    48  	testRequires(c, IsAmd64, Network)
    49  
    50  	s.d.Start(c)
    51  
    52  	if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName, "--disable"); err != nil {
    53  		c.Fatalf("Could not install plugin: %v %s", err, out)
    54  	}
    55  
    56  	defer func() {
    57  		if out, err := s.d.Cmd("plugin", "remove", pName); err != nil {
    58  			c.Fatalf("Could not remove plugin: %v %s", err, out)
    59  		}
    60  	}()
    61  
    62  	s.d.Restart(c)
    63  
    64  	out, err := s.d.Cmd("plugin", "ls")
    65  	if err != nil {
    66  		c.Fatalf("Could not list plugins: %v %s", err, out)
    67  	}
    68  	c.Assert(out, checker.Contains, pName)
    69  	c.Assert(out, checker.Contains, "false")
    70  }
    71  
    72  // TestDaemonKillLiveRestoreWithPlugins SIGKILLs daemon started with --live-restore.
    73  // Plugins should continue to run.
    74  func (s *DockerDaemonSuite) TestDaemonKillLiveRestoreWithPlugins(c *check.C) {
    75  	testRequires(c, IsAmd64, Network)
    76  
    77  	s.d.Start(c, "--live-restore")
    78  	if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName); err != nil {
    79  		c.Fatalf("Could not install plugin: %v %s", err, out)
    80  	}
    81  	defer func() {
    82  		s.d.Restart(c, "--live-restore")
    83  		if out, err := s.d.Cmd("plugin", "disable", pName); err != nil {
    84  			c.Fatalf("Could not disable plugin: %v %s", err, out)
    85  		}
    86  		if out, err := s.d.Cmd("plugin", "remove", pName); err != nil {
    87  			c.Fatalf("Could not remove plugin: %v %s", err, out)
    88  		}
    89  	}()
    90  
    91  	if err := s.d.Kill(); err != nil {
    92  		c.Fatalf("Could not kill daemon: %v", err)
    93  	}
    94  
    95  	icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Success)
    96  }
    97  
    98  // TestDaemonShutdownLiveRestoreWithPlugins SIGTERMs daemon started with --live-restore.
    99  // Plugins should continue to run.
   100  func (s *DockerDaemonSuite) TestDaemonShutdownLiveRestoreWithPlugins(c *check.C) {
   101  	testRequires(c, IsAmd64, Network)
   102  
   103  	s.d.Start(c, "--live-restore")
   104  	if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName); err != nil {
   105  		c.Fatalf("Could not install plugin: %v %s", err, out)
   106  	}
   107  	defer func() {
   108  		s.d.Restart(c, "--live-restore")
   109  		if out, err := s.d.Cmd("plugin", "disable", pName); err != nil {
   110  			c.Fatalf("Could not disable plugin: %v %s", err, out)
   111  		}
   112  		if out, err := s.d.Cmd("plugin", "remove", pName); err != nil {
   113  			c.Fatalf("Could not remove plugin: %v %s", err, out)
   114  		}
   115  	}()
   116  
   117  	if err := s.d.Interrupt(); err != nil {
   118  		c.Fatalf("Could not kill daemon: %v", err)
   119  	}
   120  
   121  	icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Success)
   122  }
   123  
   124  // TestDaemonShutdownWithPlugins shuts down running plugins.
   125  func (s *DockerDaemonSuite) TestDaemonShutdownWithPlugins(c *check.C) {
   126  	testRequires(c, IsAmd64, Network, SameHostDaemon)
   127  
   128  	s.d.Start(c)
   129  	if out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName); err != nil {
   130  		c.Fatalf("Could not install plugin: %v %s", err, out)
   131  	}
   132  
   133  	defer func() {
   134  		s.d.Restart(c)
   135  		if out, err := s.d.Cmd("plugin", "disable", pName); err != nil {
   136  			c.Fatalf("Could not disable plugin: %v %s", err, out)
   137  		}
   138  		if out, err := s.d.Cmd("plugin", "remove", pName); err != nil {
   139  			c.Fatalf("Could not remove plugin: %v %s", err, out)
   140  		}
   141  	}()
   142  
   143  	if err := s.d.Interrupt(); err != nil {
   144  		c.Fatalf("Could not kill daemon: %v", err)
   145  	}
   146  
   147  	for {
   148  		if err := syscall.Kill(s.d.Pid(), 0); err == syscall.ESRCH {
   149  			break
   150  		}
   151  	}
   152  
   153  	icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Expected{
   154  		ExitCode: 1,
   155  		Error:    "exit status 1",
   156  	})
   157  
   158  	s.d.Start(c, "--live-restore")
   159  	icmd.RunCommand("pgrep", "-f", pluginProcessName).Assert(c, icmd.Success)
   160  }
   161  
   162  // TestVolumePlugin tests volume creation using a plugin.
   163  func (s *DockerDaemonSuite) TestVolumePlugin(c *check.C) {
   164  	testRequires(c, IsAmd64, Network)
   165  
   166  	volName := "plugin-volume"
   167  	destDir := "/tmp/data/"
   168  	destFile := "foo"
   169  
   170  	s.d.Start(c)
   171  	out, err := s.d.Cmd("plugin", "install", pName, "--grant-all-permissions")
   172  	if err != nil {
   173  		c.Fatalf("Could not install plugin: %v %s", err, out)
   174  	}
   175  	pluginID, err := s.d.Cmd("plugin", "inspect", "-f", "{{.Id}}", pName)
   176  	pluginID = strings.TrimSpace(pluginID)
   177  	if err != nil {
   178  		c.Fatalf("Could not retrieve plugin ID: %v %s", err, pluginID)
   179  	}
   180  	mountpointPrefix := filepath.Join(s.d.RootDir(), "plugins", pluginID, "rootfs")
   181  	defer func() {
   182  		if out, err := s.d.Cmd("plugin", "disable", pName); err != nil {
   183  			c.Fatalf("Could not disable plugin: %v %s", err, out)
   184  		}
   185  
   186  		if out, err := s.d.Cmd("plugin", "remove", pName); err != nil {
   187  			c.Fatalf("Could not remove plugin: %v %s", err, out)
   188  		}
   189  
   190  		exists, err := existsMountpointWithPrefix(mountpointPrefix)
   191  		c.Assert(err, checker.IsNil)
   192  		c.Assert(exists, checker.Equals, false)
   193  
   194  	}()
   195  
   196  	out, err = s.d.Cmd("volume", "create", "-d", pName, volName)
   197  	if err != nil {
   198  		c.Fatalf("Could not create volume: %v %s", err, out)
   199  	}
   200  	defer func() {
   201  		if out, err := s.d.Cmd("volume", "remove", volName); err != nil {
   202  			c.Fatalf("Could not remove volume: %v %s", err, out)
   203  		}
   204  	}()
   205  
   206  	out, err = s.d.Cmd("volume", "ls")
   207  	if err != nil {
   208  		c.Fatalf("Could not list volume: %v %s", err, out)
   209  	}
   210  	c.Assert(out, checker.Contains, volName)
   211  	c.Assert(out, checker.Contains, pName)
   212  
   213  	mountPoint, err := s.d.Cmd("volume", "inspect", volName, "--format", "{{.Mountpoint}}")
   214  	if err != nil {
   215  		c.Fatalf("Could not inspect volume: %v %s", err, mountPoint)
   216  	}
   217  	mountPoint = strings.TrimSpace(mountPoint)
   218  
   219  	out, err = s.d.Cmd("run", "--rm", "-v", volName+":"+destDir, "busybox", "touch", destDir+destFile)
   220  	c.Assert(err, checker.IsNil, check.Commentf(out))
   221  	path := filepath.Join(s.d.RootDir(), "plugins", pluginID, "rootfs", mountPoint, destFile)
   222  	_, err = os.Lstat(path)
   223  	c.Assert(err, checker.IsNil)
   224  
   225  	exists, err := existsMountpointWithPrefix(mountpointPrefix)
   226  	c.Assert(err, checker.IsNil)
   227  	c.Assert(exists, checker.Equals, true)
   228  }
   229  
   230  func (s *DockerDaemonSuite) TestGraphdriverPlugin(c *check.C) {
   231  	testRequires(c, Network, IsAmd64, DaemonIsLinux, overlay2Supported, ExperimentalDaemon)
   232  
   233  	s.d.Start(c)
   234  
   235  	// install the plugin
   236  	plugin := "cpuguy83/docker-overlay2-graphdriver-plugin"
   237  	out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", plugin)
   238  	c.Assert(err, checker.IsNil, check.Commentf(out))
   239  
   240  	// restart the daemon with the plugin set as the storage driver
   241  	s.d.Restart(c, "-s", plugin, "--storage-opt", "overlay2.override_kernel_check=1")
   242  
   243  	// run a container
   244  	out, err = s.d.Cmd("run", "--rm", "busybox", "true") // this will pull busybox using the plugin
   245  	c.Assert(err, checker.IsNil, check.Commentf(out))
   246  }
   247  
   248  func (s *DockerDaemonSuite) TestPluginVolumeRemoveOnRestart(c *check.C) {
   249  	testRequires(c, DaemonIsLinux, Network, IsAmd64)
   250  
   251  	s.d.Start(c, "--live-restore=true")
   252  
   253  	out, err := s.d.Cmd("plugin", "install", "--grant-all-permissions", pName)
   254  	c.Assert(err, checker.IsNil, check.Commentf(out))
   255  	c.Assert(strings.TrimSpace(out), checker.Contains, pName)
   256  
   257  	out, err = s.d.Cmd("volume", "create", "--driver", pName, "test")
   258  	c.Assert(err, checker.IsNil, check.Commentf(out))
   259  
   260  	s.d.Restart(c, "--live-restore=true")
   261  
   262  	out, err = s.d.Cmd("plugin", "disable", pName)
   263  	c.Assert(err, checker.NotNil, check.Commentf(out))
   264  	c.Assert(out, checker.Contains, "in use")
   265  
   266  	out, err = s.d.Cmd("volume", "rm", "test")
   267  	c.Assert(err, checker.IsNil, check.Commentf(out))
   268  
   269  	out, err = s.d.Cmd("plugin", "disable", pName)
   270  	c.Assert(err, checker.IsNil, check.Commentf(out))
   271  
   272  	out, err = s.d.Cmd("plugin", "rm", pName)
   273  	c.Assert(err, checker.IsNil, check.Commentf(out))
   274  }
   275  
   276  func existsMountpointWithPrefix(mountpointPrefix string) (bool, error) {
   277  	mounts, err := mount.GetMounts()
   278  	if err != nil {
   279  		return false, err
   280  	}
   281  	for _, mnt := range mounts {
   282  		if strings.HasPrefix(mnt.Mountpoint, mountpointPrefix) {
   283  			return true, nil
   284  		}
   285  	}
   286  	return false, nil
   287  }