lobot 2.0.0pre → 2.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (297) hide show
  1. data/.gitignore +7 -10
  2. data/.gitmodules +1 -1
  3. data/.pairs +15 -0
  4. data/.rvmrc +1 -1
  5. data/.travis.yml +5 -0
  6. data/Gemfile +2 -2
  7. data/LICENSE.txt +1 -1
  8. data/README.md +67 -29
  9. data/Rakefile +11 -6
  10. data/Vagrantfile +8 -5
  11. data/bin/lobot +2 -4
  12. data/chef/cookbooks/pivotal_ci/attributes/jenkins.rb +1 -0
  13. data/chef/cookbooks/pivotal_ci/files/default/tests/minitest/default_test.rb +40 -2
  14. data/chef/cookbooks/pivotal_ci/recipes/id_rsa.rb +5 -0
  15. data/chef/cookbooks/pivotal_ci/recipes/jenkins_config.rb +5 -2
  16. data/chef/cookbooks/pivotal_ci/recipes/limited_travis_ci_environment.rb +4 -0
  17. data/chef/cookbooks/pivotal_ci/templates/default/jenkins-job-config.xml.erb +8 -6
  18. data/chef/cookbooks/pivotal_ci/test/kitchen/cookbooks/pivotal_ci_test/attributes/default.rb +0 -1
  19. data/chef/cookbooks/pivotal_ci/test/kitchen/cookbooks/pivotal_ci_test/recipes/bootstrap.rb +41 -0
  20. data/chef/cookbooks/pivotal_ci/test/kitchen/cookbooks/pivotal_ci_test/recipes/default.rb +1 -41
  21. data/chef/travis-cookbooks/ci_environment/apt/recipes/default.rb +8 -7
  22. data/chef/travis-cookbooks/ci_environment/bazaar/recipes/default.rb +1 -1
  23. data/chef/travis-cookbooks/ci_environment/cassandra/attributes/default.rb +6 -3
  24. data/chef/travis-cookbooks/ci_environment/cassandra/recipes/datastax.rb +1 -1
  25. data/chef/travis-cookbooks/ci_environment/cassandra/recipes/package.rb +1 -1
  26. data/chef/travis-cookbooks/ci_environment/cassandra/recipes/tarball.rb +6 -2
  27. data/chef/travis-cookbooks/ci_environment/cassandra/templates/default/cassandra.init.erb +58 -131
  28. data/chef/travis-cookbooks/ci_environment/chromium/recipes/default.rb +1 -1
  29. data/chef/travis-cookbooks/ci_environment/clang/attributes/tarball.rb +2 -7
  30. data/chef/travis-cookbooks/ci_environment/clang/recipes/default.rb +1 -1
  31. data/chef/travis-cookbooks/ci_environment/clang/recipes/tarball.rb +2 -4
  32. data/chef/travis-cookbooks/ci_environment/couchdb/recipes/default.rb +1 -1
  33. data/chef/travis-cookbooks/ci_environment/couchdb/recipes/ppa.rb +1 -1
  34. data/chef/travis-cookbooks/ci_environment/couchdb/recipes/ubuntu-12.04.rb +1 -1
  35. data/chef/travis-cookbooks/ci_environment/couchdb/recipes/ubuntu1110_ppa.rb +1 -1
  36. data/chef/travis-cookbooks/ci_environment/couchdb/recipes/ubuntu1204_ppa.rb +1 -1
  37. data/chef/travis-cookbooks/ci_environment/doxygen/recipes/default.rb +24 -0
  38. data/chef/travis-cookbooks/ci_environment/elasticsearch/attributes/default.rb +4 -1
  39. data/chef/travis-cookbooks/ci_environment/elasticsearch/recipes/default.rb +8 -5
  40. data/chef/travis-cookbooks/ci_environment/emacs/recipes/nox.rb +1 -1
  41. data/chef/travis-cookbooks/ci_environment/firefox/recipes/default.rb +1 -1
  42. data/chef/travis-cookbooks/ci_environment/git/recipes/default.rb +1 -1
  43. data/chef/travis-cookbooks/ci_environment/git/recipes/ppa.rb +1 -1
  44. data/chef/travis-cookbooks/ci_environment/golang/attributes/default.rb +3 -3
  45. data/chef/travis-cookbooks/ci_environment/gradle/attributes/tarball.rb +1 -1
  46. data/chef/travis-cookbooks/ci_environment/haskell/recipes/default.rb +1 -1
  47. data/chef/travis-cookbooks/ci_environment/haskell/recipes/ghc_package.rb +1 -1
  48. data/chef/travis-cookbooks/ci_environment/haskell/recipes/ghc_source.rb +1 -1
  49. data/chef/travis-cookbooks/ci_environment/haskell/recipes/platform_package.rb +1 -1
  50. data/chef/travis-cookbooks/ci_environment/haskell/recipes/platform_ppa.rb +1 -1
  51. data/chef/travis-cookbooks/ci_environment/haskell/recipes/platform_source.rb +1 -1
  52. data/chef/travis-cookbooks/ci_environment/haskell/recipes/source.rb +1 -1
  53. data/chef/travis-cookbooks/ci_environment/hbase/recipes/cdh4.rb +1 -1
  54. data/chef/travis-cookbooks/ci_environment/java/attributes/default.rb +4 -2
  55. data/chef/travis-cookbooks/ci_environment/java/recipes/default.rb +1 -1
  56. data/chef/travis-cookbooks/ci_environment/java/recipes/oraclejdk7.rb +6 -1
  57. data/chef/travis-cookbooks/ci_environment/kerl/attributes/source.rb +1 -1
  58. data/chef/travis-cookbooks/ci_environment/kerl/files/default/erlang.cookie +1 -0
  59. data/chef/travis-cookbooks/ci_environment/kerl/recipes/source.rb +8 -0
  60. data/chef/travis-cookbooks/ci_environment/kestrel/recipes/tarball.rb +1 -1
  61. data/chef/travis-cookbooks/ci_environment/leiningen/attributes/default.rb +1 -1
  62. data/chef/travis-cookbooks/ci_environment/leiningen/recipes/default.rb +1 -1
  63. data/chef/travis-cookbooks/ci_environment/leiningen/recipes/lein1x.rb +1 -1
  64. data/chef/travis-cookbooks/ci_environment/leiningen/recipes/lein2x.rb +1 -1
  65. data/chef/travis-cookbooks/ci_environment/libffi/recipes/default.rb +1 -1
  66. data/chef/travis-cookbooks/ci_environment/libgdbm/recipes/default.rb +1 -1
  67. data/chef/travis-cookbooks/ci_environment/libncurses/recipes/default.rb +1 -1
  68. data/chef/travis-cookbooks/ci_environment/libossp-uuid/recipes/default.rb +1 -1
  69. data/chef/travis-cookbooks/ci_environment/libreadline/recipes/default.rb +1 -1
  70. data/chef/travis-cookbooks/ci_environment/libssl/recipes/098.rb +1 -1
  71. data/chef/travis-cookbooks/ci_environment/libssl/recipes/default.rb +1 -1
  72. data/chef/travis-cookbooks/ci_environment/libxml/recipes/default.rb +1 -1
  73. data/chef/travis-cookbooks/ci_environment/lighttpd/recipes/default.rb +1 -1
  74. data/chef/travis-cookbooks/ci_environment/maven3/recipes/default.rb +5 -2
  75. data/chef/travis-cookbooks/ci_environment/maven3/recipes/package.rb +1 -1
  76. data/chef/travis-cookbooks/ci_environment/maven3/recipes/ppa.rb +1 -1
  77. data/chef/travis-cookbooks/ci_environment/maven3/recipes/tarball.rb +1 -1
  78. data/chef/travis-cookbooks/ci_environment/memcached/attributes/default.rb +1 -1
  79. data/chef/travis-cookbooks/ci_environment/memcached/attributes/ppa.rb +1 -1
  80. data/chef/travis-cookbooks/ci_environment/memcached/recipes/default.rb +1 -1
  81. data/chef/travis-cookbooks/ci_environment/memcached/recipes/ppa.rb +1 -1
  82. data/chef/travis-cookbooks/ci_environment/mercurial/recipes/default.rb +1 -1
  83. data/chef/travis-cookbooks/ci_environment/mercurial/recipes/ppa.rb +36 -0
  84. data/chef/travis-cookbooks/ci_environment/mongodb/attributes/mongodb.rb +1 -1
  85. data/chef/travis-cookbooks/ci_environment/mongodb/files/default/mongodb.sysvinit.sh +1 -1
  86. data/chef/travis-cookbooks/ci_environment/mongodb/recipes/apt.rb +5 -5
  87. data/chef/travis-cookbooks/ci_environment/mongodb/recipes/server.rb +5 -2
  88. data/chef/travis-cookbooks/ci_environment/mysql/attributes/default.rb +1 -3
  89. data/chef/travis-cookbooks/ci_environment/mysql/recipes/server_on_ramfs.rb +6 -1
  90. data/chef/travis-cookbooks/ci_environment/mysql/templates/default/my.cnf.erb +0 -2
  91. data/chef/travis-cookbooks/ci_environment/mysql/templates/default/ramfs/my.cnf.erb +0 -2
  92. data/chef/travis-cookbooks/ci_environment/neo4j-server/attributes/tarball.rb +13 -2
  93. data/chef/travis-cookbooks/ci_environment/neo4j-server/recipes/tarball.rb +26 -2
  94. data/chef/travis-cookbooks/ci_environment/networking_basic/recipes/default.rb +4 -1
  95. data/chef/travis-cookbooks/ci_environment/nodejs/attributes/multi.rb +3 -3
  96. data/chef/travis-cookbooks/ci_environment/nodejs/recipes/multi.rb +1 -1
  97. data/chef/travis-cookbooks/ci_environment/openssh/recipes/default.rb +1 -1
  98. data/chef/travis-cookbooks/ci_environment/perlbrew/attributes/multi.rb +1 -1
  99. data/chef/travis-cookbooks/ci_environment/phantomjs/attributes/default.rb +2 -2
  100. data/chef/travis-cookbooks/ci_environment/phantomjs/metadata.rb +3 -0
  101. data/chef/travis-cookbooks/ci_environment/phantomjs/recipes/default.rb +3 -1
  102. data/chef/travis-cookbooks/ci_environment/phantomjs/recipes/tarball.rb +3 -2
  103. data/chef/travis-cookbooks/ci_environment/php/attributes/default.rb +40 -2
  104. data/chef/travis-cookbooks/ci_environment/php/providers/pecl.rb +73 -0
  105. data/chef/travis-cookbooks/ci_environment/php/recipes/extensions.rb +25 -0
  106. data/chef/travis-cookbooks/ci_environment/php/recipes/multi.rb +5 -4
  107. data/chef/travis-cookbooks/ci_environment/php/resources/pecl.rb +10 -0
  108. data/chef/travis-cookbooks/ci_environment/phpbuild/attributes/default.rb +2 -2
  109. data/chef/travis-cookbooks/ci_environment/phpbuild/files/default/after-install.d/phpunit.sh +58 -0
  110. data/chef/travis-cookbooks/ci_environment/phpbuild/files/default/definitions/5.2.17 +3 -1
  111. data/chef/travis-cookbooks/ci_environment/phpbuild/files/default/definitions/5.3.3 +2 -1
  112. data/chef/travis-cookbooks/ci_environment/phpbuild/providers/build.rb +1 -1
  113. data/chef/travis-cookbooks/ci_environment/phpbuild/recipes/default.rb +8 -10
  114. data/chef/travis-cookbooks/ci_environment/phpbuild/templates/default/default_configure_options.erb +4 -0
  115. data/chef/travis-cookbooks/ci_environment/phpenv/attributes/default.rb +6 -0
  116. data/chef/travis-cookbooks/ci_environment/phpenv/recipes/default.rb +11 -7
  117. data/chef/travis-cookbooks/ci_environment/postgresql/recipes/server_on_ramfs.rb +2 -2
  118. data/chef/travis-cookbooks/ci_environment/python/attributes/default.rb +2 -2
  119. data/chef/travis-cookbooks/ci_environment/python/recipes/multi.rb +10 -3
  120. data/chef/travis-cookbooks/ci_environment/rabbitmq/attributes/default.rb +3 -0
  121. data/chef/travis-cookbooks/ci_environment/rabbitmq/recipes/default.rb +6 -2
  122. data/chef/travis-cookbooks/ci_environment/ragel/recipes/custom.rb +1 -1
  123. data/chef/travis-cookbooks/ci_environment/ragel/recipes/default.rb +1 -1
  124. data/chef/travis-cookbooks/ci_environment/redis/attributes/default.rb +3 -0
  125. data/chef/travis-cookbooks/ci_environment/redis/recipes/default.rb +6 -3
  126. data/chef/travis-cookbooks/ci_environment/redis/recipes/ppa.rb +1 -1
  127. data/chef/travis-cookbooks/ci_environment/riak/attributes/default.rb +1 -0
  128. data/chef/travis-cookbooks/ci_environment/riak/attributes/package.rb +3 -3
  129. data/chef/travis-cookbooks/{messaging_broker/openssl/recipes/default.rb → ci_environment/riak/attributes/service.rb} +4 -3
  130. data/chef/travis-cookbooks/ci_environment/riak/recipes/config.rb +2 -2
  131. data/chef/travis-cookbooks/ci_environment/riak/recipes/default.rb +12 -5
  132. data/chef/travis-cookbooks/ci_environment/rvm/attributes/default.rb +1 -1
  133. data/chef/travis-cookbooks/ci_environment/rvm/attributes/multi.rb +2 -0
  134. data/chef/travis-cookbooks/ci_environment/rvm/files/default/gemsets/global.gems +1 -1
  135. data/chef/travis-cookbooks/ci_environment/rvm/files/default/gemsets/jruby/global.gems +1 -1
  136. data/chef/travis-cookbooks/ci_environment/rvm/files/default/gemsets/ruby/2.0.0/global.gems +2 -0
  137. data/chef/travis-cookbooks/ci_environment/rvm/files/default/gemsets/ruby/head/global.gems +2 -0
  138. data/chef/travis-cookbooks/ci_environment/rvm/recipes/default.rb +23 -1
  139. data/chef/travis-cookbooks/ci_environment/rvm/recipes/multi.rb +2 -2
  140. data/chef/travis-cookbooks/ci_environment/rvm/templates/default/bundler_config.yml.erb +2 -0
  141. data/chef/travis-cookbooks/ci_environment/sbt/CHANGELOG.md +20 -0
  142. data/chef/travis-cookbooks/ci_environment/sbt/LICENSE +201 -0
  143. data/chef/travis-cookbooks/ci_environment/sbt/README.md +78 -2
  144. data/chef/travis-cookbooks/ci_environment/sbt/attributes/default.rb +36 -10
  145. data/chef/travis-cookbooks/ci_environment/sbt/metadata.json +27 -17
  146. data/chef/travis-cookbooks/ci_environment/sbt/metadata.rb +13 -6
  147. data/chef/travis-cookbooks/ci_environment/sbt/recipes/default.rb +101 -51
  148. data/chef/travis-cookbooks/ci_environment/sbt/templates/default/jvmopts.erb +7 -0
  149. data/chef/travis-cookbooks/ci_environment/sbt/templates/default/sbtopts.erb +54 -0
  150. data/chef/travis-cookbooks/ci_environment/sphinx/attributes/default.rb +2 -2
  151. data/chef/travis-cookbooks/ci_environment/sphinx/metadata.rb +4 -4
  152. data/chef/travis-cookbooks/ci_environment/sphinx/recipes/all.rb +1 -1
  153. data/chef/travis-cookbooks/ci_environment/sphinx/recipes/default.rb +1 -1
  154. data/chef/travis-cookbooks/{messaging_broker/build-essential/recipes/default.rb → ci_environment/sqlite/recipes/ppa.rb} +13 -24
  155. data/chef/travis-cookbooks/ci_environment/subversion/recipes/default.rb +1 -1
  156. data/chef/travis-cookbooks/ci_environment/sweeper/recipes/default.rb +1 -1
  157. data/chef/travis-cookbooks/ci_environment/travis_build_environment/attributes/default.rb +2 -0
  158. data/chef/travis-cookbooks/ci_environment/travis_build_environment/recipes/ci_user.rb +2 -2
  159. data/chef/travis-cookbooks/ci_environment/travis_build_environment/recipes/default.rb +1 -3
  160. data/chef/travis-cookbooks/ci_environment/travis_build_environment/recipes/root.rb +5 -1
  161. data/chef/travis-cookbooks/ci_environment/travis_build_environment/templates/default/ci_user/{dot_bashrc.sh → dot_bashrc.sh.erb} +0 -4
  162. data/chef/travis-cookbooks/ci_environment/unarchivers/recipes/default.rb +1 -1
  163. data/chef/travis-cookbooks/ci_environment/xserver/metadata.rb +3 -0
  164. data/chef/travis-cookbooks/ci_environment/xserver/recipes/default.rb +1 -1
  165. data/chef/travis-cookbooks/ci_environment/zeromq/recipes/default.rb +6 -23
  166. data/chef/travis-cookbooks/ci_environment/zeromq/recipes/{20x.rb → ppa.rb} +14 -14
  167. data/chef/travis-cookbooks/ci_environment/zookeeper/recipes/cdh4.rb +1 -1
  168. data/chef/travis-cookbooks/worker_host/java/metadata.rb +1 -1
  169. data/chef/travis-cookbooks/worker_host/java/recipes/openjdk.rb +6 -0
  170. data/chef/travis-cookbooks/worker_host/jruby/attributes/default.rb +1 -1
  171. data/chef/travis-cookbooks/worker_host/jruby/metadata.rb +1 -1
  172. data/chef/travis-cookbooks/worker_host/jruby/recipes/default.rb +1 -0
  173. data/chef/travis-cookbooks/worker_host/monit/recipes/default.rb +21 -17
  174. data/chef/travis-cookbooks/worker_host/networking_basic/metadata.rb +1 -1
  175. data/chef/travis-cookbooks/worker_host/networking_basic/recipes/default.rb +0 -6
  176. data/chef/travis-cookbooks/worker_host/ntp/.gitignore +1 -0
  177. data/chef/travis-cookbooks/worker_host/ntp/.travis.yml +6 -0
  178. data/chef/travis-cookbooks/worker_host/ntp/CHANGELOG.md +35 -0
  179. data/chef/travis-cookbooks/worker_host/ntp/CONTRIBUTING +29 -0
  180. data/chef/travis-cookbooks/worker_host/ntp/LICENSE +201 -0
  181. data/chef/travis-cookbooks/worker_host/ntp/README.md +163 -0
  182. data/chef/travis-cookbooks/worker_host/ntp/Rakefile +19 -0
  183. data/chef/travis-cookbooks/worker_host/ntp/TESTING.md +213 -0
  184. data/chef/travis-cookbooks/worker_host/ntp/attributes/default.rb +54 -0
  185. data/chef/travis-cookbooks/{messaging_broker/rabbitmq/resources/vhost.rb → worker_host/ntp/attributes/ntpdate.rb} +6 -7
  186. data/chef/travis-cookbooks/worker_host/ntp/chefignore +19 -0
  187. data/chef/travis-cookbooks/worker_host/ntp/files/default/ntp.leapseconds +222 -0
  188. data/chef/travis-cookbooks/worker_host/ntp/metadata.json +117 -0
  189. data/chef/travis-cookbooks/worker_host/ntp/metadata.rb +45 -0
  190. data/chef/travis-cookbooks/worker_host/ntp/recipes/default.rb +50 -0
  191. data/chef/travis-cookbooks/worker_host/ntp/recipes/disable.rb +22 -0
  192. data/chef/travis-cookbooks/worker_host/ntp/recipes/ntpdate.rb +36 -0
  193. data/chef/travis-cookbooks/{messaging_broker/openssl/libraries/secure_password.rb → worker_host/ntp/recipes/undo.rb} +17 -18
  194. data/chef/travis-cookbooks/worker_host/ntp/templates/default/ntp.conf.erb +55 -0
  195. data/chef/travis-cookbooks/worker_host/ntp/templates/default/ntpdate.erb +14 -0
  196. data/chef/travis-cookbooks/worker_host/rvm/recipes/multi.rb +1 -1
  197. data/chef/travis-cookbooks/worker_host/travis_worker/attributes/default.rb +10 -3
  198. data/chef/travis-cookbooks/worker_host/travis_worker/files/default/signal_wrapper.rb +22 -0
  199. data/chef/travis-cookbooks/worker_host/travis_worker/metadata.rb +2 -2
  200. data/chef/travis-cookbooks/worker_host/travis_worker/recipes/bluebox.rb +97 -0
  201. data/chef/travis-cookbooks/worker_host/travis_worker/recipes/default.rb +25 -15
  202. data/chef/travis-cookbooks/worker_host/travis_worker/templates/default/sv-travis-worker-run.erb +1 -1
  203. data/chef/travis-cookbooks/worker_host/travis_worker/templates/default/worker-bluebox.yml.erb +21 -0
  204. data/chef/travis-cookbooks/worker_host/travis_worker/templates/default/worker.yml.erb +0 -4
  205. data/chef/travis-cookbooks/worker_host/travis_worker_collectd/metadata.rb +1 -0
  206. data/chef/travis-cookbooks/worker_host/travis_worker_collectd/recipes/bluebox.rb +15 -0
  207. data/chef/travis-cookbooks/worker_host/travis_worker_collectd/recipes/default.rb +1 -0
  208. data/chef/travis-cookbooks/worker_host/users/recipes/default.rb +5 -0
  209. data/cookbooks/.gitkeep +3 -0
  210. data/lib/lobot.rb +8 -4
  211. data/lib/lobot/amazon.rb +33 -19
  212. data/lib/lobot/cli.rb +70 -46
  213. data/lib/lobot/config.rb +151 -19
  214. data/lib/lobot/configuration_wizard.rb +117 -0
  215. data/lib/lobot/keychain.rb +36 -0
  216. data/lib/lobot/password.rb +13 -0
  217. data/lib/lobot/sobo.rb +57 -13
  218. data/lib/lobot/templates/default_rails_build_script.sh +13 -0
  219. data/lib/lobot/version.rb +2 -2
  220. data/lobot.gemspec +4 -5
  221. data/script/bootstrap_server.sh +1 -1
  222. data/script/ci_build.sh +13 -0
  223. data/spec/assets/test_cert.crt +18 -0
  224. data/spec/fixtures/ssh_keys/vagrant_test_key +27 -0
  225. data/spec/fixtures/ssh_keys/vagrant_test_key.pub +1 -0
  226. data/spec/lib/lobot/amazon_spec.rb +80 -39
  227. data/spec/lib/lobot/cli_spec.rb +223 -154
  228. data/spec/lib/lobot/config_spec.rb +207 -5
  229. data/spec/lib/lobot/configuration_wizard_spec.rb +347 -0
  230. data/spec/lib/lobot/keychain_spec.rb +33 -0
  231. data/spec/lib/lobot/password_spec.rb +15 -0
  232. data/spec/spec_helper.rb +19 -1
  233. data/templates/Gemfile-remote +4 -0
  234. metadata +83 -100
  235. data/chef/travis-cookbooks/ci_environment/rvm/files/default/gemsets/ruby/1.8.6/global.gems +0 -2
  236. data/chef/travis-cookbooks/ci_environment/travis_build_environment/files/default/root/dot_bashrc.sh +0 -86
  237. data/chef/travis-cookbooks/ci_environment/zeromq/attributes/default.rb +0 -7
  238. data/chef/travis-cookbooks/messaging_broker/build-essential/README.md +0 -24
  239. data/chef/travis-cookbooks/messaging_broker/build-essential/metadata.rb +0 -10
  240. data/chef/travis-cookbooks/messaging_broker/emacs/metadata.rb +0 -11
  241. data/chef/travis-cookbooks/messaging_broker/emacs/recipes/default.rb +0 -21
  242. data/chef/travis-cookbooks/messaging_broker/erlang/attributes/default.rb +0 -1
  243. data/chef/travis-cookbooks/messaging_broker/erlang/metadata.rb +0 -11
  244. data/chef/travis-cookbooks/messaging_broker/erlang/recipes/default.rb +0 -27
  245. data/chef/travis-cookbooks/messaging_broker/git/README.rdoc +0 -37
  246. data/chef/travis-cookbooks/messaging_broker/git/metadata.rb +0 -16
  247. data/chef/travis-cookbooks/messaging_broker/git/recipes/default.rb +0 -24
  248. data/chef/travis-cookbooks/messaging_broker/git/recipes/server.rb +0 -34
  249. data/chef/travis-cookbooks/messaging_broker/git/templates/default/sv-git-daemon-log-run.erb +0 -2
  250. data/chef/travis-cookbooks/messaging_broker/git/templates/default/sv-git-daemon-run.erb +0 -3
  251. data/chef/travis-cookbooks/messaging_broker/haproxy/README.md +0 -79
  252. data/chef/travis-cookbooks/messaging_broker/haproxy/attributes/default.rb +0 -22
  253. data/chef/travis-cookbooks/messaging_broker/haproxy/metadata.rb +0 -13
  254. data/chef/travis-cookbooks/messaging_broker/haproxy/recipes/app_lb.rb +0 -50
  255. data/chef/travis-cookbooks/messaging_broker/haproxy/recipes/default.rb +0 -42
  256. data/chef/travis-cookbooks/messaging_broker/haproxy/templates/default/haproxy-app_lb.cfg.erb +0 -34
  257. data/chef/travis-cookbooks/messaging_broker/haproxy/templates/default/haproxy-default.erb +0 -4
  258. data/chef/travis-cookbooks/messaging_broker/haproxy/templates/default/haproxy.cfg.erb +0 -27
  259. data/chef/travis-cookbooks/messaging_broker/iptables/definitions/iptables_rule.rb +0 -35
  260. data/chef/travis-cookbooks/messaging_broker/iptables/files/default/rebuild-iptables +0 -284
  261. data/chef/travis-cookbooks/messaging_broker/iptables/metadata.rb +0 -10
  262. data/chef/travis-cookbooks/messaging_broker/iptables/recipes/default.rb +0 -50
  263. data/chef/travis-cookbooks/messaging_broker/iptables/templates/default/all_established.erb +0 -2
  264. data/chef/travis-cookbooks/messaging_broker/iptables/templates/default/all_icmp.erb +0 -2
  265. data/chef/travis-cookbooks/messaging_broker/iptables/templates/default/iptables_load.erb +0 -3
  266. data/chef/travis-cookbooks/messaging_broker/openssl/README.md +0 -37
  267. data/chef/travis-cookbooks/messaging_broker/openssl/metadata.rb +0 -8
  268. data/chef/travis-cookbooks/messaging_broker/rabbitmq/README.md +0 -86
  269. data/chef/travis-cookbooks/messaging_broker/rabbitmq/attributes/default.rb +0 -10
  270. data/chef/travis-cookbooks/messaging_broker/rabbitmq/metadata.rb +0 -63
  271. data/chef/travis-cookbooks/messaging_broker/rabbitmq/providers/user.rb +0 -66
  272. data/chef/travis-cookbooks/messaging_broker/rabbitmq/providers/vhost.rb +0 -34
  273. data/chef/travis-cookbooks/messaging_broker/rabbitmq/recipes/cluster.rb +0 -35
  274. data/chef/travis-cookbooks/messaging_broker/rabbitmq/recipes/default.rb +0 -51
  275. data/chef/travis-cookbooks/messaging_broker/rabbitmq/resources/user.rb +0 -25
  276. data/chef/travis-cookbooks/messaging_broker/rabbitmq/templates/default/doterlang.cookie.erb +0 -1
  277. data/chef/travis-cookbooks/messaging_broker/rabbitmq/templates/default/rabbitmq-env.conf.erb +0 -10
  278. data/chef/travis-cookbooks/messaging_broker/rabbitmq/templates/default/rabbitmq_cluster.config.erb +0 -5
  279. data/ci_build.sh +0 -20
  280. data/docs/ci_yml.md +0 -39
  281. data/features/ci.feature +0 -29
  282. data/features/config/secrets.yml.example +0 -4
  283. data/features/step_definitions/ci_steps.rb +0 -137
  284. data/features/support/env.rb +0 -12
  285. data/lib/generators/lobot/USAGE +0 -15
  286. data/lib/generators/lobot/config_generator.rb +0 -141
  287. data/lib/generators/lobot/install_generator.rb +0 -25
  288. data/lib/generators/lobot/templates/Capfile +0 -6
  289. data/lib/generators/lobot/templates/ci.yml +0 -22
  290. data/lib/generators/lobot/templates/ci_build.sh +0 -22
  291. data/lib/generators/lobot/templates/deploy-ci.rb +0 -7
  292. data/lib/generators/lobot/templates/soloistrc +0 -23
  293. data/lib/lobot/jenkins.rb +0 -17
  294. data/lib/lobot/railtie.rb +0 -20
  295. data/lib/lobot/recipes/ci.rb +0 -78
  296. data/lib/lobot/tasks/ci.rake +0 -93
  297. data/spec/lib/lobot/jenkins_spec.rb +0 -14
