vagrant-skytap 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (327) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +4 -0
  3. data/lib/vagrant-skytap/action/add_vm_to_environment.rb +4 -4
  4. data/lib/vagrant-skytap/action/compose_environment.rb +131 -0
  5. data/lib/vagrant-skytap/action/create_environment.rb +3 -1
  6. data/lib/vagrant-skytap/action/initialize_api_client.rb +6 -5
  7. data/lib/vagrant-skytap/action/set_up_vm.rb +3 -1
  8. data/lib/vagrant-skytap/action/store_extra_data.rb +4 -2
  9. data/lib/vagrant-skytap/action.rb +4 -17
  10. data/lib/vagrant-skytap/api/environment.rb +53 -25
  11. data/lib/vagrant-skytap/api/vm.rb +9 -3
  12. data/lib/vagrant-skytap/command/up.rb +46 -30
  13. data/lib/vagrant-skytap/errors.rb +4 -0
  14. data/lib/vagrant-skytap/version.rb +1 -1
  15. data/locales/en.yml +5 -1
  16. data/spec/unit/actions/compose_environment_spec.rb +101 -0
  17. data/spec/unit/environment_spec.rb +26 -45
  18. data/spec/unit/support/shared/skytap_context.rb +5 -0
  19. data/vagrant-skytap.gemspec +3 -3
  20. metadata +9 -311
  21. data/.byebug_history +0 -256
  22. data/.project +0 -11
  23. data/_patches-20160112/0 +0 -388
  24. data/_patches-20160112/1 +0 -82
  25. data/_patches-20160112/2 +0 -239
  26. data/_patches-20160112/COMPLETED-ABOVE-THIS-LINE +0 -4
  27. data/_patches-20160112/COMPLETED-BELOW-THIS-LINE +0 -4
  28. data/_patches-20160112/CR-ABOVE-THIS-LINE +0 -4
  29. data/_patches-20160112/CR-BELOW-THIS-LINE +0 -4
  30. data/_patches-20160112/WIP-ABOVE-THIS-LINE +0 -4
  31. data/_patches-20160112/WIP-BELOW-THIS-LINE +0 -4
  32. data/_patches-20160112/acceptance-test-runner +0 -29
  33. data/_patches-20160112/ansible-1 +0 -92
  34. data/_patches-20160112/cache-api-client-in-up +0 -40
  35. data/_patches-20160112/dead-code-in-actions +0 -44
  36. data/_patches-20160112/debug-changes +0 -42
  37. data/_patches-20160112/demo-rails-app +0 -1276
  38. data/_patches-20160112/eng-10166-halt-spec +0 -40
  39. data/_patches-20160112/eng-10256 +0 -527
  40. data/_patches-20160112/eng-10256-2 +0 -162
  41. data/_patches-20160112/eng-10256-ubuntu-testing +0 -88
  42. data/_patches-20160112/eng-10269-test-stuff +0 -87
  43. data/_patches-20160112/eng-10269-wtf +0 -119
  44. data/_patches-20160112/eng-10369 +0 -143
  45. data/_patches-20160112/eng-10369-tmp +0 -60
  46. data/_patches-20160112/eng-10919 +0 -56
  47. data/_patches-20160112/eng-11177-fix-actions-requires +0 -44
  48. data/_patches-20160112/eng-11442 +0 -4
  49. data/_patches-20160112/eng-11616 +0 -403
  50. data/_patches-20160112/eng-11616-2 +0 -67
  51. data/_patches-20160112/eng-11616-actual +0 -184
  52. data/_patches-20160112/eng-11625a +0 -4
  53. data/_patches-20160112/eng-11711 +0 -85
  54. data/_patches-20160112/eng-12232-command-spec +0 -236
  55. data/_patches-20160112/eng-12235 +0 -83
  56. data/_patches-20160112/eng-12235-override-refactor +0 -140
  57. data/_patches-20160112/eng-12240 +0 -103
  58. data/_patches-20160112/eng-12249 +0 -40
  59. data/_patches-20160112/eng-12301 +0 -50
  60. data/_patches-20160112/eng-12843 +0 -95
  61. data/_patches-20160112/env-source +0 -112
  62. data/_patches-20160112/frickin-vagrant-spec +0 -163
  63. data/_patches-20160112/gem-pre-version +0 -14
  64. data/_patches-20160112/gems-old +0 -9
  65. data/_patches-20160112/googles-specs +0 -713
  66. data/_patches-20160112/local-configs-ignore +0 -61
  67. data/_patches-20160112/misc +0 -79
  68. data/_patches-20160112/network-unreachable +0 -31
  69. data/_patches-20160112/new-boxfile +0 -288
  70. data/_patches-20160112/parallelization-maybe +0 -198
  71. data/_patches-20160112/read-state +0 -23
  72. data/_patches-20160112/refactor-to-use-public_address-cap +0 -25
  73. data/_patches-20160112/series +0 -60
  74. data/_patches-20160112/status +0 -12
  75. data/_patches-20160112/test-move-env-data +0 -231
  76. data/_patches-20160112/test-vagrantfile-vm1 +0 -167
  77. data/_patches-20160112/the_version_in_0.1.13.pre1 +0 -598
  78. data/_patches-20160112/vagrant-spec-mock-api +0 -137
  79. data/_patches-20160112/vagrant-vmware-plugin +0 -233
  80. data/_patches-20160112/vagrantfile +0 -403
  81. data/_patches-20160112/vagrantfile-for-acceptance-tests +0 -29
  82. data/_patches-20160112/vagrantfile-for-nick +0 -95
  83. data/_patches-20160112/vagrantfiles-to-forget-what-they-are-for +0 -134
  84. data/_patches-20160112/vm-vanished +0 -42
  85. data/_patches-20160112a/01 +0 -148
  86. data/_patches-20160112a/2 +0 -239
  87. data/_patches-20160112a/COMPLETED-ABOVE-THIS-LINE +0 -4
  88. data/_patches-20160112a/COMPLETED-BELOW-THIS-LINE +0 -4
  89. data/_patches-20160112a/CR-ABOVE-THIS-LINE +0 -4
  90. data/_patches-20160112a/CR-BELOW-THIS-LINE +0 -4
  91. data/_patches-20160112a/WIP-ABOVE-THIS-LINE +0 -4
  92. data/_patches-20160112a/WIP-BELOW-THIS-LINE +0 -4
  93. data/_patches-20160112a/acceptance-test-runner +0 -29
  94. data/_patches-20160112a/ansible-1 +0 -92
  95. data/_patches-20160112a/cache-api-client-in-up +0 -40
  96. data/_patches-20160112a/dead-code-in-actions +0 -44
  97. data/_patches-20160112a/debug-changes +0 -42
  98. data/_patches-20160112a/demo-rails-app +0 -1276
  99. data/_patches-20160112a/eng-10166-halt-spec +0 -40
  100. data/_patches-20160112a/eng-10256-ubuntu-testing +0 -88
  101. data/_patches-20160112a/eng-10269-test-stuff +0 -87
  102. data/_patches-20160112a/eng-10269-wtf +0 -119
  103. data/_patches-20160112a/eng-10369 +0 -143
  104. data/_patches-20160112a/eng-10369-tmp +0 -60
  105. data/_patches-20160112a/eng-10919 +0 -56
  106. data/_patches-20160112a/eng-11177-fix-actions-requires +0 -44
  107. data/_patches-20160112a/eng-11442 +0 -4
  108. data/_patches-20160112a/eng-11616 +0 -403
  109. data/_patches-20160112a/eng-11616-2 +0 -67
  110. data/_patches-20160112a/eng-11616-actual +0 -184
  111. data/_patches-20160112a/eng-11625a +0 -4
  112. data/_patches-20160112a/eng-11711 +0 -85
  113. data/_patches-20160112a/eng-12232-command-spec +0 -236
  114. data/_patches-20160112a/eng-12235 +0 -83
  115. data/_patches-20160112a/eng-12235-override-refactor +0 -140
  116. data/_patches-20160112a/eng-12240 +0 -103
  117. data/_patches-20160112a/eng-12249 +0 -40
  118. data/_patches-20160112a/eng-12301 +0 -50
  119. data/_patches-20160112a/eng-12843 +0 -95
  120. data/_patches-20160112a/env-source +0 -112
  121. data/_patches-20160112a/frickin-vagrant-spec +0 -163
  122. data/_patches-20160112a/gem-pre-version +0 -14
  123. data/_patches-20160112a/gems-old +0 -9
  124. data/_patches-20160112a/googles-specs +0 -713
  125. data/_patches-20160112a/local-configs-ignore +0 -61
  126. data/_patches-20160112a/misc +0 -79
  127. data/_patches-20160112a/network-unreachable +0 -31
  128. data/_patches-20160112a/new-boxfile +0 -288
  129. data/_patches-20160112a/parallelization-maybe +0 -198
  130. data/_patches-20160112a/read-state +0 -23
  131. data/_patches-20160112a/refactor-to-use-public_address-cap +0 -25
  132. data/_patches-20160112a/series +0 -58
  133. data/_patches-20160112a/status +0 -14
  134. data/_patches-20160112a/test-move-env-data +0 -231
  135. data/_patches-20160112a/test-vagrantfile-vm1 +0 -167
  136. data/_patches-20160112a/the_version_in_0.1.13.pre1 +0 -612
  137. data/_patches-20160112a/then-copy-the-newer-files +0 -632
  138. data/_patches-20160112a/vagrant-spec-mock-api +0 -137
  139. data/_patches-20160112a/vagrant-vmware-plugin +0 -233
  140. data/_patches-20160112a/vagrantfile +0 -403
  141. data/_patches-20160112a/vagrantfile-for-acceptance-tests +0 -29
  142. data/_patches-20160112a/vagrantfile-for-nick +0 -95
  143. data/_patches-20160112a/vagrantfiles-to-forget-what-they-are-for +0 -134
  144. data/_patches-20160112a/vm-vanished +0 -42
  145. data/_patches-20160113/COMPLETED-ABOVE-THIS-LINE +0 -4
  146. data/_patches-20160113/COMPLETED-BELOW-THIS-LINE +0 -4
  147. data/_patches-20160113/CR-ABOVE-THIS-LINE +0 -4
  148. data/_patches-20160113/CR-BELOW-THIS-LINE +0 -4
  149. data/_patches-20160113/WIP-ABOVE-THIS-LINE +0 -4
  150. data/_patches-20160113/WIP-BELOW-THIS-LINE +0 -4
  151. data/_patches-20160113/acceptance-test-runner +0 -29
  152. data/_patches-20160113/ansible-1 +0 -92
  153. data/_patches-20160113/cache-api-client-in-up +0 -40
  154. data/_patches-20160113/dead-code-in-actions +0 -44
  155. data/_patches-20160113/debug-changes +0 -55
  156. data/_patches-20160113/demo-rails-app +0 -1276
  157. data/_patches-20160113/eng-10166-halt-spec +0 -40
  158. data/_patches-20160113/eng-10256 +0 -543
  159. data/_patches-20160113/eng-10256-ubuntu-testing +0 -88
  160. data/_patches-20160113/eng-10269-test-stuff +0 -87
  161. data/_patches-20160113/eng-10269-wtf +0 -119
  162. data/_patches-20160113/eng-10369 +0 -143
  163. data/_patches-20160113/eng-10369-tmp +0 -60
  164. data/_patches-20160113/eng-10919 +0 -56
  165. data/_patches-20160113/eng-11177-fix-actions-requires +0 -44
  166. data/_patches-20160113/eng-11442 +0 -4
  167. data/_patches-20160113/eng-11616 +0 -403
  168. data/_patches-20160113/eng-11616-2 +0 -67
  169. data/_patches-20160113/eng-11616-actual +0 -184
  170. data/_patches-20160113/eng-11625a +0 -4
  171. data/_patches-20160113/eng-11711 +0 -85
  172. data/_patches-20160113/eng-12232-command-spec +0 -236
  173. data/_patches-20160113/eng-12235 +0 -83
  174. data/_patches-20160113/eng-12235-override-refactor +0 -140
  175. data/_patches-20160113/eng-12240 +0 -103
  176. data/_patches-20160113/eng-12249 +0 -40
  177. data/_patches-20160113/eng-12301 +0 -50
  178. data/_patches-20160113/eng-12720 +0 -47
  179. data/_patches-20160113/eng-12843 +0 -95
  180. data/_patches-20160113/env-source +0 -112
  181. data/_patches-20160113/frickin-vagrant-spec +0 -163
  182. data/_patches-20160113/gem-pre-version +0 -14
  183. data/_patches-20160113/gems-old +0 -9
  184. data/_patches-20160113/googles-specs +0 -713
  185. data/_patches-20160113/local-configs-ignore +0 -61
  186. data/_patches-20160113/misc +0 -79
  187. data/_patches-20160113/network-unreachable +0 -31
  188. data/_patches-20160113/new-boxfile +0 -288
  189. data/_patches-20160113/parallelization-maybe +0 -198
  190. data/_patches-20160113/read-state +0 -23
  191. data/_patches-20160113/refactor-to-use-public_address-cap +0 -25
  192. data/_patches-20160113/series +0 -56
  193. data/_patches-20160113/status +0 -14
  194. data/_patches-20160113/test-move-env-data +0 -231
  195. data/_patches-20160113/test-vagrantfile-vm1 +0 -167
  196. data/_patches-20160113/vagrant-spec-mock-api +0 -137
  197. data/_patches-20160113/vagrant-vmware-plugin +0 -233
  198. data/_patches-20160113/vagrantfile +0 -403
  199. data/_patches-20160113/vagrantfile-for-acceptance-tests +0 -29
  200. data/_patches-20160113/vagrantfile-for-nick +0 -95
  201. data/_patches-20160113/vagrantfiles-to-forget-what-they-are-for +0 -134
  202. data/_patches-20160113/vm-vanished +0 -42
  203. data/_patches-20160118/COMPLETED-ABOVE-THIS-LINE +0 -4
  204. data/_patches-20160118/COMPLETED-BELOW-THIS-LINE +0 -4
  205. data/_patches-20160118/CR-ABOVE-THIS-LINE +0 -4
  206. data/_patches-20160118/CR-BELOW-THIS-LINE +0 -4
  207. data/_patches-20160118/WIP-ABOVE-THIS-LINE +0 -4
  208. data/_patches-20160118/WIP-BELOW-THIS-LINE +0 -4
  209. data/_patches-20160118/acceptance-test-runner +0 -29
  210. data/_patches-20160118/ansible-1 +0 -92
  211. data/_patches-20160118/cache-api-client-in-up +0 -40
  212. data/_patches-20160118/dead-code-in-actions +0 -44
  213. data/_patches-20160118/debug-changes +0 -55
  214. data/_patches-20160118/demo-rails-app +0 -1276
  215. data/_patches-20160118/eng-10166-halt-spec +0 -40
  216. data/_patches-20160118/eng-10256 +0 -554
  217. data/_patches-20160118/eng-10256-cr +0 -314
  218. data/_patches-20160118/eng-10256-ubuntu-testing +0 -88
  219. data/_patches-20160118/eng-10269-test-stuff +0 -87
  220. data/_patches-20160118/eng-10269-wtf +0 -119
  221. data/_patches-20160118/eng-10369 +0 -143
  222. data/_patches-20160118/eng-10369-tmp +0 -60
  223. data/_patches-20160118/eng-10919 +0 -56
  224. data/_patches-20160118/eng-11177-fix-actions-requires +0 -44
  225. data/_patches-20160118/eng-11442 +0 -4
  226. data/_patches-20160118/eng-11616 +0 -403
  227. data/_patches-20160118/eng-11616-2 +0 -67
  228. data/_patches-20160118/eng-11616-actual +0 -184
  229. data/_patches-20160118/eng-11625a +0 -4
  230. data/_patches-20160118/eng-11711 +0 -85
  231. data/_patches-20160118/eng-12232-command-spec +0 -236
  232. data/_patches-20160118/eng-12235 +0 -83
  233. data/_patches-20160118/eng-12235-override-refactor +0 -140
  234. data/_patches-20160118/eng-12240 +0 -103
  235. data/_patches-20160118/eng-12249 +0 -40
  236. data/_patches-20160118/eng-12301 +0 -50
  237. data/_patches-20160118/eng-12720 +0 -74
  238. data/_patches-20160118/eng-12843 +0 -95
  239. data/_patches-20160118/eng-13040 +0 -291
  240. data/_patches-20160118/env-source +0 -112
  241. data/_patches-20160118/frickin-vagrant-spec +0 -163
  242. data/_patches-20160118/gem-pre-version +0 -14
  243. data/_patches-20160118/gems-old +0 -9
  244. data/_patches-20160118/googles-specs +0 -713
  245. data/_patches-20160118/local-configs-ignore +0 -61
  246. data/_patches-20160118/misc +0 -79
  247. data/_patches-20160118/network-unreachable +0 -31
  248. data/_patches-20160118/new-boxfile +0 -288
  249. data/_patches-20160118/parallelization-maybe +0 -198
  250. data/_patches-20160118/port-forwarding-processes +0 -87
  251. data/_patches-20160118/read-state +0 -23
  252. data/_patches-20160118/refactor-to-use-public_address-cap +0 -25
  253. data/_patches-20160118/series +0 -59
  254. data/_patches-20160118/status +0 -13
  255. data/_patches-20160118/test-move-env-data +0 -231
  256. data/_patches-20160118/test-vagrantfile-vm1 +0 -167
  257. data/_patches-20160118/vagrant-spec-mock-api +0 -137
  258. data/_patches-20160118/vagrant-vmware-plugin +0 -233
  259. data/_patches-20160118/vagrantfile +0 -403
  260. data/_patches-20160118/vagrantfile-for-acceptance-tests +0 -29
  261. data/_patches-20160118/vagrantfile-for-nick +0 -95
  262. data/_patches-20160118/vagrantfiles-to-forget-what-they-are-for +0 -134
  263. data/_patches-20160118/vm-vanished +0 -42
  264. data/_patches-20160118a/COMPLETED-ABOVE-THIS-LINE +0 -4
  265. data/_patches-20160118a/COMPLETED-BELOW-THIS-LINE +0 -4
  266. data/_patches-20160118a/CR-ABOVE-THIS-LINE +0 -4
  267. data/_patches-20160118a/CR-BELOW-THIS-LINE +0 -4
  268. data/_patches-20160118a/WIP-ABOVE-THIS-LINE +0 -4
  269. data/_patches-20160118a/WIP-BELOW-THIS-LINE +0 -4
  270. data/_patches-20160118a/acceptance-test-runner +0 -29
  271. data/_patches-20160118a/ansible-1 +0 -92
  272. data/_patches-20160118a/bar +0 -189
  273. data/_patches-20160118a/cache-api-client-in-up +0 -40
  274. data/_patches-20160118a/dead-code-in-actions +0 -44
  275. data/_patches-20160118a/debug-changes +0 -55
  276. data/_patches-20160118a/demo-rails-app +0 -1276
  277. data/_patches-20160118a/eng-10166-halt-spec +0 -40
  278. data/_patches-20160118a/eng-10256 +0 -554
  279. data/_patches-20160118a/eng-10256-cr +0 -314
  280. data/_patches-20160118a/eng-10256-ubuntu-testing +0 -88
  281. data/_patches-20160118a/eng-10269-test-stuff +0 -87
  282. data/_patches-20160118a/eng-10269-wtf +0 -119
  283. data/_patches-20160118a/eng-10369 +0 -143
  284. data/_patches-20160118a/eng-10369-tmp +0 -60
  285. data/_patches-20160118a/eng-10919 +0 -56
  286. data/_patches-20160118a/eng-11177-fix-actions-requires +0 -44
  287. data/_patches-20160118a/eng-11442 +0 -4
  288. data/_patches-20160118a/eng-11616 +0 -403
  289. data/_patches-20160118a/eng-11616-2 +0 -67
  290. data/_patches-20160118a/eng-11616-actual +0 -184
  291. data/_patches-20160118a/eng-11625a +0 -4
  292. data/_patches-20160118a/eng-11711 +0 -85
  293. data/_patches-20160118a/eng-12232-command-spec +0 -236
  294. data/_patches-20160118a/eng-12235 +0 -83
  295. data/_patches-20160118a/eng-12235-override-refactor +0 -140
  296. data/_patches-20160118a/eng-12240 +0 -103
  297. data/_patches-20160118a/eng-12249 +0 -40
  298. data/_patches-20160118a/eng-12301 +0 -50
  299. data/_patches-20160118a/eng-12720 +0 -74
  300. data/_patches-20160118a/eng-12843 +0 -95
  301. data/_patches-20160118a/eng-13040 +0 -291
  302. data/_patches-20160118a/env-source +0 -112
  303. data/_patches-20160118a/foo +0 -169
  304. data/_patches-20160118a/frickin-vagrant-spec +0 -163
  305. data/_patches-20160118a/gem-pre-version +0 -14
  306. data/_patches-20160118a/gems-old +0 -9
  307. data/_patches-20160118a/googles-specs +0 -713
  308. data/_patches-20160118a/guestport-madness +0 -59
  309. data/_patches-20160118a/local-configs-ignore +0 -61
  310. data/_patches-20160118a/misc +0 -79
  311. data/_patches-20160118a/network-unreachable +0 -31
  312. data/_patches-20160118a/new-boxfile +0 -288
  313. data/_patches-20160118a/parallelization-maybe +0 -198
  314. data/_patches-20160118a/port-forwarding-processes +0 -87
  315. data/_patches-20160118a/read-state +0 -23
  316. data/_patches-20160118a/refactor-to-use-public_address-cap +0 -25
  317. data/_patches-20160118a/series +0 -62
  318. data/_patches-20160118a/status +0 -14
  319. data/_patches-20160118a/test-move-env-data +0 -231
  320. data/_patches-20160118a/test-vagrantfile-vm1 +0 -167
  321. data/_patches-20160118a/vagrant-spec-mock-api +0 -137
  322. data/_patches-20160118a/vagrant-vmware-plugin +0 -233
  323. data/_patches-20160118a/vagrantfile +0 -403
  324. data/_patches-20160118a/vagrantfile-for-acceptance-tests +0 -29
  325. data/_patches-20160118a/vagrantfile-for-nick +0 -95
  326. data/_patches-20160118a/vagrantfiles-to-forget-what-they-are-for +0 -134
  327. data/_patches-20160118a/vm-vanished +0 -42
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 42367c7e3c19aaeea00c74ed4756d8c54d92612f
4
- data.tar.gz: c5b4962d7052fad5e4a7e4c90bad7799c64b92ed
3
+ metadata.gz: d2727c03689c62c012fa747457f85b6a24f667e5
4
+ data.tar.gz: 8d0a62aade129cb4532728e647b40129d8c44239
5
5
  SHA512:
