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 }