@@ -0,0 +1,13 @@
1
+ #!/bin/bash -le
2
+
3
+ source .rvmrc
4
+
5
+ # install bundler if necessary
6
+ set -e
7
+
8
+ gem install bundler --no-ri --no-rdoc && bundle install
9
+
10
+ # debugging info
11
+ echo USER=$USER && ruby --version && which ruby && which bundle
12
+
13
+ bundle exec rspec spec
@@ -1,3 +1,3 @@
1
1
  module Lobot
2
- VERSION = "2.0.0pre"
3
- end
2
+ VERSION = "2.1.0"
3
+ end
@@ -15,23 +15,22 @@ Gem::Specification.new do |s|
15
15
  s.rubyforge_project = "lobot"
16
16
 
17
17
  s.files = `git ls-files`.split("\n") + `cd chef/travis-cookbooks && git ls-files`.split("\n").map { |f| "chef/travis-cookbooks/#{f}" }
18
- s.test_files = `git ls-files -- {test,spec,features}`.split("\n")
19
18
  s.executables = `git ls-files -- bin`.split("\n").map{ |f| File.basename(f) }
20
19
  s.require_paths = ["lib"]
21
20
 
22
21
  s.add_dependency "fog", "~> 1.6"
23
22
  s.add_dependency "ci_reporter", "~> 1.7"