6
- metadata.gz: 3ac68aee81962e0729980aa6b5785413ca24780a2a149447f34ca3aec45a4cd4629c415035ff11c3acb838c69a85e5c115c47df2ea7ac24ded5655d0de8ed70c
7
- data.tar.gz: a0fa8b2edc3ac422141d5af6d07990e18824c76443c649b2272ff0dab506124679b7fa401531e6ee215e38b5d14250a347b19d28c2c538e98ed3150190763799
6
+ metadata.gz: 5e11895205c8662c702d30d714bb3e89cdbf34f92671633720068855ce7eebe9305a13c437318e9f6b479e737d273dc91dc273950de745cd819d4e28fdbb9d8e
7
+ data.tar.gz: 962b89d9673a20560d54b942d068a64130c34de2e9434eeebe07017c9519189e31679ffc65f0e1fd2f830104a587dbee3c020473862a3cdbce2f48c649bc09ca
data/CHANGELOG.md CHANGED
@@ -1,3 +1,7 @@
1
+ # 0.2.3 (January 28, 2016)
2
+
3
+ * Optimizations to REST calls in `vagrant up`.
4
+
1
5
  # 0.2.2 (January 26, 2016)
2
6
 
3
7
  * Bug fix: `vagrant add` would create but not start a new VM if
