docker_api_swarm_test.go 44 KB

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