24
23
  s.add_dependency "thor"
25
- s.add_dependency "hashie"
24
+ s.add_dependency "hashie", "~> 2.0.2"
25
+ s.add_dependency "haddock"
26
26
  s.add_dependency "net-ssh"
27
+ s.add_dependency "httpclient"
28
+ s.add_dependency "godot"
27
29
 
28
- s.add_development_dependency "godot"
29
30
  s.add_development_dependency "rspec"
30
- s.add_development_dependency "jasmine"
31
31
  s.add_development_dependency "guard-rspec"
32
32
  s.add_development_dependency "guard-bundler"
33
33
  s.add_development_dependency "test-kitchen"
34
- s.add_development_dependency "pry"
35
34
 
36
35
  s.add_development_dependency "terminal-notifier-guard"
37
36
  s.add_development_dependency "rb-fsevent"
@@ -20,7 +20,7 @@ then
20
20
  sudo apt-get install -y $to_install
21
21
  fi
22
22
 
23
- test -d /usr/local/rvm || curl -L https://get.rvm.io | sudo bash -s stable
23
+ test -d /usr/local/rvm || curl --location https://get.rvm.io | sudo bash -s stable
24
24
 
25
25
  sudo tee /etc/profile.d/rvm.sh > /dev/null <<RVMSH_CONTENT