@@ -1,6 +1,5 @@
1
1
  require 'log4r'
2
- require 'json'
3
- require 'vagrant-skytap/setup_helper'
2
+ require 'vagrant-skytap/api/vm'
4
3
 
5
4
 
6
5
  module VagrantPlugins
@@ -19,8 +18,9 @@ module VagrantPlugins
19
18
 
20
19
  def call(env)
21
20
  environment = env[:environment]
22
- vm = environment.add_vm(vm_url)
23
- env[:machine].id = vm.id
21
+ vm = API::Vm.fetch(env, vm_url)
22
+ environment.add_vms([vm])
23
+ env[:machine].id = environment.vms.last.id
24
24
  environment.wait_until_ready
25
25
 
26
26
  @app.call(env)
@@ -0,0 +1,131 @@
1
+ require 'log4r'
2
+ require 'vagrant-skytap/api/environment'
3
+ require 'vagrant-skytap/api/vm'
4
+
5
+ module VagrantPlugins
6
+ module Skytap
7
+ module Action
8
+ # Creates a multi-VM Skytap environment, or adds VMs to an existing
9
+ # environment. The source VMs (analogous to "images") may come from
10
+ # various other environments and templates. We can parallelize this
11
+ # somewhat by adding multiple VMs per REST call, subject to the
12
+ # restriction that all source VMs added in a single call must be unique
13
+ # and must belong to the same containing environment/template.
14
+ # If creating a new environment from scratch, write the environment
15
+ # URL into the project data directory.
16
+ class ComposeEnvironment
17
+ attr_reader :env
18
+
19
+ def initialize(app, env)
20
+ @app = app
21
+ @env = env
22
+ @logger = Log4r::Logger.new("vagrant_skytap::action::compose_environment")
23
+ end
24
+
25
+ def call(env)
26
+ environment = env[:environment]
27
+ new_environment = !environment
28
+ machines = env[:machines].reject(&:id)
29
+ environment = add_vms(environment, machines)
30
+
31
+ if new_environment
32
+ env[:environment] = environment
33
+ env[:ui].info(I18n.t("vagrant_skytap.environment_url", url: environment.url))
34
+ elsif machines.present?
35
+ env[:ui].info("Added VMs to #{environment.url}.")
36
+ else
37
+ env[:ui].info("No new VMs added to #{environment.url}.")
38
+ end
39
+
40
+ @app.call(env)
41
+ end
42
+
43
+ # Create Skytap VMs for the given machines (if they do not exist)
44
+ # within the given Skytap environment.
45
+ #
46
+ # @param [API::Environment] environment The Skytap environment, if it exists
47
+ # @param [Array] machines Set of [Vagrant::Machine] objects
48
+ # @return [API::Environment] The new or existing environment
49
+ def add_vms(environment, machines)
50
+ source_vms_map = fetch_source_vms(machines)
51
+
52
+ get_groupings(source_vms_map, parallel: @env[:parallel]).each do |names|
53
+ vms_for_pass = names.collect{|name| source_vms_map[name]}
54
+
55
+ if !environment
56
+ @logger.debug("Creating environment from source vms: #{vms_for_pass.collect(&:id)}")
57
+ environment = API::Environment.create!(env, vms_for_pass)
58
+ environment.properties.write('url' => environment.url)
59
+ vms = environment.vms
60
+ else
61
+ @logger.debug("Adding source vms: #{vms_for_pass.collect(&:id)}")
62
+ vms = environment.add_vms(vms_for_pass)
63
+ end
64
+
65
+ machines.select{|m| names.include?(m.name)}.each_with_index do |machine, i|
66
+ machine.id = vms[i].id
67
+ end
68
+ end
69
+
70
+ environment
71
+ end
72
+
73
+ # Fetch the source VMs for the given machines.
74
+ # TODO Optimize by downloading unique parent objects, and pick
75
+ # the VM child objects; Set the VMs' parent object so Vm#region
76
+ # doesn't require another GET.
77
+ #
78
+ # @param [Array] machines Set of [Vagrant::Machine] objects
79
+ # @return [Hash] mapping of machine names to [API::Vm] objects
80
+ def fetch_source_vms(machines)
81
+ machines.inject({}) do |acc, machine|
82
+ acc[machine.name] = API::Vm.fetch(env, machine.provider_config.vm_url)
83
+ acc
84
+ end
85
+ end
86
+
87
+ # Group the machines to minimize calls to the REST API --
88
+ # unique VMs from the same environment or template can be
89
+ # added in a single call. The return value is a nested
90
+ # array of machine names, e.g.:
91
+ # [ [:vm1, :vm4, :vm5], [:vm3], [:vm2] ]
92
+ #
93
+ # However, if the :parallel option is false, just return one
94
+ # machine per grouping, e.g.:
95
+ # [ [:vm1], [:vm2], [:vm3], [:vm4], [:vm5] ]
96
+ #
97
+ # @param [Hash] vms_map Mapping of machine names to [API::Vm] objects
98
+ # @param [Hash] options
99
+ # @return [Array] groupings (arrays) of machine names
100
+ def get_groupings(vms_map, options={})
101
+ parallel = true
102
+ parallel = options[:parallel] if options.has_key?(:parallel)
103
+ return vms_map.keys.collect{|name| [name]} unless parallel
104
+
105
+ # Produces nested hash, mapping configuration/template urls to
106
+ # a map of machine names to the source VM id. (We discard the
107
+ # parent urls -- they are just used to group the VMs.)
108
+ groupings = vms_map.inject(Hash.new{|h,k| h[k] = {}}) do |acc, (name, vm)|
109
+ acc[vm.parent_url][name] = vm.id
110
+ acc
111
+ end.values
112
+
113
+ # If the same source VM appears more than once, the API
114
+ # requires us to make multiple calls. For simplicity,
115
+ # if a particular grouping includes such, just create a single
116
+ # call for each vm in the group. (Could be optimized further)
117
+ groupings2 = []
118
+ groupings.each_with_index do |grouping, i|
119
+ if grouping.values.uniq.count == grouping.values.count
120
+ groupings2 << grouping.keys
121
+ else
122
+ groupings2.concat(grouping.keys.map{|v| [v]})
123
+ end
124
+ end
125
+
126
+ groupings2.sort_by{|grouping| grouping.count}.reverse
127
+ end
128
+ end
129
+ end
130
+ end
131
+ end
@@ -4,6 +4,7 @@ require 'json'
4
4
  require 'vagrant-skytap/setup_helper'
