docker_api_swarm_test.go 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311
  1. // +build !windows
  2. package main
  3. import (
  4. "fmt"
  5. "net/http"
  6. "os"
  7. "path/filepath"
  8. "strconv"
  9. "strings"
  10. "sync"
  11. "syscall"
  12. "time"
  13. "github.com/docker/docker/api/types/swarm"
  14. "github.com/docker/docker/integration-cli/daemon"
  15. "github.com/docker/docker/pkg/integration/checker"
  16. "github.com/go-check/check"
  17. )
  18. var defaultReconciliationTimeout = 30 * time.Second
  19. func (s *DockerSwarmSuite) TestAPISwarmInit(c *check.C) {
  20. // todo: should find a better way to verify that components are running than /info
  21. d1 := s.AddDaemon(c, true, true)
  22. info, err := d1.SwarmInfo()
  23. c.Assert(err, checker.IsNil)
  24. c.Assert(info.ControlAvailable, checker.True)
  25. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  26. d2 := s.AddDaemon(c, true, false)
  27. info, err = d2.SwarmInfo()
  28. c.Assert(err, checker.IsNil)
  29. c.Assert(info.ControlAvailable, checker.False)
  30. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  31. // Leaving cluster
  32. c.Assert(d2.Leave(false), checker.IsNil)
  33. info, err = d2.SwarmInfo()
  34. c.Assert(err, checker.IsNil)
  35. c.Assert(info.ControlAvailable, checker.False)
  36. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
  37. c.Assert(d2.Join(swarm.JoinRequest{JoinToken: d1.JoinTokens(c).Worker, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil)
  38. info, err = d2.SwarmInfo()
  39. c.Assert(err, checker.IsNil)
  40. c.Assert(info.ControlAvailable, checker.False)
  41. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  42. // Current state restoring after restarts
  43. d1.Stop(c)
  44. d2.Stop(c)
  45. d1.Start(c)
  46. d2.Start(c)
  47. info, err = d1.SwarmInfo()
  48. c.Assert(err, checker.IsNil)
  49. c.Assert(info.ControlAvailable, checker.True)
  50. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  51. info, err = d2.SwarmInfo()
  52. c.Assert(err, checker.IsNil)
  53. c.Assert(info.ControlAvailable, checker.False)
  54. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  55. }
  56. func (s *DockerSwarmSuite) TestAPISwarmJoinToken(c *check.C) {
  57. d1 := s.AddDaemon(c, false, false)
  58. c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil)
  59. // todo: error message differs depending if some components of token are valid
  60. d2 := s.AddDaemon(c, false, false)
  61. err := d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.ListenAddr}})
  62. c.Assert(err, checker.NotNil)
  63. c.Assert(err.Error(), checker.Contains, "join token is necessary")
  64. info, err := d2.SwarmInfo()
  65. c.Assert(err, checker.IsNil)
  66. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
  67. err = d2.Join(swarm.JoinRequest{JoinToken: "foobaz", RemoteAddrs: []string{d1.ListenAddr}})
  68. c.Assert(err, checker.NotNil)
  69. c.Assert(err.Error(), checker.Contains, "invalid join token")
  70. info, err = d2.SwarmInfo()
  71. c.Assert(err, checker.IsNil)
  72. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
  73. workerToken := d1.JoinTokens(c).Worker
  74. c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil)
  75. info, err = d2.SwarmInfo()
  76. c.Assert(err, checker.IsNil)
  77. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  78. c.Assert(d2.Leave(false), checker.IsNil)
  79. info, err = d2.SwarmInfo()
  80. c.Assert(err, checker.IsNil)
  81. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
  82. // change tokens
  83. d1.RotateTokens(c)
  84. err = d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}})
  85. c.Assert(err, checker.NotNil)
  86. c.Assert(err.Error(), checker.Contains, "join token is necessary")
  87. info, err = d2.SwarmInfo()
  88. c.Assert(err, checker.IsNil)
  89. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
  90. workerToken = d1.JoinTokens(c).Worker
  91. c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil)
  92. info, err = d2.SwarmInfo()
  93. c.Assert(err, checker.IsNil)
  94. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  95. c.Assert(d2.Leave(false), checker.IsNil)
  96. info, err = d2.SwarmInfo()
  97. c.Assert(err, checker.IsNil)
  98. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
  99. // change spec, don't change tokens
  100. d1.UpdateSwarm(c, func(s *swarm.Spec) {})
  101. err = d2.Join(swarm.JoinRequest{RemoteAddrs: []string{d1.ListenAddr}})
  102. c.Assert(err, checker.NotNil)
  103. c.Assert(err.Error(), checker.Contains, "join token is necessary")
  104. info, err = d2.SwarmInfo()
  105. c.Assert(err, checker.IsNil)
  106. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
  107. c.Assert(d2.Join(swarm.JoinRequest{JoinToken: workerToken, RemoteAddrs: []string{d1.ListenAddr}}), checker.IsNil)
  108. info, err = d2.SwarmInfo()
  109. c.Assert(err, checker.IsNil)
  110. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  111. c.Assert(d2.Leave(false), checker.IsNil)
  112. info, err = d2.SwarmInfo()
  113. c.Assert(err, checker.IsNil)
  114. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
  115. }
  116. func (s *DockerSwarmSuite) TestAPISwarmCAHash(c *check.C) {
  117. d1 := s.AddDaemon(c, true, true)
  118. d2 := s.AddDaemon(c, false, false)
  119. splitToken := strings.Split(d1.JoinTokens(c).Worker, "-")
  120. splitToken[2] = "1kxftv4ofnc6mt30lmgipg6ngf9luhwqopfk1tz6bdmnkubg0e"
  121. replacementToken := strings.Join(splitToken, "-")
  122. err := d2.Join(swarm.JoinRequest{JoinToken: replacementToken, RemoteAddrs: []string{d1.ListenAddr}})
  123. c.Assert(err, checker.NotNil)
  124. c.Assert(err.Error(), checker.Contains, "remote CA does not match fingerprint")
  125. }
  126. func (s *DockerSwarmSuite) TestAPISwarmPromoteDemote(c *check.C) {
  127. d1 := s.AddDaemon(c, false, false)
  128. c.Assert(d1.Init(swarm.InitRequest{}), checker.IsNil)
  129. d2 := s.AddDaemon(c, true, false)
  130. info, err := d2.SwarmInfo()
  131. c.Assert(err, checker.IsNil)
  132. c.Assert(info.ControlAvailable, checker.False)
  133. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  134. d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
  135. n.Spec.Role = swarm.NodeRoleManager
  136. })
  137. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckControlAvailable, checker.True)
  138. d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
  139. n.Spec.Role = swarm.NodeRoleWorker
  140. })
  141. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckControlAvailable, checker.False)
  142. // Demoting last node should fail
  143. node := d1.GetNode(c, d1.NodeID)
  144. node.Spec.Role = swarm.NodeRoleWorker
  145. url := fmt.Sprintf("/nodes/%s/update?version=%d", node.ID, node.Version.Index)
  146. status, out, err := d1.SockRequest("POST", url, node.Spec)
  147. c.Assert(err, checker.IsNil)
  148. c.Assert(status, checker.Equals, http.StatusInternalServerError, check.Commentf("output: %q", string(out)))
  149. c.Assert(string(out), checker.Contains, "last manager of the swarm")
  150. info, err = d1.SwarmInfo()
  151. c.Assert(err, checker.IsNil)
  152. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  153. c.Assert(info.ControlAvailable, checker.True)
  154. // Promote already demoted node
  155. d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
  156. n.Spec.Role = swarm.NodeRoleManager
  157. })
  158. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckControlAvailable, checker.True)
  159. }
  160. func (s *DockerSwarmSuite) TestAPISwarmServicesEmptyList(c *check.C) {
  161. d := s.AddDaemon(c, true, true)
  162. services := d.ListServices(c)
  163. c.Assert(services, checker.NotNil)
  164. c.Assert(len(services), checker.Equals, 0, check.Commentf("services: %#v", services))
  165. }
  166. func (s *DockerSwarmSuite) TestAPISwarmServicesCreate(c *check.C) {
  167. d := s.AddDaemon(c, true, true)
  168. instances := 2
  169. id := d.CreateService(c, simpleTestService, setInstances(instances))
  170. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
  171. service := d.GetService(c, id)
  172. instances = 5
  173. d.UpdateService(c, service, setInstances(instances))
  174. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
  175. d.RemoveService(c, service.ID)
  176. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 0)
  177. }
  178. func (s *DockerSwarmSuite) TestAPISwarmServicesMultipleAgents(c *check.C) {
  179. d1 := s.AddDaemon(c, true, true)
  180. d2 := s.AddDaemon(c, true, false)
  181. d3 := s.AddDaemon(c, true, false)
  182. time.Sleep(1 * time.Second) // make sure all daemons are ready to accept tasks
  183. instances := 9
  184. id := d1.CreateService(c, simpleTestService, setInstances(instances))
  185. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.GreaterThan, 0)
  186. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.GreaterThan, 0)
  187. waitAndAssert(c, defaultReconciliationTimeout, d3.CheckActiveContainerCount, checker.GreaterThan, 0)
  188. waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount, d3.CheckActiveContainerCount), checker.Equals, instances)
  189. // reconciliation on d2 node down
  190. d2.Stop(c)
  191. waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d3.CheckActiveContainerCount), checker.Equals, instances)
  192. // test downscaling
  193. instances = 5
  194. d1.UpdateService(c, d1.GetService(c, id), setInstances(instances))
  195. waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d3.CheckActiveContainerCount), checker.Equals, instances)
  196. }
  197. func (s *DockerSwarmSuite) TestAPISwarmServicesCreateGlobal(c *check.C) {
  198. d1 := s.AddDaemon(c, true, true)
  199. d2 := s.AddDaemon(c, true, false)
  200. d3 := s.AddDaemon(c, true, false)
  201. d1.CreateService(c, simpleTestService, setGlobalMode)
  202. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, 1)
  203. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.Equals, 1)
  204. waitAndAssert(c, defaultReconciliationTimeout, d3.CheckActiveContainerCount, checker.Equals, 1)
  205. d4 := s.AddDaemon(c, true, false)
  206. d5 := s.AddDaemon(c, true, false)
  207. waitAndAssert(c, defaultReconciliationTimeout, d4.CheckActiveContainerCount, checker.Equals, 1)
  208. waitAndAssert(c, defaultReconciliationTimeout, d5.CheckActiveContainerCount, checker.Equals, 1)
  209. }
  210. func (s *DockerSwarmSuite) TestAPISwarmServicesUpdate(c *check.C) {
  211. const nodeCount = 3
  212. var daemons [nodeCount]*daemon.Swarm
  213. for i := 0; i < nodeCount; i++ {
  214. daemons[i] = s.AddDaemon(c, true, i == 0)
  215. }
  216. // wait for nodes ready
  217. waitAndAssert(c, 5*time.Second, daemons[0].CheckNodeReadyCount, checker.Equals, nodeCount)
  218. // service image at start
  219. image1 := "busybox:latest"
  220. // target image in update
  221. image2 := "busybox:test"
  222. // create a different tag
  223. for _, d := range daemons {
  224. out, err := d.Cmd("tag", image1, image2)
  225. c.Assert(err, checker.IsNil, check.Commentf(out))
  226. }
  227. // create service
  228. instances := 5
  229. parallelism := 2
  230. id := daemons[0].CreateService(c, serviceForUpdate, setInstances(instances))
  231. // wait for tasks ready
  232. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
  233. map[string]int{image1: instances})
  234. // issue service update
  235. service := daemons[0].GetService(c, id)
  236. daemons[0].UpdateService(c, service, setImage(image2))
  237. // first batch
  238. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
  239. map[string]int{image1: instances - parallelism, image2: parallelism})
  240. // 2nd batch
  241. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
  242. map[string]int{image1: instances - 2*parallelism, image2: 2 * parallelism})
  243. // 3nd batch
  244. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
  245. map[string]int{image2: instances})
  246. // Roll back to the previous version. This uses the CLI because
  247. // rollback is a client-side operation.
  248. out, err := daemons[0].Cmd("service", "update", "--rollback", id)
  249. c.Assert(err, checker.IsNil, check.Commentf(out))
  250. // first batch
  251. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
  252. map[string]int{image2: instances - parallelism, image1: parallelism})
  253. // 2nd batch
  254. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
  255. map[string]int{image2: instances - 2*parallelism, image1: 2 * parallelism})
  256. // 3nd batch
  257. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
  258. map[string]int{image1: instances})
  259. }
  260. func (s *DockerSwarmSuite) TestAPISwarmServicesFailedUpdate(c *check.C) {
  261. const nodeCount = 3
  262. var daemons [nodeCount]*daemon.Swarm
  263. for i := 0; i < nodeCount; i++ {
  264. daemons[i] = s.AddDaemon(c, true, i == 0)
  265. }
  266. // wait for nodes ready
  267. waitAndAssert(c, 5*time.Second, daemons[0].CheckNodeReadyCount, checker.Equals, nodeCount)
  268. // service image at start
  269. image1 := "busybox:latest"
  270. // target image in update
  271. image2 := "busybox:badtag"
  272. // create service
  273. instances := 5
  274. id := daemons[0].CreateService(c, serviceForUpdate, setInstances(instances))
  275. // wait for tasks ready
  276. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
  277. map[string]int{image1: instances})
  278. // issue service update
  279. service := daemons[0].GetService(c, id)
  280. daemons[0].UpdateService(c, service, setImage(image2), setFailureAction(swarm.UpdateFailureActionPause), setMaxFailureRatio(0.25), setParallelism(1))
  281. // should update 2 tasks and then pause
  282. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckServiceUpdateState(id), checker.Equals, swarm.UpdateStatePaused)
  283. v, _ := daemons[0].CheckServiceRunningTasks(id)(c)
  284. c.Assert(v, checker.Equals, instances-2)
  285. // Roll back to the previous version. This uses the CLI because
  286. // rollback is a client-side operation.
  287. out, err := daemons[0].Cmd("service", "update", "--rollback", id)
  288. c.Assert(err, checker.IsNil, check.Commentf(out))
  289. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckRunningTaskImages, checker.DeepEquals,
  290. map[string]int{image1: instances})
  291. }
  292. func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintRole(c *check.C) {
  293. const nodeCount = 3
  294. var daemons [nodeCount]*daemon.Swarm
  295. for i := 0; i < nodeCount; i++ {
  296. daemons[i] = s.AddDaemon(c, true, i == 0)
  297. }
  298. // wait for nodes ready
  299. waitAndAssert(c, 5*time.Second, daemons[0].CheckNodeReadyCount, checker.Equals, nodeCount)
  300. // create service
  301. constraints := []string{"node.role==worker"}
  302. instances := 3
  303. id := daemons[0].CreateService(c, simpleTestService, setConstraints(constraints), setInstances(instances))
  304. // wait for tasks ready
  305. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckServiceRunningTasks(id), checker.Equals, instances)
  306. // validate tasks are running on worker nodes
  307. tasks := daemons[0].GetServiceTasks(c, id)
  308. for _, task := range tasks {
  309. node := daemons[0].GetNode(c, task.NodeID)
  310. c.Assert(node.Spec.Role, checker.Equals, swarm.NodeRoleWorker)
  311. }
  312. //remove service
  313. daemons[0].RemoveService(c, id)
  314. // create service
  315. constraints = []string{"node.role!=worker"}
  316. id = daemons[0].CreateService(c, simpleTestService, setConstraints(constraints), setInstances(instances))
  317. // wait for tasks ready
  318. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckServiceRunningTasks(id), checker.Equals, instances)
  319. tasks = daemons[0].GetServiceTasks(c, id)
  320. // validate tasks are running on manager nodes
  321. for _, task := range tasks {
  322. node := daemons[0].GetNode(c, task.NodeID)
  323. c.Assert(node.Spec.Role, checker.Equals, swarm.NodeRoleManager)
  324. }
  325. //remove service
  326. daemons[0].RemoveService(c, id)
  327. // create service
  328. constraints = []string{"node.role==nosuchrole"}
  329. id = daemons[0].CreateService(c, simpleTestService, setConstraints(constraints), setInstances(instances))
  330. // wait for tasks created
  331. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckServiceTasks(id), checker.Equals, instances)
  332. // let scheduler try
  333. time.Sleep(250 * time.Millisecond)
  334. // validate tasks are not assigned to any node
  335. tasks = daemons[0].GetServiceTasks(c, id)
  336. for _, task := range tasks {
  337. c.Assert(task.NodeID, checker.Equals, "")
  338. }
  339. }
  340. func (s *DockerSwarmSuite) TestAPISwarmServiceConstraintLabel(c *check.C) {
  341. const nodeCount = 3
  342. var daemons [nodeCount]*daemon.Swarm
  343. for i := 0; i < nodeCount; i++ {
  344. daemons[i] = s.AddDaemon(c, true, i == 0)
  345. }
  346. // wait for nodes ready
  347. waitAndAssert(c, 5*time.Second, daemons[0].CheckNodeReadyCount, checker.Equals, nodeCount)
  348. nodes := daemons[0].ListNodes(c)
  349. c.Assert(len(nodes), checker.Equals, nodeCount)
  350. // add labels to nodes
  351. daemons[0].UpdateNode(c, nodes[0].ID, func(n *swarm.Node) {
  352. n.Spec.Annotations.Labels = map[string]string{
  353. "security": "high",
  354. }
  355. })
  356. for i := 1; i < nodeCount; i++ {
  357. daemons[0].UpdateNode(c, nodes[i].ID, func(n *swarm.Node) {
  358. n.Spec.Annotations.Labels = map[string]string{
  359. "security": "low",
  360. }
  361. })
  362. }
  363. // create service
  364. instances := 3
  365. constraints := []string{"node.labels.security==high"}
  366. id := daemons[0].CreateService(c, simpleTestService, setConstraints(constraints), setInstances(instances))
  367. // wait for tasks ready
  368. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckServiceRunningTasks(id), checker.Equals, instances)
  369. tasks := daemons[0].GetServiceTasks(c, id)
  370. // validate all tasks are running on nodes[0]
  371. for _, task := range tasks {
  372. c.Assert(task.NodeID, checker.Equals, nodes[0].ID)
  373. }
  374. //remove service
  375. daemons[0].RemoveService(c, id)
  376. // create service
  377. constraints = []string{"node.labels.security!=high"}
  378. id = daemons[0].CreateService(c, simpleTestService, setConstraints(constraints), setInstances(instances))
  379. // wait for tasks ready
  380. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckServiceRunningTasks(id), checker.Equals, instances)
  381. tasks = daemons[0].GetServiceTasks(c, id)
  382. // validate all tasks are NOT running on nodes[0]
  383. for _, task := range tasks {
  384. c.Assert(task.NodeID, checker.Not(checker.Equals), nodes[0].ID)
  385. }
  386. //remove service
  387. daemons[0].RemoveService(c, id)
  388. constraints = []string{"node.labels.security==medium"}
  389. id = daemons[0].CreateService(c, simpleTestService, setConstraints(constraints), setInstances(instances))
  390. // wait for tasks created
  391. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckServiceTasks(id), checker.Equals, instances)
  392. // let scheduler try
  393. time.Sleep(250 * time.Millisecond)
  394. tasks = daemons[0].GetServiceTasks(c, id)
  395. // validate tasks are not assigned
  396. for _, task := range tasks {
  397. c.Assert(task.NodeID, checker.Equals, "")
  398. }
  399. //remove service
  400. daemons[0].RemoveService(c, id)
  401. // multiple constraints
  402. constraints = []string{
  403. "node.labels.security==high",
  404. fmt.Sprintf("node.id==%s", nodes[1].ID),
  405. }
  406. id = daemons[0].CreateService(c, simpleTestService, setConstraints(constraints), setInstances(instances))
  407. // wait for tasks created
  408. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckServiceTasks(id), checker.Equals, instances)
  409. // let scheduler try
  410. time.Sleep(250 * time.Millisecond)
  411. tasks = daemons[0].GetServiceTasks(c, id)
  412. // validate tasks are not assigned
  413. for _, task := range tasks {
  414. c.Assert(task.NodeID, checker.Equals, "")
  415. }
  416. // make nodes[1] fulfills the constraints
  417. daemons[0].UpdateNode(c, nodes[1].ID, func(n *swarm.Node) {
  418. n.Spec.Annotations.Labels = map[string]string{
  419. "security": "high",
  420. }
  421. })
  422. // wait for tasks ready
  423. waitAndAssert(c, defaultReconciliationTimeout, daemons[0].CheckServiceRunningTasks(id), checker.Equals, instances)
  424. tasks = daemons[0].GetServiceTasks(c, id)
  425. for _, task := range tasks {
  426. c.Assert(task.NodeID, checker.Equals, nodes[1].ID)
  427. }
  428. }
  429. func (s *DockerSwarmSuite) TestAPISwarmServicesStateReporting(c *check.C) {
  430. testRequires(c, SameHostDaemon)
  431. testRequires(c, DaemonIsLinux)
  432. d1 := s.AddDaemon(c, true, true)
  433. d2 := s.AddDaemon(c, true, true)
  434. d3 := s.AddDaemon(c, true, false)
  435. time.Sleep(1 * time.Second) // make sure all daemons are ready to accept
  436. instances := 9
  437. d1.CreateService(c, simpleTestService, setInstances(instances))
  438. waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount, d3.CheckActiveContainerCount), checker.Equals, instances)
  439. getContainers := func() map[string]*daemon.Swarm {
  440. m := make(map[string]*daemon.Swarm)
  441. for _, d := range []*daemon.Swarm{d1, d2, d3} {
  442. for _, id := range d.ActiveContainers() {
  443. m[id] = d
  444. }
  445. }
  446. return m
  447. }
  448. containers := getContainers()
  449. c.Assert(containers, checker.HasLen, instances)
  450. var toRemove string
  451. for i := range containers {
  452. toRemove = i
  453. }
  454. _, err := containers[toRemove].Cmd("stop", toRemove)
  455. c.Assert(err, checker.IsNil)
  456. waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount, d3.CheckActiveContainerCount), checker.Equals, instances)
  457. containers2 := getContainers()
  458. c.Assert(containers2, checker.HasLen, instances)
  459. for i := range containers {
  460. if i == toRemove {
  461. c.Assert(containers2[i], checker.IsNil)
  462. } else {
  463. c.Assert(containers2[i], checker.NotNil)
  464. }
  465. }
  466. containers = containers2
  467. for i := range containers {
  468. toRemove = i
  469. }
  470. // try with killing process outside of docker
  471. pidStr, err := containers[toRemove].Cmd("inspect", "-f", "{{.State.Pid}}", toRemove)
  472. c.Assert(err, checker.IsNil)
  473. pid, err := strconv.Atoi(strings.TrimSpace(pidStr))
  474. c.Assert(err, checker.IsNil)
  475. c.Assert(syscall.Kill(pid, syscall.SIGKILL), checker.IsNil)
  476. time.Sleep(time.Second) // give some time to handle the signal
  477. waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount, d3.CheckActiveContainerCount), checker.Equals, instances)
  478. containers2 = getContainers()
  479. c.Assert(containers2, checker.HasLen, instances)
  480. for i := range containers {
  481. if i == toRemove {
  482. c.Assert(containers2[i], checker.IsNil)
  483. } else {
  484. c.Assert(containers2[i], checker.NotNil)
  485. }
  486. }
  487. }
  488. func (s *DockerSwarmSuite) TestAPISwarmLeaderProxy(c *check.C) {
  489. // add three managers, one of these is leader
  490. d1 := s.AddDaemon(c, true, true)
  491. d2 := s.AddDaemon(c, true, true)
  492. d3 := s.AddDaemon(c, true, true)
  493. // start a service by hitting each of the 3 managers
  494. d1.CreateService(c, simpleTestService, func(s *swarm.Service) {
  495. s.Spec.Name = "test1"
  496. })
  497. d2.CreateService(c, simpleTestService, func(s *swarm.Service) {
  498. s.Spec.Name = "test2"
  499. })
  500. d3.CreateService(c, simpleTestService, func(s *swarm.Service) {
  501. s.Spec.Name = "test3"
  502. })
  503. // 3 services should be started now, because the requests were proxied to leader
  504. // query each node and make sure it returns 3 services
  505. for _, d := range []*daemon.Swarm{d1, d2, d3} {
  506. services := d.ListServices(c)
  507. c.Assert(services, checker.HasLen, 3)
  508. }
  509. }
  510. func (s *DockerSwarmSuite) TestAPISwarmLeaderElection(c *check.C) {
  511. // Create 3 nodes
  512. d1 := s.AddDaemon(c, true, true)
  513. d2 := s.AddDaemon(c, true, true)
  514. d3 := s.AddDaemon(c, true, true)
  515. // assert that the first node we made is the leader, and the other two are followers
  516. c.Assert(d1.GetNode(c, d1.NodeID).ManagerStatus.Leader, checker.True)
  517. c.Assert(d1.GetNode(c, d2.NodeID).ManagerStatus.Leader, checker.False)
  518. c.Assert(d1.GetNode(c, d3.NodeID).ManagerStatus.Leader, checker.False)
  519. d1.Stop(c)
  520. var (
  521. leader *daemon.Swarm // keep track of leader
  522. followers []*daemon.Swarm // keep track of followers
  523. )
  524. checkLeader := func(nodes ...*daemon.Swarm) checkF {
  525. return func(c *check.C) (interface{}, check.CommentInterface) {
  526. // clear these out before each run
  527. leader = nil
  528. followers = nil
  529. for _, d := range nodes {
  530. if d.GetNode(c, d.NodeID).ManagerStatus.Leader {
  531. leader = d
  532. } else {
  533. followers = append(followers, d)
  534. }
  535. }
  536. if leader == nil {
  537. return false, check.Commentf("no leader elected")
  538. }
  539. return true, check.Commentf("elected %v", leader.ID())
  540. }
  541. }
  542. // wait for an election to occur
  543. waitAndAssert(c, defaultReconciliationTimeout, checkLeader(d2, d3), checker.True)
  544. // assert that we have a new leader
  545. c.Assert(leader, checker.NotNil)
  546. // Keep track of the current leader, since we want that to be chosen.
  547. stableleader := leader
  548. // add the d1, the initial leader, back
  549. d1.Start(c)
  550. // TODO(stevvooe): may need to wait for rejoin here
  551. // wait for possible election
  552. waitAndAssert(c, defaultReconciliationTimeout, checkLeader(d1, d2, d3), checker.True)
  553. // pick out the leader and the followers again
  554. // verify that we still only have 1 leader and 2 followers
  555. c.Assert(leader, checker.NotNil)
  556. c.Assert(followers, checker.HasLen, 2)
  557. // and that after we added d1 back, the leader hasn't changed
  558. c.Assert(leader.NodeID, checker.Equals, stableleader.NodeID)
  559. }
  560. func (s *DockerSwarmSuite) TestAPISwarmRaftQuorum(c *check.C) {
  561. d1 := s.AddDaemon(c, true, true)
  562. d2 := s.AddDaemon(c, true, true)
  563. d3 := s.AddDaemon(c, true, true)
  564. d1.CreateService(c, simpleTestService)
  565. d2.Stop(c)
  566. // make sure there is a leader
  567. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckLeader, checker.IsNil)
  568. d1.CreateService(c, simpleTestService, func(s *swarm.Service) {
  569. s.Spec.Name = "top1"
  570. })
  571. d3.Stop(c)
  572. // make sure there is a leader
  573. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckLeader, checker.IsNil)
  574. var service swarm.Service
  575. simpleTestService(&service)
  576. service.Spec.Name = "top2"
  577. status, out, err := d1.SockRequest("POST", "/services/create", service.Spec)
  578. c.Assert(err, checker.IsNil)
  579. c.Assert(status, checker.Equals, http.StatusInternalServerError, check.Commentf("deadline exceeded", string(out)))
  580. d2.Start(c)
  581. // make sure there is a leader
  582. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckLeader, checker.IsNil)
  583. d1.CreateService(c, simpleTestService, func(s *swarm.Service) {
  584. s.Spec.Name = "top3"
  585. })
  586. }
  587. func (s *DockerSwarmSuite) TestAPISwarmListNodes(c *check.C) {
  588. d1 := s.AddDaemon(c, true, true)
  589. d2 := s.AddDaemon(c, true, false)
  590. d3 := s.AddDaemon(c, true, false)
  591. nodes := d1.ListNodes(c)
  592. c.Assert(len(nodes), checker.Equals, 3, check.Commentf("nodes: %#v", nodes))
  593. loop0:
  594. for _, n := range nodes {
  595. for _, d := range []*daemon.Swarm{d1, d2, d3} {
  596. if n.ID == d.NodeID {
  597. continue loop0
  598. }
  599. }
  600. c.Errorf("unknown nodeID %v", n.ID)
  601. }
  602. }
  603. func (s *DockerSwarmSuite) TestAPISwarmNodeUpdate(c *check.C) {
  604. d := s.AddDaemon(c, true, true)
  605. nodes := d.ListNodes(c)
  606. d.UpdateNode(c, nodes[0].ID, func(n *swarm.Node) {
  607. n.Spec.Availability = swarm.NodeAvailabilityPause
  608. })
  609. n := d.GetNode(c, nodes[0].ID)
  610. c.Assert(n.Spec.Availability, checker.Equals, swarm.NodeAvailabilityPause)
  611. }
  612. func (s *DockerSwarmSuite) TestAPISwarmNodeRemove(c *check.C) {
  613. testRequires(c, Network)
  614. d1 := s.AddDaemon(c, true, true)
  615. d2 := s.AddDaemon(c, true, false)
  616. _ = s.AddDaemon(c, true, false)
  617. nodes := d1.ListNodes(c)
  618. c.Assert(len(nodes), checker.Equals, 3, check.Commentf("nodes: %#v", nodes))
  619. // Getting the info so we can take the NodeID
  620. d2Info, err := d2.SwarmInfo()
  621. c.Assert(err, checker.IsNil)
  622. // forceful removal of d2 should work
  623. d1.RemoveNode(c, d2Info.NodeID, true)
  624. nodes = d1.ListNodes(c)
  625. c.Assert(len(nodes), checker.Equals, 2, check.Commentf("nodes: %#v", nodes))
  626. // Restart the node that was removed
  627. d2.Restart(c)
  628. // Give some time for the node to rejoin
  629. time.Sleep(1 * time.Second)
  630. // Make sure the node didn't rejoin
  631. nodes = d1.ListNodes(c)
  632. c.Assert(len(nodes), checker.Equals, 2, check.Commentf("nodes: %#v", nodes))
  633. }
  634. func (s *DockerSwarmSuite) TestAPISwarmNodeDrainPause(c *check.C) {
  635. d1 := s.AddDaemon(c, true, true)
  636. d2 := s.AddDaemon(c, true, false)
  637. time.Sleep(1 * time.Second) // make sure all daemons are ready to accept tasks
  638. // start a service, expect balanced distribution
  639. instances := 8
  640. id := d1.CreateService(c, simpleTestService, setInstances(instances))
  641. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.GreaterThan, 0)
  642. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.GreaterThan, 0)
  643. waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals, instances)
  644. // drain d2, all containers should move to d1
  645. d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
  646. n.Spec.Availability = swarm.NodeAvailabilityDrain
  647. })
  648. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances)
  649. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.Equals, 0)
  650. // set d2 back to active
  651. d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
  652. n.Spec.Availability = swarm.NodeAvailabilityActive
  653. })
  654. instances = 1
  655. d1.UpdateService(c, d1.GetService(c, id), setInstances(instances))
  656. waitAndAssert(c, defaultReconciliationTimeout*2, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals, instances)
  657. instances = 8
  658. d1.UpdateService(c, d1.GetService(c, id), setInstances(instances))
  659. // drained node first so we don't get any old containers
  660. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.GreaterThan, 0)
  661. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.GreaterThan, 0)
  662. waitAndAssert(c, defaultReconciliationTimeout*2, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals, instances)
  663. d2ContainerCount := len(d2.ActiveContainers())
  664. // set d2 to paused, scale service up, only d1 gets new tasks
  665. d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
  666. n.Spec.Availability = swarm.NodeAvailabilityPause
  667. })
  668. instances = 14
  669. d1.UpdateService(c, d1.GetService(c, id), setInstances(instances))
  670. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances-d2ContainerCount)
  671. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.Equals, d2ContainerCount)
  672. }
  673. func (s *DockerSwarmSuite) TestAPISwarmLeaveRemovesContainer(c *check.C) {
  674. d := s.AddDaemon(c, true, true)
  675. instances := 2
  676. d.CreateService(c, simpleTestService, setInstances(instances))
  677. id, err := d.Cmd("run", "-d", "busybox", "top")
  678. c.Assert(err, checker.IsNil)
  679. id = strings.TrimSpace(id)
  680. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances+1)
  681. c.Assert(d.Leave(false), checker.NotNil)
  682. c.Assert(d.Leave(true), checker.IsNil)
  683. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, 1)
  684. id2, err := d.Cmd("ps", "-q")
  685. c.Assert(err, checker.IsNil)
  686. c.Assert(id, checker.HasPrefix, strings.TrimSpace(id2))
  687. }
  688. // #23629
  689. func (s *DockerSwarmSuite) TestAPISwarmLeaveOnPendingJoin(c *check.C) {
  690. testRequires(c, Network)
  691. s.AddDaemon(c, true, true)
  692. d2 := s.AddDaemon(c, false, false)
  693. id, err := d2.Cmd("run", "-d", "busybox", "top")
  694. c.Assert(err, checker.IsNil)
  695. id = strings.TrimSpace(id)
  696. err = d2.Join(swarm.JoinRequest{
  697. RemoteAddrs: []string{"123.123.123.123:1234"},
  698. })
  699. c.Assert(err, check.NotNil)
  700. c.Assert(err.Error(), checker.Contains, "Timeout was reached")
  701. info, err := d2.SwarmInfo()
  702. c.Assert(err, checker.IsNil)
  703. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStatePending)
  704. c.Assert(d2.Leave(true), checker.IsNil)
  705. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.Equals, 1)
  706. id2, err := d2.Cmd("ps", "-q")
  707. c.Assert(err, checker.IsNil)
  708. c.Assert(id, checker.HasPrefix, strings.TrimSpace(id2))
  709. }
  710. // #23705
  711. func (s *DockerSwarmSuite) TestAPISwarmRestoreOnPendingJoin(c *check.C) {
  712. testRequires(c, Network)
  713. d := s.AddDaemon(c, false, false)
  714. err := d.Join(swarm.JoinRequest{
  715. RemoteAddrs: []string{"123.123.123.123:1234"},
  716. })
  717. c.Assert(err, check.NotNil)
  718. c.Assert(err.Error(), checker.Contains, "Timeout was reached")
  719. waitAndAssert(c, defaultReconciliationTimeout, d.CheckLocalNodeState, checker.Equals, swarm.LocalNodeStatePending)
  720. d.Stop(c)
  721. d.Start(c)
  722. info, err := d.SwarmInfo()
  723. c.Assert(err, checker.IsNil)
  724. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateInactive)
  725. }
  726. func (s *DockerSwarmSuite) TestAPISwarmManagerRestore(c *check.C) {
  727. d1 := s.AddDaemon(c, true, true)
  728. instances := 2
  729. id := d1.CreateService(c, simpleTestService, setInstances(instances))
  730. d1.GetService(c, id)
  731. d1.Stop(c)
  732. d1.Start(c)
  733. d1.GetService(c, id)
  734. d2 := s.AddDaemon(c, true, true)
  735. d2.GetService(c, id)
  736. d2.Stop(c)
  737. d2.Start(c)
  738. d2.GetService(c, id)
  739. d3 := s.AddDaemon(c, true, true)
  740. d3.GetService(c, id)
  741. d3.Stop(c)
  742. d3.Start(c)
  743. d3.GetService(c, id)
  744. d3.Kill()
  745. time.Sleep(1 * time.Second) // time to handle signal
  746. d3.Start(c)
  747. d3.GetService(c, id)
  748. }
  749. func (s *DockerSwarmSuite) TestAPISwarmScaleNoRollingUpdate(c *check.C) {
  750. d := s.AddDaemon(c, true, true)
  751. instances := 2
  752. id := d.CreateService(c, simpleTestService, setInstances(instances))
  753. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
  754. containers := d.ActiveContainers()
  755. instances = 4
  756. d.UpdateService(c, d.GetService(c, id), setInstances(instances))
  757. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
  758. containers2 := d.ActiveContainers()
  759. loop0:
  760. for _, c1 := range containers {
  761. for _, c2 := range containers2 {
  762. if c1 == c2 {
  763. continue loop0
  764. }
  765. }
  766. c.Errorf("container %v not found in new set %#v", c1, containers2)
  767. }
  768. }
  769. func (s *DockerSwarmSuite) TestAPISwarmInvalidAddress(c *check.C) {
  770. d := s.AddDaemon(c, false, false)
  771. req := swarm.InitRequest{
  772. ListenAddr: "",
  773. }
  774. status, _, err := d.SockRequest("POST", "/swarm/init", req)
  775. c.Assert(err, checker.IsNil)
  776. c.Assert(status, checker.Equals, http.StatusBadRequest)
  777. req2 := swarm.JoinRequest{
  778. ListenAddr: "0.0.0.0:2377",
  779. RemoteAddrs: []string{""},
  780. }
  781. status, _, err = d.SockRequest("POST", "/swarm/join", req2)
  782. c.Assert(err, checker.IsNil)
  783. c.Assert(status, checker.Equals, http.StatusBadRequest)
  784. }
  785. func (s *DockerSwarmSuite) TestAPISwarmForceNewCluster(c *check.C) {
  786. d1 := s.AddDaemon(c, true, true)
  787. d2 := s.AddDaemon(c, true, true)
  788. instances := 2
  789. id := d1.CreateService(c, simpleTestService, setInstances(instances))
  790. waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d2.CheckActiveContainerCount), checker.Equals, instances)
  791. // drain d2, all containers should move to d1
  792. d1.UpdateNode(c, d2.NodeID, func(n *swarm.Node) {
  793. n.Spec.Availability = swarm.NodeAvailabilityDrain
  794. })
  795. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances)
  796. waitAndAssert(c, defaultReconciliationTimeout, d2.CheckActiveContainerCount, checker.Equals, 0)
  797. d2.Stop(c)
  798. c.Assert(d1.Init(swarm.InitRequest{
  799. ForceNewCluster: true,
  800. Spec: swarm.Spec{},
  801. }), checker.IsNil)
  802. waitAndAssert(c, defaultReconciliationTimeout, d1.CheckActiveContainerCount, checker.Equals, instances)
  803. d3 := s.AddDaemon(c, true, true)
  804. info, err := d3.SwarmInfo()
  805. c.Assert(err, checker.IsNil)
  806. c.Assert(info.ControlAvailable, checker.True)
  807. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  808. instances = 4
  809. d3.UpdateService(c, d3.GetService(c, id), setInstances(instances))
  810. waitAndAssert(c, defaultReconciliationTimeout, reducedCheck(sumAsIntegers, d1.CheckActiveContainerCount, d3.CheckActiveContainerCount), checker.Equals, instances)
  811. }
  812. func simpleTestService(s *swarm.Service) {
  813. ureplicas := uint64(1)
  814. restartDelay := time.Duration(100 * time.Millisecond)
  815. s.Spec = swarm.ServiceSpec{
  816. TaskTemplate: swarm.TaskSpec{
  817. ContainerSpec: swarm.ContainerSpec{
  818. Image: "busybox:latest",
  819. Command: []string{"/bin/top"},
  820. },
  821. RestartPolicy: &swarm.RestartPolicy{
  822. Delay: &restartDelay,
  823. },
  824. },
  825. Mode: swarm.ServiceMode{
  826. Replicated: &swarm.ReplicatedService{
  827. Replicas: &ureplicas,
  828. },
  829. },
  830. }
  831. s.Spec.Name = "top"
  832. }
  833. func serviceForUpdate(s *swarm.Service) {
  834. ureplicas := uint64(1)
  835. restartDelay := time.Duration(100 * time.Millisecond)
  836. s.Spec = swarm.ServiceSpec{
  837. TaskTemplate: swarm.TaskSpec{
  838. ContainerSpec: swarm.ContainerSpec{
  839. Image: "busybox:latest",
  840. Command: []string{"/bin/top"},
  841. },
  842. RestartPolicy: &swarm.RestartPolicy{
  843. Delay: &restartDelay,
  844. },
  845. },
  846. Mode: swarm.ServiceMode{
  847. Replicated: &swarm.ReplicatedService{
  848. Replicas: &ureplicas,
  849. },
  850. },
  851. UpdateConfig: &swarm.UpdateConfig{
  852. Parallelism: 2,
  853. Delay: 4 * time.Second,
  854. FailureAction: swarm.UpdateFailureActionContinue,
  855. },
  856. }
  857. s.Spec.Name = "updatetest"
  858. }
  859. func setInstances(replicas int) daemon.ServiceConstructor {
  860. ureplicas := uint64(replicas)
  861. return func(s *swarm.Service) {
  862. s.Spec.Mode = swarm.ServiceMode{
  863. Replicated: &swarm.ReplicatedService{
  864. Replicas: &ureplicas,
  865. },
  866. }
  867. }
  868. }
  869. func setImage(image string) daemon.ServiceConstructor {
  870. return func(s *swarm.Service) {
  871. s.Spec.TaskTemplate.ContainerSpec.Image = image
  872. }
  873. }
  874. func setFailureAction(failureAction string) daemon.ServiceConstructor {
  875. return func(s *swarm.Service) {
  876. s.Spec.UpdateConfig.FailureAction = failureAction
  877. }
  878. }
  879. func setMaxFailureRatio(maxFailureRatio float32) daemon.ServiceConstructor {
  880. return func(s *swarm.Service) {
  881. s.Spec.UpdateConfig.MaxFailureRatio = maxFailureRatio
  882. }
  883. }
  884. func setParallelism(parallelism uint64) daemon.ServiceConstructor {
  885. return func(s *swarm.Service) {
  886. s.Spec.UpdateConfig.Parallelism = parallelism
  887. }
  888. }
  889. func setConstraints(constraints []string) daemon.ServiceConstructor {
  890. return func(s *swarm.Service) {
  891. if s.Spec.TaskTemplate.Placement == nil {
  892. s.Spec.TaskTemplate.Placement = &swarm.Placement{}
  893. }
  894. s.Spec.TaskTemplate.Placement.Constraints = constraints
  895. }
  896. }
  897. func setGlobalMode(s *swarm.Service) {
  898. s.Spec.Mode = swarm.ServiceMode{
  899. Global: &swarm.GlobalService{},
  900. }
  901. }
  902. func checkClusterHealth(c *check.C, cl []*daemon.Swarm, managerCount, workerCount int) {
  903. var totalMCount, totalWCount int
  904. for _, d := range cl {
  905. var (
  906. info swarm.Info
  907. err error
  908. )
  909. // check info in a waitAndAssert, because if the cluster doesn't have a leader, `info` will return an error
  910. checkInfo := func(c *check.C) (interface{}, check.CommentInterface) {
  911. info, err = d.SwarmInfo()
  912. return err, check.Commentf("cluster not ready in time")
  913. }
  914. waitAndAssert(c, defaultReconciliationTimeout, checkInfo, checker.IsNil)
  915. if !info.ControlAvailable {
  916. totalWCount++
  917. continue
  918. }
  919. var leaderFound bool
  920. totalMCount++
  921. var mCount, wCount int
  922. for _, n := range d.ListNodes(c) {
  923. waitReady := func(c *check.C) (interface{}, check.CommentInterface) {
  924. if n.Status.State == swarm.NodeStateReady {
  925. return true, nil
  926. }
  927. nn := d.GetNode(c, n.ID)
  928. n = *nn
  929. return n.Status.State == swarm.NodeStateReady, check.Commentf("state of node %s, reported by %s", n.ID, d.Info.NodeID)
  930. }
  931. waitAndAssert(c, defaultReconciliationTimeout, waitReady, checker.True)
  932. waitActive := func(c *check.C) (interface{}, check.CommentInterface) {
  933. if n.Spec.Availability == swarm.NodeAvailabilityActive {
  934. return true, nil
  935. }
  936. nn := d.GetNode(c, n.ID)
  937. n = *nn
  938. return n.Spec.Availability == swarm.NodeAvailabilityActive, check.Commentf("availability of node %s, reported by %s", n.ID, d.Info.NodeID)
  939. }
  940. waitAndAssert(c, defaultReconciliationTimeout, waitActive, checker.True)
  941. if n.Spec.Role == swarm.NodeRoleManager {
  942. c.Assert(n.ManagerStatus, checker.NotNil, check.Commentf("manager status of node %s (manager), reported by %s", n.ID, d.Info.NodeID))
  943. if n.ManagerStatus.Leader {
  944. leaderFound = true
  945. }
  946. mCount++
  947. } else {
  948. c.Assert(n.ManagerStatus, checker.IsNil, check.Commentf("manager status of node %s (worker), reported by %s", n.ID, d.Info.NodeID))
  949. wCount++
  950. }
  951. }
  952. c.Assert(leaderFound, checker.True, check.Commentf("lack of leader reported by node %s", info.NodeID))
  953. c.Assert(mCount, checker.Equals, managerCount, check.Commentf("managers count reported by node %s", info.NodeID))
  954. c.Assert(wCount, checker.Equals, workerCount, check.Commentf("workers count reported by node %s", info.NodeID))
  955. }
  956. c.Assert(totalMCount, checker.Equals, managerCount)
  957. c.Assert(totalWCount, checker.Equals, workerCount)
  958. }
  959. func (s *DockerSwarmSuite) TestAPISwarmRestartCluster(c *check.C) {
  960. mCount, wCount := 5, 1
  961. var nodes []*daemon.Swarm
  962. for i := 0; i < mCount; i++ {
  963. manager := s.AddDaemon(c, true, true)
  964. info, err := manager.SwarmInfo()
  965. c.Assert(err, checker.IsNil)
  966. c.Assert(info.ControlAvailable, checker.True)
  967. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  968. nodes = append(nodes, manager)
  969. }
  970. for i := 0; i < wCount; i++ {
  971. worker := s.AddDaemon(c, true, false)
  972. info, err := worker.SwarmInfo()
  973. c.Assert(err, checker.IsNil)
  974. c.Assert(info.ControlAvailable, checker.False)
  975. c.Assert(info.LocalNodeState, checker.Equals, swarm.LocalNodeStateActive)
  976. nodes = append(nodes, worker)
  977. }
  978. // stop whole cluster
  979. {
  980. var wg sync.WaitGroup
  981. wg.Add(len(nodes))
  982. errs := make(chan error, len(nodes))
  983. for _, d := range nodes {
  984. go func(daemon *daemon.Swarm) {
  985. defer wg.Done()
  986. if err := daemon.StopWithError(); err != nil {
  987. errs <- err
  988. }
  989. // FIXME(vdemeester) This is duplicated…
  990. if root := os.Getenv("DOCKER_REMAP_ROOT"); root != "" {
  991. daemon.Root = filepath.Dir(daemon.Root)
  992. }
  993. }(d)
  994. }
  995. wg.Wait()
  996. close(errs)
  997. for err := range errs {
  998. c.Assert(err, check.IsNil)
  999. }
  1000. }
  1001. // start whole cluster
  1002. {
  1003. var wg sync.WaitGroup
  1004. wg.Add(len(nodes))
  1005. errs := make(chan error, len(nodes))
  1006. for _, d := range nodes {
  1007. go func(daemon *daemon.Swarm) {
  1008. defer wg.Done()
  1009. if err := daemon.StartWithError("--iptables=false"); err != nil {
  1010. errs <- err
  1011. }
  1012. }(d)
  1013. }
  1014. wg.Wait()
  1015. close(errs)
  1016. for err := range errs {
  1017. c.Assert(err, check.IsNil)
  1018. }
  1019. }
  1020. checkClusterHealth(c, nodes, mCount, wCount)
  1021. }
  1022. func (s *DockerSwarmSuite) TestAPISwarmServicesUpdateWithName(c *check.C) {
  1023. d := s.AddDaemon(c, true, true)
  1024. instances := 2
  1025. id := d.CreateService(c, simpleTestService, setInstances(instances))
  1026. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
  1027. service := d.GetService(c, id)
  1028. instances = 5
  1029. setInstances(instances)(service)
  1030. url := fmt.Sprintf("/services/%s/update?version=%d", service.Spec.Name, service.Version.Index)
  1031. status, out, err := d.SockRequest("POST", url, service.Spec)
  1032. c.Assert(err, checker.IsNil)
  1033. c.Assert(status, checker.Equals, http.StatusOK, check.Commentf("output: %q", string(out)))
  1034. waitAndAssert(c, defaultReconciliationTimeout, d.CheckActiveContainerCount, checker.Equals, instances)
  1035. }
  1036. func (s *DockerSwarmSuite) TestAPISwarmSecretsEmptyList(c *check.C) {
  1037. d := s.AddDaemon(c, true, true)
  1038. secrets := d.ListSecrets(c)
  1039. c.Assert(secrets, checker.NotNil)
  1040. c.Assert(len(secrets), checker.Equals, 0, check.Commentf("secrets: %#v", secrets))
  1041. }
  1042. func (s *DockerSwarmSuite) TestAPISwarmSecretsCreate(c *check.C) {
  1043. d := s.AddDaemon(c, true, true)
  1044. testName := "test_secret"
  1045. id := d.CreateSecret(c, swarm.SecretSpec{
  1046. swarm.Annotations{
  1047. Name: testName,
  1048. },
  1049. []byte("TESTINGDATA"),
  1050. })
  1051. c.Assert(id, checker.Not(checker.Equals), "", check.Commentf("secrets: %s", id))
  1052. secrets := d.ListSecrets(c)
  1053. c.Assert(len(secrets), checker.Equals, 1, check.Commentf("secrets: %#v", secrets))
  1054. name := secrets[0].Spec.Annotations.Name
  1055. c.Assert(name, checker.Equals, testName, check.Commentf("secret: %s", name))
  1056. }
  1057. func (s *DockerSwarmSuite) TestAPISwarmSecretsDelete(c *check.C) {
  1058. d := s.AddDaemon(c, true, true)
  1059. testName := "test_secret"
  1060. id := d.CreateSecret(c, swarm.SecretSpec{
  1061. swarm.Annotations{
  1062. Name: testName,
  1063. },
  1064. []byte("TESTINGDATA"),
  1065. })
  1066. c.Assert(id, checker.Not(checker.Equals), "", check.Commentf("secrets: %s", id))
  1067. secret := d.GetSecret(c, id)
  1068. c.Assert(secret.ID, checker.Equals, id, check.Commentf("secret: %v", secret))
  1069. d.DeleteSecret(c, secret.ID)
  1070. status, out, err := d.SockRequest("GET", "/secrets/"+id, nil)
  1071. c.Assert(err, checker.IsNil)
  1072. c.Assert(status, checker.Equals, http.StatusNotFound, check.Commentf("secret delete: %s", string(out)))
  1073. }