26
26
  [[ -s "/usr/local/rvm/scripts/rvm" ]] && source "/usr/local/rvm/scripts/rvm"
@@ -0,0 +1,13 @@
1
+ #!/bin/bash -le
2
+
3
+ source .rvmrc
4
+
5
+ # install bundler if necessary
6
+ set -e
7
+
8
+ gem install bundler --no-ri --no-rdoc && bundle install
9
+
10
+ # debugging info
11
+ echo USER=$USER && ruby --version && which ruby && which bundle
12
+
13
+ bundle exec rspec spec --tag ~slow --tag ~vagrant --tag ~osx
@@ -0,0 +1,18 @@
1
+ -----BEGIN CERTIFICATE-----
2
+ MIIC2TCCAkKgAwIBAgIBAjANBgkqhkiG9w0BAQUFADBvMRUwEwYDVQQDDAxteWRv
3
+ bWFpbi5jb20xETAPBgNVBAsMCE9yZyBVbml0MRcwFQYDVQQKDA5NeSBPcmcgUHR5
4
+ IEx0ZDEPMA0GA1UEBwwGU3lkbmV5MQwwCgYDVQQIDANOU1cxCzAJBgNVBAYTAkFV
5
+ MB4XDTEyMTExMDIxMjgzM1oXDTQwMDMyNzIxMjgzM1oweTELMAkGA1UEBhMCQVUx
6
+ DDAKBgNVBAgMA05TVzEPMA0GA1UEBwwGU3lkbmV5MRcwFQYDVQQKDA5NeSBPcmcg
7
+ UHR5IEx0ZDERMA8GA1UECwwIT3JnIFVuaXQxHzAdBgNVBAMMFmxvYm90X3Rlc3Rf
8
+ Y2VydGlmaWNhdGUwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBAMwBCTdyENiZ
9
+ bIA74XR1Yhe7kk3E/DMhri4RNZ8MQXExNltXC71rzOyhhoq77ND64VzBCZuT/iMb
10
+ RLK29C0SN/XQQa/vqPml4tUTyONqKogqJcXtGyCp7U5hIpW4Y+klw/LtYDPJoFM8
11
+ yMSGxzn0+YIX4KH0u9hrl+i8F5KSOl0jAgMBAAGjezB5MAkGA1UdEwQCMAAwLAYJ
12
+ YIZIAYb4QgENBB8WHU9wZW5TU0wgR2VuZXJhdGVkIENlcnRpZmljYXRlMB0GA1Ud
13
+ DgQWBBRTPY4WEkIjl5AkbeYhQ9aVGacA3zAfBgNVHSMEGDAWgBQ3ZYrFt76HbAP6
14
+ rHBbiEbUjSF+KDANBgkqhkiG9w0BAQUFAAOBgQAwNlqhnO7RZe2q9Y2GzBJe6xTU
15
+ rI4zAEaNPjQFjVgytiYl6w6xS48Ksx46boZ1/RyGRO7N0PgloIWSDnVWDvHgIz2F
16
+ vGho9G63qQtzu122WU9XcW1KDaN+0tQCO/Ow3l9CUUe/J1mzyfLtP3E5e7QGYqOg
17
+ lbrTC5b3JtKGy1MSoQ==
18
+ -----END CERTIFICATE-----
@@ -0,0 +1,27 @@
1
+ -----BEGIN RSA PRIVATE KEY-----
2
+ MIIEpQIBAAKCAQEA3ItezXAizPua9JTKlxN5D3Q3RUNT7TXUbqfg3XmEEEOIcidc
3
+ yAAqG+4XVbp7Fjv80ADSWTrZzJN5/rfr762/zvupBEmDsHcaSaWo6MCTnek6uBPR
4
+ I7GwFh17zKtjrXNdZqKyHn6STwdcar5hh282sqbs7TJjVVnSLuJbjTZEsSVS3r3/
5
+ CVhWTxVQbis/fgE7IQkGCKDDtEJtXRR3VBtDz5n5Ez0aefsjUxtcgSJKLJoVJrOM
6
+ DVO/rIvbiAEBXy3uZsFi9uSvTp0nIyE5t8GPoQeG8pgcgiahNOy+sIiWcbK5BXrb
7
+ SrdWi0NfW+2CfJGzJXo2Fs09QVzpUyts2GAqaQIDAQABAoIBAQC9ab2MN4jMADO/
8
+ Z6LvSbwpd6iYhhCopBjEyM4pqNmxli6zy/a1lt6TilLkP/rCx9aDVpFSLWctemPG
9
+ TnQGL3WS8TTiB7lgb4pWQj7lV6/waYUS34I5Y7xV4hCXYYOETpajNYxBAHfsA+ht
10
+ jQD6bpvNp+vIdAQ4I6KOvb3fdAJfGJSmdr5Yqas2u9DqCidrw4gQ5cPRwxpki+8n
11
+ s6eGKw6HGaoqYk/hsLECec5kZqy89lrn/E0+1xzlUwBXSaUsbLUKE6toHMZzoSIP
12
+ tUIh+WoKe0gt2s4j+sMD0wSYmny0UvuFyDlyQHDOSE8TSVODGWhEr1pztqklYEfg
13
+ oM4JrqPZAoGBAPfd9eS0qviFvRloOxPIdEeHaCc7+yBQnBWBDvgA19fcvFByJlmr
14
+ i6qrQmChIxZS8loDGKQEPsJnrVKww15GcmDU0yesAfQHmXpplQK3cslTXhghwC3z
15
+ p7ohMLnWjEi9Q+k0RizhFCq55w7+9U+E5wbW9017MAzC4A52mhm+GDZ/AoGBAOPH
16
+ 55TxoF4/o3rrXNtjajQ/DBYZPAmUbqpdj0QQIRkIxziiV44Aw2HmdqgtlZaQ5a/r
17
+ 8qUJCO2/on/zyQvjByx/sGfdqhOcVymySGSPOSusk6cwq2oCaDPdwZorrzueE0jV
18
+ DgHFF9Y3p1W5CEl4Um6IWRZZS9PK4cPC/p1mXDsXAoGAVO1JTjaVChgQxb7P1yRs
19
+ qwF7L04+6kCUak3RCiqHyh+IqmuiNkEv1qddU+yCMCj1ft/mtnP56PRLD7UfC5NJ
20
+ p2Hkg4hNFwbvkGDSvJ6Mhuy4pb4Ssev1QTIUFuirIlUvCp1tmfz4wvb1c07qUHey
21
+ DMbk7zhRK14uFOaQQFfAxhMCgYEAhQINY7b4mzB0COn5Dg7uTFXoe9r+aOWo/Yim
22
+ iOsWOKUcmCCMGdquPLOz5B7CM+qmhOS1itNMyG/XtvmnE27dmIlzfCM/FjZ721hE
23
+ 15uembcrfTx5S+zd5jN+wsTxjVGQFz558GSjt65F41Op2CUPlYW+58L6+VCGJqbt
24
+ wQGtp78CgYEA8WD+AcC70tS0h+siJoG2AYvQfBmZPGcZjGmban8SGRHcXMctpVw/
25
+ LOP18TY4/nfT/j4OwwZ07SlCbIWPJm7+u0IiWxmf5j48pGy7p1oMxih9IggXr0+t
26
+ KyWHrnBl8O90L7QLmSBzfOHAIoPhejgAqqADQd9lSDXSSW7GhVh0g4Q=
27
+ -----END RSA PRIVATE KEY-----
@@ -0,0 +1 @@
1
+ ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDci17NcCLM+5r0lMqXE3kPdDdFQ1PtNdRup+DdeYQQQ4hyJ1zIACob7hdVunsWO/zQANJZOtnMk3n+t+vvrb/O+6kESYOwdxpJpajowJOd6Tq4E9EjsbAWHXvMq2Otc11morIefpJPB1xqvmGHbzaypuztMmNVWdIu4luNNkSxJVLevf8JWFZPFVBuKz9+ATshCQYIoMO0Qm1dFHdUG0PPmfkTPRp5+yNTG1yBIkosmhUms4wNU7+si9uIAQFfLe5mwWL25K9OnScjITm3wY+hB4bymByCJqE07L6wiJZxsrkFettKt1aLQ19b7YJ8kbMlejYWzT1BXOlTK2zYYCpp pivotal@holloway
@@ -1,108 +1,149 @@
1
1
  require "spec_helper"