5
5
  require 'vagrant-skytap/util/timer'
6
6
  require 'vagrant-skytap/api/environment'
7
+ require 'vagrant-skytap/api/vm'
7
8
 
8
9
  require 'net/https'
9
10
  require 'uri'
@@ -26,7 +27,8 @@ module VagrantPlugins
26
27
  end
27
28
 
28
29
  def call(env)
29
- environment = API::Environment.create!(env, vm_url)
30
+ vm = API::Vm.fetch(env, vm_url)
31
+ environment = API::Environment.create!(env, [vm])
30
32
  env[:environment] = environment
31
33
  environment.properties.write('url' => environment.url)
32
34
  env[:machine].id = environment.vms.first.id
@@ -13,11 +13,12 @@ module VagrantPlugins
13
13
  end
14
14
 
15
15
  def call(env)
16
- @logger.info("Connecting to Skytap...")
17
-
18
- client = API::Client.new(env[:machine].provider_config)
19
- if client.get('/configurations').code == '200'
20
- env[:api_client] = client
16
+ unless env[:api_client]
17
+ @logger.info("Connecting to Skytap...")
18
+ client = API::Client.new(env[:machine].provider_config)
19
+ if client.get('/configurations').code == '200'
20
+ env[:api_client] = client
21
+ end
21
22
  end
