docker_api_swarm_test.go 46 KB

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