2
2
 
3
- describe Lobot::Amazon, :slow => true do
3
+ describe Lobot::Amazon, :slow do
4
+ subject(:amazon) { Lobot::Amazon.new(ENV["EC2_KEY"], ENV["EC2_SECRET"]) }
4
5
  let(:tempdir) { Dir.mktmpdir }
5
- let(:amazon) { Lobot::Amazon.new(ENV["EC2_KEY"], ENV["EC2_SECRET"]) }
6
6
  let(:fog) { amazon.send(:fog) }
7
7
 
8
+ before { pending "Missing EC2 Credentials" unless SpecHelpers::ec2_credentials_present? }
9
+
8
10
  describe "#create_security_group" do
11
+ after { amazon.fog_security_groups.get(security_group).destroy if SpecHelpers::ec2_credentials_present? }
12
+
9
13
  context "when there is no existing security group" do
14
+ let(:security_group) { "totally_not_a_honeypot" }
15
+
10
16
  it "creates a security group" do
11
- amazon.create_security_group("totally_not_a_honeypot")
12
- amazon.security_groups.map(&:name).should include "totally_not_a_honeypot"
17
+ amazon.create_security_group(security_group)
18
+ amazon.fog_security_groups.map(&:name).should include security_group
13
19
  end
14
20
  end
15
21
 
16
22
  context "when the security group already exists" do
17
- before { amazon.create_security_group("bart_police") }
23
+ let(:security_group) { "bart_police" }
24
+ before { amazon.create_security_group(security_group) }
18
25
 
19
26
  it "does not complain" do
20
- expect { amazon.create_security_group("bart_police") }.not_to raise_error
27
+ expect { amazon.create_security_group(security_group) }.not_to raise_error
21
28
  end
22
29
  end
23
30
  end
24
31
 
25
32
  describe "#open_port" do
26
- before { amazon.create_security_group("bag_of_weasels") }
33
+ let(:security_group) { "bag_of_weasels" }
34
+ let(:group) { amazon.fog_security_groups.get(security_group) }
27
35
 
28
- let(:group) { amazon.security_groups.get("bag_of_weasels") }
36
+ before { amazon.create_security_group(security_group) }
37
+ after { amazon.fog_security_groups.get(security_group).destroy if SpecHelpers::ec2_credentials_present? }
29
38
 
30
- def includes_port?(permissions, ports)
31
- permissions.any? { |p| (p["fromPort"]..p["toPort"]).include?(80) }
39
+ def includes_port?(permissions, port)
40
+ permissions.any? { |p| (p["fromPort"]..p["toPort"]).include?(port) }
32
41
  end
33
42
 
34
43
  it "opens a port for business" do
35
44
  group.ip_permissions.should_not include "80"