22
23
 
23
24
  @app.call(env)
@@ -12,7 +12,9 @@ module VagrantPlugins
12
12
  end
13
13
 
14
14
  def call(env)
15
- SetupHelper.run!(env, env[:environment])
15
+ unless VmProperties.read(env[:machine].data_dir)
16
+ SetupHelper.run!(env, env[:environment])
17
+ end
16
18
  @app.call(env)
17
19
  end
18
20
  end
@@ -17,8 +17,10 @@ module VagrantPlugins
17
17
 
18
18
  def call(env)
19
19
  entry = machine_index_entry
20
- entry.extra_data.merge!(provider_extra_data)
21
- entry = machine_index.set(entry)
20
+ unless entry.extra_data.has_key?('vm_id')
21
+ entry.extra_data.merge!(provider_extra_data)
22
+ entry = machine_index.set(entry)
23
+ end
22
24
  machine_index.release(entry)
23
25
 
24
26
  @app.call(env)
@@ -208,26 +208,14 @@ module VagrantPlugins
208
208
  Vagrant::Action::Builder.new.tap do |b|
209
209
  b.use HandleBox
210
210
  b.use action_fetch_environment
211
- b.use Call, ExistenceCheck do |env, b1|
212
- case result = env[:result]
213
- when :missing_environment
214
- b1.use CreateEnvironment
215
- b1.use MessageEnvironmentUrl
216
- when :no_vms, :missing_vm
217
- b1.use AddVmToEnvironment
218
- else
219
- next
220
- end
221
- b1.use StoreExtraData
222
- b1.use SetUpVm
223
- end
211
+ b.use ComposeEnvironment
224
212
  end
