docker_api_swarm_test.go 47 KB

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