36
- amazon.open_port("bag_of_weasels", 80)
45
+ amazon.open_port(security_group, 80)
37
46
  includes_port?(group.reload.ip_permissions, 80).should be_true
38
47
  end
39
48
 
40
49
  it "takes a bunch of ports" do
41
- amazon.open_port("bag_of_weasels", 22, 443)
50
+ amazon.open_port(security_group, 22, 443)
42
51
  includes_port?(group.reload.ip_permissions, 22).should be_true
43
52
  includes_port?(group.reload.ip_permissions, 443).should be_true
44
53
  end
45
54
  end
46
55
 
47
56
  describe "#add_key_pair" do
48
- let(:key_pair_path) { "#{tempdir}/supernuts" }
57
+ let(:key_pair_pub) { File.read(File.expand_path(ssh_key_pair_path + ".pub")) }
58
+ let(:key_pair_name) { "is_supernuts" }
49
59
 
50
- before do
51
- system "ssh-keygen -q -f #{key_pair_path} -P ''"
52
- amazon.delete_key_pair("is_supernuts")
53
- end
60
+ before { amazon.delete_key_pair(key_pair_name) }
61
+ after { amazon.delete_key_pair(key_pair_name) if SpecHelpers::ec2_credentials_present? }
54
62
 
55
63
  it "uploads the key" do
56
- amazon.add_key_pair("is_supernuts", "#{key_pair_path}.pub")
57
- amazon.key_pairs.map(&:name).should include "is_supernuts"
64
+ amazon.add_key_pair(key_pair_name, key_pair_pub)
65
+ amazon.fog_key_pairs.map(&:name).should include key_pair_name
58
66
  end
59
67
 
60
68
  context "when the key is already there" do
61
- before { amazon.add_key_pair("is_supernuts", "#{key_pair_path}.pub") }
69
+ before { amazon.add_key_pair(key_pair_name, key_pair_pub) }
62
70
 
63
71
  it "doesn't reupload" do
64
72
  expect do
65
- amazon.add_key_pair("is_supernuts", "#{key_pair_path}.pub")
73
+ amazon.add_key_pair(key_pair_name, key_pair_pub)
66
74
  end.not_to raise_error
67
75
  end
68
76
  end
69
77
  end
70
78
 
71
79
  describe "things which launch instances" do
72
- let(:key_pair_path) { "#{tempdir}/cookie" }
80
+ let(:key_pair_name) { "eating_my_cookie" }
81
+ let(:security_group) { "chump_of_change" }
82
+ let(:key_pair_pub) { File.read(File.expand_path(ssh_key_pair_path + ".pub")) }
83
+ let(:freshly_launched_server) { amazon.launch_server(key_pair_name, security_group, "t1.micro") }
73
84
 
74
85
  before do
75
- system "ssh-keygen -q -f #{key_pair_path} -P ''"
76
- amazon.add_key_pair("eating_my_cookie", "#{key_pair_path}.pub")
77
- amazon.create_security_group("chump_of_change")
86
+ amazon.delete_key_pair(key_pair_name)
87
+ amazon.add_key_pair(key_pair_name, key_pair_pub)
88
+ amazon.create_security_group(security_group)
78
89
  end
79
90
 
80
- let(:freshly_launched_server) { amazon.launch_server("eating_my_cookie", "chump_of_change", "t1.micro") }
91
+ after do
92
+ if SpecHelpers::ec2_credentials_present?
93
+ freshly_launched_server.destroy
94
+ amazon.delete_key_pair(key_pair_name)
95
+ # Make a best effort attempt to clean up after the tests have completed
96
+ # EC2 does not always reap these resources fast enough for our tests, we could wait, but why bother?
97
+ amazon.elastic_ip_address.destroy rescue nil
98
+ amazon.fog_security_groups.get(security_group).destroy rescue nil
99
+ end
100
+ end
81
101
 
82
102
  describe "#launch_instance" do
83
103
  it "creates an instance" do
84
- expect { freshly_launched_server }.to change { amazon.servers.reload.count }.by(1)
104
+ expect { freshly_launched_server }.to change { amazon.fog_servers.reload.count }.by(1)
85
105
 
86
- freshly_launched_server.availability_zone.should == "us-east-1a"
106
+ freshly_launched_server.availability_zone.should =~ /us-east-1[abcd]/
87
107
  freshly_launched_server.flavor_id.should == "t1.micro"
88
- freshly_launched_server.tags.should == {"lobot"=>Lobot::VERSION, "Name"=>"Lobot"}
89
- freshly_launched_server.key_name.should == "eating_my_cookie"
90
- freshly_launched_server.groups.should == ["chump_of_change"]
108
+ freshly_launched_server.tags.should == {"lobot" => Lobot::VERSION, "Name" => "Lobot"}
109
+ freshly_launched_server.key_name.should == key_pair_name
110
+ freshly_launched_server.groups.should == [security_group]
91
111
  freshly_launched_server.public_ip_address.should == amazon.elastic_ip_address.public_ip
92
-
93
- freshly_launched_server.destroy
94
- amazon.elastic_ip_address.destroy
95
112
  end
96
113
  end
97
114
 
98
115
  describe "#destroy_ec2" do
99
116
  let!(:server_ip) { freshly_launched_server.public_ip_address }
100
117
 
101
- it "stops all the instances" do
102
- expect do
103
- amazon.destroy_ec2
104
- end.to change { freshly_launched_server.reload.state }.from("running")
105
- fog.addresses.get(server_ip).should_not be
118
+ context 'with a confirmation Proc that returns true' do
119
+ let(:proc) { ->(_) { true } }
120
+
121
+ it "stops all the instances" do
122
+ # TODO: This probably needs some more testing with n > 1 instances
123
+ expect do
124
+ amazon.destroy_ec2(proc, :all)
125
+ end.to change { freshly_launched_server.reload.state }.from("running")
126
+ fog.addresses.get(server_ip).should_not be
127
+ end
128
+
129
+ it "stops the named instances" do
130
+ expect do
131
+ amazon.destroy_ec2(proc, freshly_launched_server.id)
132
+ freshly_launched_server.wait_for { !ready? }
133
+ end.to change { freshly_launched_server.reload.state }.from("running")
134
+ fog.addresses.get(server_ip).should_not be
135
+ end
136
+ end
137
+
138
+ context 'with a confirmation Proc that returns false' do
139
+ let(:proc) { ->(_) { false } }
140
+
141
+ it 'does not stop instances' do
142
+ expect do
143
+ amazon.destroy_ec2(proc, :all)
144
+ end.to_not change { freshly_launched_server.reload.state }.from("running")
145
+ fog.addresses.get(server_ip).should be
146
+ end
106
147
  end
107
148
  end
108
149
  end
@@ -1,212 +1,281 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe Lobot::CLI do
4
- let(:tempfile) do
5
- Tempfile.new('lobot-config').tap do |file|
6
- file.write YAML.dump({})
7
- file.close
8
- end
9
- end
10
-
11
- let(:lobot_config) { Lobot::Config.new(:aws_key => ENV["EC2_KEY"], :aws_secret => ENV["EC2_SECRET"]) }
12
4
  let(:cli) { subject }
13
- let(:sobo) { Lobot::Sobo.new(lobot_config.master, lobot_config.server_ssh_key) }
5
+ let(:sobo) { Lobot::Sobo.new(lobot_config.master, lobot_config.server_ssh_key_path) }
14
6
 
15
7
  before do
16
- cli.stub(:lobot_config).and_return(lobot_config)
8
+ cli.stub(:lobot_config).and_return(lobot_config) # lobot_config must be defined in each context below
17
9
  end
18
10
 
19
- describe "#ssh" do
20
- it "starts an ssh session to the lobot host" do
21
- cli.should_receive(:exec).with("ssh -i #{cli.lobot_config.server_ssh_key} ubuntu@#{cli.lobot_config.master} -p #{cli.lobot_config.ssh_port}")
22
- cli.ssh
11
+ context 'with Amazon' do
12
+ let(:lobot_config) {
13
+ Lobot::Config.new(
14
+ :aws_key => ENV["EC2_KEY"],
15
+ :aws_secret => ENV["EC2_SECRET"],
16
+ :server_ssh_key => ssh_key_pair_path)
17
+ }
18
+
19
+ describe '#create & #destroy_ec2', :slow, :ec2 do
20
+ it "launches an instance and associates elastic ip" do
21
+ pending "Missing EC2 Credentials" unless SpecHelpers::ec2_credentials_present?
22
+ cli.lobot_config.instance_size = 't1.micro'
23
+ expect { cli.create }.to change { lobot_config.master }.from(nil)
24
+
25
+ cli.stub(:options).and_return({'force' => 'force'})
26
+ expect { cli.destroy_ec2 }.to change { lobot_config.master }.to(nil)
27
+ end
23
28
  end