225
213
  end
226
214
 
227
215
  def self.action_update_hardware
228
216
  Vagrant::Action::Builder.new.tap do |b|
229
- b.use InitializeAPIClient
230
- b.use FetchEnvironment
217
+ b.use StoreExtraData
218
+ b.use SetUpVm
231
219
  b.use Call, IsStopped do |env, b1|
232
220
  if env[:result]
233
221
  b1.use UpdateHardware
@@ -239,8 +227,6 @@ module VagrantPlugins
239
227
 
240
228
  def self.action_run_vm
241
229
  Vagrant::Action::Builder.new.tap do |b|
242
- b.use InitializeAPIClient
243
- b.use FetchEnvironment
244
230
 
245
231
  # The "up" command stores the pre-run states to
246
232
  # avoid a race condition when running multiple
@@ -314,6 +300,7 @@ module VagrantPlugins
314
300
  autoload :StoreExtraData, action_root.join("store_extra_data")
315
301
  autoload :AddVmToEnvironment, action_root.join("add_vm_to_environment")
316
302
  autoload :ClearForwardedPorts, action_root.join("clear_forwarded_ports")
303
+ autoload :ComposeEnvironment, action_root.join("compose_environment")
317
304
  autoload :CreateEnvironment, action_root.join("create_environment")
318
305
  autoload :DeleteEnvironment, action_root.join("delete_environment")
319
306
  autoload :DeleteVm, action_root.join("delete_vm")
@@ -16,11 +16,17 @@ module VagrantPlugins
16
16
 
17
17
  RESOURCE_ROOT = '/configurations'
18
18
  class << self
19
- def create!(env, vm_url)
20
- vm = Vm.fetch(env, vm_url)
21
- check_vm_before_adding(env, vm)
22
-
23
- args = {vm_ids: [vm.id]}.tap do |ret|
19
+ # Makes the REST call to create a new environment, using
20
+ # the provided VMs as sources.
21
+ #
22
+ # @param [Hash] env The environment hash passed in from the action
23
+ # @param [Array] vms The source [API::Vm] objects
24
+ # @return [API::Environment]
25
+ def create!(env, vms)
26
+ check_vms_before_adding(vms)
27
+ vm = vms.first
28
+
29
+ args = {vm_ids: vms.collect(&:id)}.tap do |ret|
24
30
  if vm.from_template?
25
31
  ret[:template_id] = vm.template_id
26
32
  else
@@ -32,6 +38,11 @@ module VagrantPlugins
32
38
  new(JSON.load(resp.body), env)
33
39
  end
34
40
 
41
+ # Makes the REST call to retrieve an existing environment.
42
+ #
43
+ # @param [Hash] env The environment hash passed in from the action
44
+ # @param [String] url The url of the remote resource.
45
+ # @return [API::Environment]
35
46
  def fetch(env, url)
36
47
  resp = env[:api_client].get(url)
37
48
  new(JSON.load(resp.body), env)
@@ -41,16 +52,34 @@ module VagrantPlugins
41
52
  EnvironmentProperties.read(env[:machine].env.local_data_path)
42
53
  end
43
54
 
44
- def check_vm_before_adding(env, vm)
45
- raise Errors::SourceVmNotStopped, name: env[:machine].name, url: vm.url unless vm.stopped?
55
+ # Validates that a set of VMs can be used together in a REST call to
56
+ # create a new environment, or to add to an existing environment.
57
+ #
58
+ # @param [Array] vms The [API::Vm] objects to validate
59
+ # @param [API::Environment] environment to validate against (optional)
60
+ # @return [Boolean] true, if no exceptions were raised
61
+ def check_vms_before_adding(vms, environment = nil)
62
+ # logger.debug
63
+ vms.each do |vm|
64
+ raise Errors::SourceVmNotStopped, url: vm.url unless vm.stopped?
65
+ end
66
+
67
+ raise Errors::VmParentMismatch, vm_ids: vms.collect(&:id).join(', ') unless vms.collect(&:parent_url).uniq.count == 1
68
+
69
+ if environment
70
+ parent = vms.first.parent
71
+ unless parent.region == environment.region
72
+ raise Errors::RegionMismatch, environment_region: environment.region, vm_region: parent.region
73
+ end
74
+ end
75
+ true
46
76
  end
47
77
  end
48
78
 
49
-
50
79
  attr_reader :provider_config
51
80
  attr_reader :vms, :networks
52
81
 
53
- reads :id, :name, :vms, :networks, :region, :runstate, :url
82
+ reads :id, :name, :vms, :networks, :region, :runstate, :url, :region
54
83
 
55
84
  def initialize(attrs, env)
56
85
  super
@@ -63,7 +92,7 @@ module VagrantPlugins
63
92
  end
