github.com/opsramp/moby@v1.13.1/integration-cli/docker_cli_daemon_plugins_test.go (about)

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