24
- end
25
29
 
26
- describe "#open" do
27
- let(:lobot_config) do
28
- Lobot::Config.new(:node_attributes => {
29
- :nginx => {
30
- :basic_auth_user => "ci",
31
- :basic_auth_password => "secret"
32
- }
33
- })
30
+ describe "#ssh" do
31
+ it "starts an ssh session to the lobot host" do
32
+ cli.should_receive(:exec).with("ssh -i #{cli.lobot_config.server_ssh_key_path} ubuntu@#{cli.lobot_config.master} -p #{cli.lobot_config.ssh_port}")
33
+ cli.ssh
34
+ end
34
35
  end
35
36
 
36
- it "opens a web browser with the lobot page" do
37
- cli.should_receive(:exec).with("open https://#{cli.lobot_config.node_attributes.nginx.basic_auth_user}:#{cli.lobot_config.node_attributes.nginx.basic_auth_password}@#{cli.lobot_config.master}/")
38
- cli.open
39
- end
40
- end
41
-
42
- describe "#add_build" do
43
- let(:name) { "bob" }
44
- let(:repository) { "http://github.com/mkocher/soloist.git" }
45
- let(:branch) { "master" }
46
- let(:command) { "script/ci_build.sh" }
47
-
48
- it "adds a build to the node attributes" do
49
- cli.add_build(name, repository, branch, command)
50
- lobot_config.node_attributes.jenkins.builds.should =~ [{
51
- "name" => "bob",
52
- "repository" => "http://github.com/mkocher/soloist.git",
53
- "command" => "script/ci_build.sh",
54
- "branch" => "master"
55
- }]
56
- end
37
+ describe "#open", :osx do
38
+ let(:lobot_config) do
39
+ Lobot::Config.new(:node_attributes => {
40
+ :nginx => {
41
+ :basic_auth_user => "ci",
42
+ :basic_auth_password => "secret"
43
+ }
44
+ })
45
+ end
57
46
 
58
- it "does not add a build twice with identical parameters" do
59
- cli.add_build(name, repository, branch, command)
60
- cli.add_build(name, repository, branch, command)
61
- lobot_config.node_attributes.jenkins.builds.should =~ [{
62
- "name" => "bob",
63
- "repository" => "http://github.com/mkocher/soloist.git",
64
- "command" => "script/ci_build.sh",
65
- "branch" => "master"
66
- }]
47
+ it "opens a web browser with the lobot page" do
48
+ lobot_config.master = "127.0.0.1"
49
+ cli.should_receive(:exec).with("open https://ci:secret@127.0.0.1/")
50
+ cli.open
51
+ end
67
52
  end
68
53
 
69
- context "with persisted configuration data" do
70
- let(:lobot_config) { Lobot::Config.from_file(tempfile.path) }
54
+ describe "#trust_certificate", :osx do
55
+ let(:keychain) { Lobot::Keychain.new("/Library/Keychains/System.keychain") }
56
+ before { lobot_config.master = "192.168.99.99" }
71
57
 
72
- def builds
73
- cli.lobot_config.reload.node_attributes.jenkins.builds
74
- end
58
+ it "adds the key to the keychain" do
59
+ fake_keychain = double(:keychain)
60
+ fake_keychain.should_receive(:fetch_remote_certificate).with("https://#{lobot_config.master}/").and_return("IAMACERTIFICATE")
61
+ fake_keychain.should_receive(:add_certificate).with("IAMACERTIFICATE")
62
+ Lobot::Keychain.should_receive(:new).with("/Library/Keychains/System.keychain").and_return(fake_keychain)
75
63
 
76
- it "persists a build" do
77
- cli.add_build(name, repository, branch, command)
78
- builds.should_not be_nil
79
- builds.should_not be_empty
64
+ cli.trust_certificate
80
65
  end
81
66
  end
82
- end
83
-
84
- shared_examples_for "a start command that updates known_hosts" do
85
- let(:key) { "AAAAB3NzaC1yc2EAAAADAQABAAABAQDjhJ/xZCgVhq9Xk+3DKJZ6tcgyIHcIXKSzu6Z/EK1uykyHeP/i7CwwKgiAv7lAV7B4UiUMHUm2nEiguog9VtYc6mc0g1N829lnuMhPRyOTb0SSYTNEN7Uuwy10cuq3Rd/9QAdxNV/voQW3Rl60BFzZvzp8UxJzCXFT1NmB+0W45X7Ypstv0oVV/EdyJJUuoPijQ097A4kHt6KUThKzxhagh1UrVTCE6eccscxuuRPX3yCEf8cUaVrKtuSE3vZnBcmSOY92zA4NV/YdJYNPIrKyCvWb/R+nC4R0pQNqv1gSEqPT51wYxKnvmIPFGntKaJSN2qmMlvs/AlFnFOeUsUFN" }
86
67
 
87
- def known_hosts_contents
88
- File.read(File.expand_path('~/.ssh/known_hosts'))
89
- end
68
+ describe "#add_build" do
69
+ let(:name) { "bob" }
70
+ let(:repository) { "http://github.com/mkocher/soloist.git" }
71
+ let(:branch) { "master" }
72
+ let(:command) { "script/ci_build.sh" }
90
73
 
91
- it "clears out the entry in knownhosts as this is a new box but the ip may be recycled" do
92
- system "echo '#{ip_address} ssh-rsa #{key}' >> ~/.ssh/known_hosts"
93
- action
94
- known_hosts_contents.should_not include(key)
95
- known_hosts_contents.should include(ip_address)
96
- end
74
+ context "when the config is invalid" do
75
+ before { lobot_config.node_attributes.jenkins = {} }
97
76
 
98
- it "doesn't mess with other entries" do
99
- expect { action }.not_to change { known_hosts_contents }
100
- end
101
- end
77
+ it "raises an error" do
78
+ expect do
79
+ cli.add_build(name, repository, branch, command)
80
+ end.to raise_error %r{your config file does not have a}
81
+ end
82
+ end
102
83
 
103
- describe "#create", :slow => true do
104
- it "launches an instance and associates elastic ip" do
105
- cli.lobot_config.instance_size = 't1.micro'
106
- expect { cli.create }.to change { lobot_config.master }.from(nil)
107
- expect { cli.destroy_ec2 }.to change { lobot_config.master }.to(nil)
84
+ context "when the configuration is valid" do
85
+ context "with persisted configuration data" do
86
+ let(:tempfile) do
87
+ Tempfile.new('lobot-config').tap do |file|
88
+ file.write YAML.dump({})
89
+ file.close
90
+ end
91
+ end
92
+
93
+ let(:lobot_config) { Lobot::Config.from_file(tempfile.path) }
94
+
95
+ def builds
96
+ cli.lobot_config.reload.node_attributes.jenkins.builds
97
+ end
98
+
99
+ it "persists a build" do
100
+ cli.add_build(name, repository, branch, command)
101
+ builds.should_not be_nil
102
+ builds.should_not be_empty
103
+ end
104
+ end
105
+ end
108
106
  end
109
107
 
110
108
  context "with a fake amazon" do
111
- let(:ip_address) { "192.168.33.10" }
109
+ let(:ip_address) { "127.0.0.1" }
112
110
  let(:server) { double("server", :public_ip_address => ip_address).as_null_object }
113
111
  let(:amazon) { double("AMZN", :launch_server => server).as_null_object }
112
+ let(:instance_id) { 'i-xxxxxx' }
114
113
 
115
- before { cli.stub(:amazon).and_return(amazon) }
116
-
117
- def action
118
- cli.create
114
+ before do
115
+ cli.stub(:amazon).and_return(amazon)
119
116
  end
120
117
 
121
- it_behaves_like "a start command that updates known_hosts"
122
-
123
- context "with a custom instance size", :slow => false do
124
- before { cli.lobot_config.instance_size = 'really_big_instance' }
118
+ describe "#create" do
119
+ before do
120
+ amazon.stub(:with_key_pair).and_yield("unique-key-pair-name")
121
+ cli.should_receive(:wait_for_server)
122
+ end
125
123
 
126
- it "launches the instance with the configured instance size" do
127
- amazon.should_receive(:launch_server).with(anything, anything, 'really_big_instance')
124
+ it "uses the configured key pair" do
125
+ amazon.should_receive(:with_key_pair).with(cli.lobot_config.server_ssh_pubkey)
128
126
  cli.create
129
127
  end
130
- end
131
- end
132
- end
133
128
 