64
93
  end
65
94
 
66
- def get_vms_by_id(ids=[])
95
+ def get_vms_by_id(ids)
67
96
  vms.select{|vm| ids.include?(vm.id)}
68
97
  end
69
98
 
@@ -109,27 +138,26 @@ module VagrantPlugins
109
138
  end
110
139
  end
111
140
 
112
- def add_vm(vm_url)
113
- vm = Vm.fetch(env, vm_url)
114
- check_vm_before_adding(env, vm)
115
- vm_ids = vms.collect(&:id)
141
+ # Makes the REST call to add VMs to this environment, using
142
+ # the provided VMs as sources.
143
+ #
144
+ # @param [Array] vms The source [API::Vm] objects
145
+ # @return [Array] The new [API::Vm] objects
146
+ def add_vms(vms)
147
+ return unless vms.present?
148
+ self.class.check_vms_before_adding(vms, self)
116
149
 
117
- args = {vm_ids: [vm.id]}.tap do |ret|
118
- if vm.from_template?
119
- ret[:template_id] = vm.template_id
150
+ args = {vm_ids: vms.collect(&:id)}.tap do |ret|
151
+ if vms.first.from_template?
152
+ ret[:template_id] = vms.first.template_id
120
153
  else
121
- ret[:merge_configuration] = vm.configuration_id
154
+ ret[:merge_configuration] = vms.first.configuration_id
122
155
  end
123
156
  end
124
157
 
158
+ existing_vm_ids = self.vms.collect(&:id)
125
159
  update_with_retry(args)
126
- new_vm_ids = vms.collect(&:id) - vm_ids
127
- get_vm_by_id(new_vm_ids.last)
128
- end
129
-
130
- def check_vm_before_adding(env, vm)
131
- raise Errors::RegionMismatch, environment_region: region, vm_region: vm.region unless vm.region == region
132
- self.class.check_vm_before_adding(env, vm)
160
+ get_vms_by_id(self.vms.collect(&:id) - existing_vm_ids)
133
161
  end
134
162
 
135
163
  def create_publish_set(attrs={})
@@ -70,10 +70,16 @@ module VagrantPlugins
70
70
  $1
71
71
  end
72
72
 
73
+ def parent_url
74
+ template_url || configuration_url
75
+ end
76
+
77
+ def parent
78
+ @parent ||= Environment.fetch(env, parent_url)
79
+ end
80
+
73
81
  def region
74
- return @region if @region
75
- resp = env[:api_client].get(template_url || configuration_url)
76
- @region = JSON.load(resp.body)['region']
82
+ @region ||= parent.region
77
83
  end
78
84
 
79
85
  def delete
@@ -11,15 +11,6 @@ module VagrantPlugins
11
11
  class Up < VagrantPlugins::CommandUp::Command
12
12
 
13
13
  def execute
14
- # This implementation of the "up" command overrides
15
- # the default implementation due to load order.
16
- if @env.default_provider == :skytap
17
- @logger.debug("Executing Skytap 'Up' implementation.")
18
- else
19
- @logger.debug("Calling default 'Up' implementation.")
20
- return super
21
- end
22
-
23
14
  options = {}
24
15
  options[:destroy_on_error] = true
25
16
  options[:parallel] = true
@@ -80,28 +71,15 @@ module VagrantPlugins
80
71
  names = nil if autostart && names.empty?
81
72
  end
82
73
 
83
- if names
84
- with_target_vms(names, provider: options[:provider]) do |machine|
85
- @env.ui.info(I18n.t(
86
- "vagrant.commands.up.upping",
87
- name: machine.name,
88
- provider: machine.provider_name))
89
-
90
- machines << machine
91
- machine.action(:create, options)
92
- machine.action(:update_hardware, options)
93
- end
94
-
95
- initial_states = machines.inject({}) {|acc, m| acc[m.id] = m.state.id ; acc }
96
-
97
- machines.each do |machine|
98
- machine.action(:run_vm, options.merge(
99
- machines: machines,
100
- initial_states: initial_states
101
- ))
102
- end
74
+ with_target_vms(names, provider: options[:provider]) {|machine| machines << machine}
75
+ unless machines.first.provider_name == :skytap
76
+ @logger.debug("Calling default 'Up' implementation.")
77
+ return super
103
78
  end
104
79
 
80
+ @logger.debug("Executing Skytap 'Up' implementation.")
81
+ bring_up_machines(machines, options)
82
+
105
83
  if machines.empty?
106
84
  @env.ui.info(I18n.t("vagrant.up_no_machines"))
107
85
  return 0
@@ -124,8 +102,46 @@ module VagrantPlugins
124
102
  # Success, exit status 0
125
103
  0
126
104
  end
105
+
106
+ # Custom handling for Skytap environments. Creating and
107
+ # running happens in multiple phases:
108
+ # * Compose Skytap environment from groups of VMs, or
109
+ # add groups of machines to an existing environment,
110
+ # using optimal number of API calls.
111
+ # * Customize the VMs.
112
+ # * Run the VMs. If parallelized this happens with a
113
+ # single API call.
114
+ #
115
+ # @param [Array] machines The [Vagrant::Machine] objects to bring up
116
+ # @param [Hash] options
117
+ # @return [Array] The [Vagrant::Machine] objects
118
+ def bring_up_machines(machines, options={})
119
+ return [] unless machines.present?
120
+
121
+ # Invoke once for the entire set of machines.
122
+ result = machines.first.action(:create, options.merge(machines: machines))
123
+
124
+ # Lets us eliminate some redundant API calls
125
+ cached_objects = {
126
+ api_client: result[:api_client],
127
+ environment: result[:environment],
128
+ machines: machines,
129
+ initial_states: machines.inject({}) {|acc, m| acc[m.id] = m.state.id ; acc },
130
+ }
131
+
132
+ machines.each do |machine|
133
+ machine.action(:update_hardware, options.merge(cached_objects))
134
+ end
135
+
136
+ machines.each do |machine|
137
+ @env.ui.info(I18n.t(
138
+ "vagrant.commands.up.upping",
139
+ name: machine.name,
140
+ provider: machine.provider_name))
141
+ machine.action(:run_vm, options.merge(cached_objects))
142
+ end
143
+ end
127
144
  end
128
145
  end
129
146
  end
130
147
  end
131
-
@@ -70,6 +70,10 @@ module VagrantPlugins
70
70
  class FeatureNotSupportedForHostOs < VagrantSkytapError
