gopkg.in/docker/docker.v1@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 }