134
- describe "#create_vagrant" do
135
- before do
136
- File.open(tempfile.path, "w") do |f|
137
- f.write(YAML.dump(
138
- "node_attributes" => {
139
- "nginx" => {
140
- "basic_auth_user" => "ci",
141
- "basic_auth_password" => "secret"
142
- }
143
- }
144
- ))
129
+ context "with a custom instance size", :slow => false do
130
+ before { cli.lobot_config.instance_size = 'really_big_instance' }
131
+
132
+ it "launches the instance with the configured instance size" do
133
+ amazon.should_receive(:launch_server).with(anything, anything, 'really_big_instance')
134
+ cli.create
135
+ end
136
+ end
145
137
  end
146
- end
147
138
 
148
- def lobot_config
149
- Lobot::Config.from_file(tempfile.path)
150
- end
139
+ describe "destroy_ec2" do
140
+ before do
141
+ cli.lobot_config.master = ip_address
142
+ cli.lobot_config.instance_id = instance_id
143
+ end
151
144
 
152
- it "starts a virtual machine" do
153
- cli.create_vagrant
154
- Godot.wait('192.168.33.10', 22).should be
155
- end
145
+ context 'by default' do
146
+ before do
147
+ amazon.stub(:destroy_ec2).and_yield(mock("SERVER").as_null_object)
148
+ end
149
+
150
+ it 'deletes the known instance' do
151
+ amazon.should_receive(:destroy_ec2).and_yield(mock("SERVER").as_null_object)
152
+ cli.destroy_ec2
153
+ end
154
+
155
+ it 'clears the master ip address' do
156
+ expect { cli.destroy_ec2 }.to change(cli.lobot_config, :master).to(nil)
157
+ end
158
+
159
+ it 'clears the master instance id' do
160
+ expect { cli.destroy_ec2 }.to change(cli.lobot_config, :instance_id).to(nil)
161
+ end
162
+
163
+ it 'does not delete sibling instances' do
164
+ amazon.should_receive(:destroy_ec2).with(a_kind_of(Proc), instance_id)
165
+ cli.destroy_ec2
166
+ end
167
+
168
+ it 'prompts for confirmation' do
169
+ cli.should_receive(:yes?).and_return(true)
170
+ amazon.should_receive(:destroy_ec2).with(a_kind_of(Proc), instance_id) do |confirm_proc, instance_id|
171
+ confirm_proc.call(mock("SERVER").as_null_object)
172
+ end
173
+ cli.destroy_ec2
174
+ end
175
+ end
156
176
 
157
- it "updates the config master ip address" do
158
- expect { cli.create_vagrant }.to change { lobot_config.master }.to('192.168.33.10')
159
- end
177
+ context 'with --all' do
178
+ before do
179
+ cli.stub(:options).and_return({'all' => 'all'})
180
+ end
160
181
 
161
- context "known_hosts" do
162
- let(:ip_address) { "192.168.33.10" }
182
+ it 'deletes everything tagged "lobot"' do
183
+ amazon.should_receive(:destroy_ec2).with(a_kind_of(Proc), :all)
184
+ cli.destroy_ec2
185
+ end
186
+ end
163
187
 
164
- def action
188
+ context 'with --force' do
189
+ before do
190
+ cli.stub(:options).and_return({'force' => 'force'})
191
+ end
192
+
193
+ it 'does not prompt for confirmation' do
194
+ cli.should_not_receive(:ask)
195
+ amazon.should_receive(:destroy_ec2).with(a_kind_of(Proc), instance_id) do |confirm_proc, instance_id|
196
+ confirm_proc.call(mock("SERVER").as_null_object)
197
+ end
198
+ cli.destroy_ec2
199
+ end
200
+ end
201
+ end
202
+ end
203
+ end
204
+
205
+ context 'with Vagrant', :vagrant do
206
+ let(:lobot_config) {
207
+ Lobot::Config.new(
208
+ "node_attributes" => {
209
+ "jenkins" => {
210
+ "builds" => []
211
+ },
212
+ "nginx" => {
213
+ "basic_auth_user" => "ci",
214
+ "basic_auth_password" => "secret"
215
+ }
216
+ },
217
+ "server_ssh_key" => ssh_key_pair_path,
218
+ "github_ssh_key" => ssh_key_pair_path
219
+ )
220
+ }
221
+
222
+ describe "#create_vagrant" do
223
+ it "starts a virtual machine" do
165
224
  cli.create_vagrant
225
+ Godot.wait('192.168.33.10', 22).should be
166
226
  end
167
227
 
168
- it_behaves_like "a start command that updates known_hosts"
228
+ it "updates the config master ip address" do
229
+ expect { cli.create_vagrant }.to change { lobot_config.master }.to('192.168.33.10')
230
+ end
169
231
  end
170
- end
171
232
 
172
- describe "#bootstrap", :slow => true do
173
- before { cli.create_vagrant }
233
+ describe "#bootstrap", :slow do
234
+ before { cli.create_vagrant }
174
235
 
175
- it "installs all necessary packages, installs rvm and sets up the user" do
176
- cli.bootstrap
177
- sobo.exec!("dpkg --get-selections").should include("libncurses5-dev")
178
- sobo.exec!("ls /usr/local/rvm/").should_not be_empty
179
- sobo.exec!("groups ubuntu").should include("rvm")
236
+ it "installs all necessary packages, installs rvm and sets up the user" do
237
+ cli.bootstrap
238
+ sobo.backtick("dpkg --get-selections").should include("libncurses5-dev")
239
+ sobo.backtick("ls /usr/local/rvm/").should_not be_empty
240
+ sobo.backtick("groups ubuntu").should include("rvm")
241
+ end
180
242
  end
181
- end
182
243
 
183
- describe "#chef", :slow => true do
184
- let(:name) { "Bob" }
185
- let(:repository) { "http://github.com/mkocher/soloist.git" }
186
- let(:branch) { "master" }
187
- let(:command) { "exit 0" }
244
+ describe "#chef", :slow do
245
+ let(:name) { "Bob" }
246
+ let(:repository) { "http://github.com/mkocher/soloist.git" }
247
+ let(:branch) { "master" }
248
+ let(:command) { "exit 0" }
188
249
 
189
- let(:godot) { Godot.new(cli.master_server.ip, 8080) }
190
- let(:jenkins) { Lobot::Jenkins.new(lobot_config) }
250
+ let(:godot) { Godot.new(cli.master_server.ip, 8080, timeout: 180) }
251
+ let(:jenkins) { Lobot::Jenkins.new(lobot_config) }
191
252
 
192
- before do
193
- cli.create_vagrant
194
- cli.bootstrap
195
- cli.add_build(name, repository, branch, command)
196
- end
253
+ before do
254
+ cli.create_vagrant
255
+ cli.bootstrap
256
+ cli.add_build(name, repository, branch, command)
257
+ FileUtils.mkdir_p("/tmp/lobot_dummy/cookbooks/pork/recipes/")
258
+ File.write("/tmp/lobot_dummy/cookbooks/pork/recipes/bacon.rb", "package 'htop'")
259
+ end
197
260
 
198
- it "runs chef" do
199
- cli.lobot_config.recipes = ["pivotal_ci::jenkins", "pivotal_ci::id_rsa", "pivotal_ci::git_config", "sysctl", "pivotal_ci::jenkins_config"]
200
- cli.chef
261
+ after do
262
+ FileUtils.rm_rf("/tmp/lobot_dummy")
263
+ end
201
264
 
202
- sobo.exec!("ls /var/lib/").should include "jenkins"
203
- sobo.exec!("grep 'kernel.shmmax=' /etc/sysctl.conf").should_not be_empty
204
- sobo.exec!("sudo cat /var/lib/jenkins/.ssh/id_rsa").should == File.read(lobot_config.github_ssh_key)
265
+ it "runs chef" do
266
+ Dir.chdir('/tmp/lobot_dummy/') do
267
+ cli.lobot_config.recipes = ["pivotal_ci::jenkins", "pivotal_ci::id_rsa", "pivotal_ci::git_config", "sysctl", "pivotal_ci::jenkins_config", "pork::bacon"]
268
+ cli.chef
269
+ end
205
270
 
206
- godot.wait!
207
- godot.match!(/Bob/, 'api/json')
271
+ sobo.backtick("ls /var/lib/").should include "jenkins"
272
+ sobo.backtick("grep 'kernel.shmmax=' /etc/sysctl.conf").should_not be_empty
273
+ sobo.backtick("sudo cat /var/lib/jenkins/.ssh/id_rsa").should == lobot_config.github_ssh_key
274
+ sobo.system("dpkg -l htop").should == 0
208
275
 
209
- jenkins.jobs.first.name.should == "Bob"
276
+ godot.wait!
277
+ godot.match!(/Bob/, 'api/json')
278
+ end
210
279
  end
211
280
  end
212
281
  end