71
71
  error_key(:feature_not_supported_for_host_os)
72
72
  end
73
+
74
+ class VmParentMismatch < VagrantSkytapError
75
+ error_key(:vm_parent_mismatch)
76
+ end
73
77
  end
74
78
  end
75
79
  end
@@ -1,5 +1,5 @@
1
1
  module VagrantPlugins
2
2
  module Skytap
3
- VERSION = "0.2.2"
3
+ VERSION = "0.2.3"
4
4
  end
5
5
  end
data/locales/en.yml CHANGED
@@ -85,7 +85,7 @@ en:
85
85
  Could not connect to the VPN.
86
86
 
87
87
  source_vm_not_stopped: |-
88
- You cannot bring up the machine '%{name}' using the VM %{url} because the VM is running or suspended.
88
+ You cannot bring up the machine using the VM %{url} because the VM is running or suspended.
89
89
 
90
90
  resource_busy: |-
91
91
  This operation failed because the resource was busy: %{err}
@@ -109,6 +109,10 @@ en:
109
109
  region_mismatch: |-
110
110
  A VM from the '%{vm_region}' region cannot be added to an environment in the '%{environment_region}' region.
111
111
 
112
+ vm_parent_mismatch: |-
113
+ The provided VMs (%{vm_ids}) do not belong to the same environment or template.
114
+ (This is a bug which should be reported.)
115
+
112
116
  feature_not_supported_for_host_os: |-
113
117
  The %{feature_name} feature is currently not supported for your host operating system.
114
118
 
@@ -0,0 +1,101 @@
1
+ require File.expand_path("../../base", __FILE__)
2
+
3
+ describe VagrantPlugins::Skytap::Action::ComposeEnvironment do
4
+ include_context "unit"
5
+ include_context "rest_api"
6
+
7
+ let(:app) { lambda { |env| } }
8
+ let(:env) { { machine: machine, machines: [machine], environment: environment, ui: ui, api_client: api_client } }
9
+ let(:base_url) {"http://example.com/"}
10
+ let(:provider_config) do
11
+ double(:provider_config, vm_url: "/vms/1", username: "jsmith", api_token: "123123", base_url: base_url)
12
+ end
13
+ let(:ui) { double(:ui, info: nil) }
14
+ let(:api_client) { API::Client.new(provider_config) }
15
+
16
+ let(:machine) { double(:machine, name: "vm1", id: nil, :id= => nil, provider_config: provider_config) }
17
+ let(:existing_machine) { double(:existing_machine, name: "vm2", id: 2) }
18
+
19
+ let(:environment) { double(:environment, url: "foo") }
20
+ let(:new_environment) { double(:environment, url: "foo", vms: [vm], properties: environment_properties) }
21
+ let(:vm) { double(:vm, id: 1, parent_url: "https://example.com/templates/1") }
22
+
23
+ let(:environment_properties) { double(:environment_properties, read: nil, write: nil) }
24
+
25
+ let(:subject) { described_class.new(app, env) }
26
+
27
+ before do
28
+ stub_request(:get, /.*/).to_return(body: '{}', status: 200)
29
+ end
30
+
31
+ describe "#call" do
32
+ it "does nothing if all machines exist" do
33
+ machine.stub(id: 1)
34
+ expect(app).to receive(:call).with(env)
35
+
36
+ expect(API::Environment).to_not receive(:create!)
37
+ expect(API::Vm).to_not receive(:fetch)
38
+ expect(environment).to_not receive(:add_vms)
39
+
40
+ subject.call(env)
41
+ end
42
+
43
+ it "makes a single create! call when creating an environment with 1 machine", run: true do
44
+ myenv = env.merge(environment: nil)
45
+ expect(app).to receive(:call).with(myenv)
46
+
47
+ expect(API::Environment).to receive(:create!).and_return(new_environment)
48
+ expect(API::Vm).to receive(:fetch).once.and_return(vm)
49
+ expect(environment).to_not receive(:add_vms)
50
+
51
+ subject.call(myenv)
52
+ end
53
+
54
+ it "makes a single add_vms call when adding 1 machine to existing environment" do
55
+ myenv = env.merge(machines: [machine, existing_machine])
56
+ expect(app).to receive(:call).with(myenv)
57
+
58
+ expect(API::Environment).to_not receive(:create!)
59
+ expect(API::Vm).to receive(:fetch).once.and_return(vm)
60
+ expect(environment).to receive(:add_vms).once.and_return([vm])
61
+
62
+ subject.call(myenv)
63
+ end
64
+ end
65
+
66
+ describe "fetch_source_vms" do
67
+ it "fetches a vm and returns a mapping" do
68
+ vms = subject.fetch_source_vms([machine])
69
+ expect(a_request(:get, %r{/vms/\d+$})).to have_been_made.once
70
+ expect(vms.count).to eq(1)
71
+ expect(vms.keys.first).to eq("vm1")
72
+ expect(vms.values.first).to be_a_kind_of(API::Vm)
73
+ end
74
+ end
75
+
76
+ describe "get_groupings" do
77
+ let(:vm_in_same_template) { double(:vm_in_same_template, id: 2, parent_url: "https://example.com/templates/1")}
78
+ let(:vm_in_different_template) { double(:vm_in_different_template, id: 3, parent_url: "https://example.com/templates/2")}
79
+
80
+ it "returns a single group for a single vm" do
81
+ expect(subject.get_groupings({"vm1" => vm})).to eq([ ["vm1"] ])
82
+ end
83
+
84
+ it "groups vms in same template together" do
85
+ expect(subject.get_groupings({"vm1" => vm, "vm2" => vm_in_same_template})).to eq([ ["vm1", "vm2"] ])
86
+ end
87
+
88
+ it "groups vms in different templates separately" do
89
+ # These are expected to be in reverse order, because we sort them descending by count
90
+ expect(subject.get_groupings({"vm1" => vm, "vm2" => vm_in_different_template})).to eq([ ["vm2"], ["vm1"] ])
91
+ end
92
+
93
+ it "groups identical vms separately" do
94
+ expect(subject.get_groupings({"vm1" => vm, "vm2" => vm})).to eq([ ["vm2"], ["vm1"] ])
95
+ end
96
+
97
+ it "respects parallel flag" do
98
+ expect(subject.get_groupings({"vm1" => vm, "vm2" => vm_in_same_template}, parallel: false)).to eq([ ["vm1"], ["vm2"] ])
99
+ end
100
+ end
101
+ end