motherbrain 0.0.0.placeholder → 0.13.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (259) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +9 -0
  3. data/.ruby-version +1 -0
  4. data/.travis.yml +9 -0
  5. data/CHANGELOG.md +196 -0
  6. data/COMMANDS.md +9 -0
  7. data/CONTRIBUTING.md +24 -0
  8. data/Dockerfile +26 -0
  9. data/Gemfile +60 -2
  10. data/Guardfile +30 -0
  11. data/LICENSE +10 -0
  12. data/MANIFESTS.md +90 -0
  13. data/OPERATORS_GUIDE.md +195 -0
  14. data/PLUGINS.md +268 -0
  15. data/README.md +304 -16
  16. data/Thorfile +123 -0
  17. data/VAGRANT.md +116 -0
  18. data/bin/boot +9 -0
  19. data/bin/mb +5 -0
  20. data/bin/mbsrv +5 -0
  21. data/config.json +32 -0
  22. data/features/cli/bootstrap_command/configurable_scripts.feature +32 -0
  23. data/features/cli/configure_command.feature +57 -0
  24. data/features/cli/environment_command/create_command.feature +22 -0
  25. data/features/cli/environment_command/destroy_command.feature +33 -0
  26. data/features/cli/environment_command/from_command.feature +29 -0
  27. data/features/cli/environment_command/list_command.feature +0 -0
  28. data/features/cli/node_limiting.feature +47 -0
  29. data/features/cli/plugin_command/list_command.feature +46 -0
  30. data/features/cli/service_command/service_command.feature +21 -0
  31. data/features/cli/template_command.feature +10 -0
  32. data/features/cli/validate_config.feature +46 -0
  33. data/features/step_definitions/bootstrap_steps.rb +57 -0
  34. data/features/step_definitions/chef_server_steps.rb +3 -0
  35. data/features/step_definitions/configuration_steps.rb +18 -0
  36. data/features/step_definitions/core_cli_steps.rb +33 -0
  37. data/features/step_definitions/environment_steps.rb +43 -0
  38. data/features/step_definitions/node_steps.rb +3 -0
  39. data/features/step_definitions/plugin_steps.rb +15 -0
  40. data/features/step_definitions/template_steps.rb +7 -0
  41. data/features/support/env.rb +68 -0
  42. data/lib/mb/api.rb +8 -0
  43. data/lib/mb/api/application.rb +7 -0
  44. data/lib/mb/api/endpoint.rb +5 -0
  45. data/lib/mb/api/helpers.rb +38 -0
  46. data/lib/mb/api/v1.rb +56 -0
  47. data/lib/mb/api/v1/config_endpoint.rb +12 -0
  48. data/lib/mb/api/v1/environments_endpoint.rb +174 -0
  49. data/lib/mb/api/v1/jobs_endpoint.rb +31 -0
  50. data/lib/mb/api/v1/plugins_endpoint.rb +90 -0
  51. data/lib/mb/api/validators.rb +5 -0
  52. data/lib/mb/api/validators/sem_ver.rb +18 -0
  53. data/lib/mb/application.rb +148 -0
  54. data/lib/mb/berkshelf.rb +50 -0
  55. data/lib/mb/bootstrap.rb +9 -0
  56. data/lib/mb/bootstrap/manager.rb +250 -0
  57. data/lib/mb/bootstrap/manifest.rb +131 -0
  58. data/lib/mb/bootstrap/routine.rb +199 -0
  59. data/lib/mb/bootstrap/template.rb +73 -0
  60. data/lib/mb/bootstrap/worker.rb +227 -0
  61. data/lib/mb/chef.rb +6 -0
  62. data/lib/mb/chef/config.rb +69 -0
  63. data/lib/mb/chef/run_list_item.rb +115 -0
  64. data/lib/mb/chef_mutex.rb +304 -0
  65. data/lib/mb/clean_room_base.rb +39 -0
  66. data/lib/mb/cli.rb +50 -0
  67. data/lib/mb/cli/base.rb +51 -0
  68. data/lib/mb/cli/shell.rb +29 -0
  69. data/lib/mb/cli/shell/basic.rb +11 -0
  70. data/lib/mb/cli/shell/color.rb +11 -0
  71. data/lib/mb/cli/shell/ext.rb +41 -0
  72. data/lib/mb/cli/sub_command.rb +95 -0
  73. data/lib/mb/cli/sub_command/component.rb +56 -0
  74. data/lib/mb/cli/sub_command/plugin.rb +232 -0
  75. data/lib/mb/cli_client.rb +178 -0
  76. data/lib/mb/cli_gateway.rb +426 -0
  77. data/lib/mb/cli_gateway/sub_commands.rb +3 -0
  78. data/lib/mb/cli_gateway/sub_commands/environment.rb +124 -0
  79. data/lib/mb/cli_gateway/sub_commands/plugin.rb +148 -0
  80. data/lib/mb/command.rb +88 -0
  81. data/lib/mb/command_invoker.rb +235 -0
  82. data/lib/mb/command_invoker/worker.rb +40 -0
  83. data/lib/mb/command_runner.rb +233 -0
  84. data/lib/mb/component.rb +245 -0
  85. data/lib/mb/config.rb +275 -0
  86. data/lib/mb/config_manager.rb +75 -0
  87. data/lib/mb/console.rb +35 -0
  88. data/lib/mb/cookbook_metadata.rb +73 -0
  89. data/lib/mb/core_ext.rb +3 -0
  90. data/lib/mb/core_ext/dir.rb +37 -0
  91. data/lib/mb/core_ext/enumerable.rb +48 -0
  92. data/lib/mb/core_ext/file.rb +24 -0
  93. data/lib/mb/core_ext/signal.rb +11 -0
  94. data/lib/mb/environment_manager.rb +195 -0
  95. data/lib/mb/error_handler.rb +212 -0
  96. data/lib/mb/errors.rb +693 -0
  97. data/lib/mb/file_system.rb +60 -0
  98. data/lib/mb/file_system/tempfile.rb +25 -0
  99. data/lib/mb/gear.rb +154 -0
  100. data/lib/mb/gears.rb +8 -0
  101. data/lib/mb/gears/dynamic_service.rb +218 -0
  102. data/lib/mb/gears/jmx.rb +24 -0
  103. data/lib/mb/gears/jmx/action.rb +46 -0
  104. data/lib/mb/gears/mysql.rb +20 -0
  105. data/lib/mb/gears/mysql/action.rb +190 -0
  106. data/lib/mb/gears/service.rb +163 -0
  107. data/lib/mb/gears/service/action.rb +58 -0
  108. data/lib/mb/gears/service/action_runner.rb +161 -0
  109. data/lib/mb/grape_ext.rb +3 -0
  110. data/lib/mb/grape_ext/endpoint.rb +13 -0
  111. data/lib/mb/group.rb +143 -0
  112. data/lib/mb/job.rb +183 -0
  113. data/lib/mb/job/state_machine.rb +34 -0
  114. data/lib/mb/job/states.rb +46 -0
  115. data/lib/mb/job_manager.rb +96 -0
  116. data/lib/mb/job_record.rb +67 -0
  117. data/lib/mb/job_ticket.rb +25 -0
  118. data/lib/mb/lock_manager.rb +116 -0
  119. data/lib/mb/logging.rb +134 -0
  120. data/lib/mb/logging/basic_format.rb +31 -0
  121. data/lib/mb/manifest.rb +128 -0
  122. data/lib/mb/mixin.rb +3 -0
  123. data/lib/mb/mixin/attribute_setting.rb +265 -0
  124. data/lib/mb/mixin/coded_exit.rb +49 -0
  125. data/lib/mb/mixin/locks.rb +54 -0
  126. data/lib/mb/mixin/services.rb +100 -0
  127. data/lib/mb/node_filter.rb +97 -0
  128. data/lib/mb/node_querier.rb +527 -0
  129. data/lib/mb/plugin.rb +300 -0
  130. data/lib/mb/plugin_manager.rb +589 -0
  131. data/lib/mb/provisioner.rb +186 -0
  132. data/lib/mb/provisioner/manager.rb +213 -0
  133. data/lib/mb/provisioner/manifest.rb +125 -0
  134. data/lib/mb/provisioner/provision_data.rb +96 -0
  135. data/lib/mb/provisioners.rb +5 -0
  136. data/lib/mb/provisioners/aws.rb +395 -0
  137. data/lib/mb/rest_gateway.rb +72 -0
  138. data/lib/mb/ridley_ext.rb +5 -0
  139. data/lib/mb/ridley_ext/cookbook_object.rb +15 -0
  140. data/lib/mb/srv_ctl.rb +183 -0
  141. data/lib/mb/test.rb +104 -0
  142. data/lib/mb/thor_ext.rb +49 -0
  143. data/lib/mb/upgrade.rb +6 -0
  144. data/lib/mb/upgrade/manager.rb +85 -0
  145. data/lib/mb/upgrade/worker.rb +149 -0
  146. data/lib/mb/version.rb +1 -1
  147. data/lib/motherbrain.rb +166 -2
  148. data/man/man_helper.rb +81 -0
  149. data/man/mb.1 +494 -0
  150. data/man/mb.1.html +300 -0
  151. data/man/mb.1.ronn.erb +62 -0
  152. data/motherbrain.gemspec +56 -20
  153. data/scripts/node_name.rb +14 -0
  154. data/spec/fixtures/cb_metadata.json +7 -0
  155. data/spec/fixtures/cb_metadata.rb +14 -0
  156. data/spec/fixtures/fake_id_rsa +27 -0
  157. data/spec/fixtures/fake_key.pem +27 -0
  158. data/spec/fixtures/myface-0.1.0/metadata.rb +14 -0
  159. data/spec/fixtures/myface-0.1.0/motherbrain.rb +0 -0
  160. data/spec/fixtures/test_env.json +15 -0
  161. data/spec/spec_helper.rb +67 -0
  162. data/spec/support/actor_mocking.rb +7 -0
  163. data/spec/support/berkshelf.rb +24 -0
  164. data/spec/support/chef_server.rb +102 -0
  165. data/spec/support/doubles.rb +11 -0
  166. data/spec/support/klass.rb +10 -0
  167. data/spec/support/matchers/each.rb +12 -0
  168. data/spec/support/matchers/error_codes.rb +5 -0
  169. data/spec/support/matchers/exit_codes.rb +57 -0
  170. data/spec/support/matchers/jobs.rb +11 -0
  171. data/spec/support/spec_helpers.rb +145 -0
  172. data/spec/unit/mb/api/application_spec.rb +11 -0
  173. data/spec/unit/mb/api/helpers_spec.rb +5 -0
  174. data/spec/unit/mb/api/v1/config_endpoint_spec.rb +19 -0
  175. data/spec/unit/mb/api/v1/environments_endpoint_spec.rb +71 -0
  176. data/spec/unit/mb/api/v1/jobs_endpoint_spec.rb +24 -0
  177. data/spec/unit/mb/api/v1/plugins_endpoint_spec.rb +298 -0
  178. data/spec/unit/mb/api/v1_spec.rb +37 -0
  179. data/spec/unit/mb/api/validators/sem_ver_spec.rb +5 -0
  180. data/spec/unit/mb/application_spec.rb +19 -0
  181. data/spec/unit/mb/berkshelf_spec.rb +38 -0
  182. data/spec/unit/mb/bootstrap/manager_spec.rb +347 -0
  183. data/spec/unit/mb/bootstrap/manifest_spec.rb +333 -0
  184. data/spec/unit/mb/bootstrap/routine_spec.rb +393 -0
  185. data/spec/unit/mb/bootstrap/template_spec.rb +100 -0
  186. data/spec/unit/mb/bootstrap/worker_spec.rb +194 -0
  187. data/spec/unit/mb/chef/config_spec.rb +33 -0
  188. data/spec/unit/mb/chef/run_list_item_spec.rb +34 -0
  189. data/spec/unit/mb/chef_mutex_spec.rb +314 -0
  190. data/spec/unit/mb/clean_room_base_spec.rb +31 -0
  191. data/spec/unit/mb/cli/base_spec.rb +43 -0
  192. data/spec/unit/mb/cli/shell/basic_spec.rb +5 -0
  193. data/spec/unit/mb/cli/shell/color_spec.rb +5 -0
  194. data/spec/unit/mb/cli/shell/ext_spec.rb +11 -0
  195. data/spec/unit/mb/cli/shell_spec.rb +38 -0
  196. data/spec/unit/mb/cli/sub_command/base_spec.rb +102 -0
  197. data/spec/unit/mb/cli/sub_command/component_spec.rb +5 -0
  198. data/spec/unit/mb/cli/sub_command/plugin_spec.rb +91 -0
  199. data/spec/unit/mb/cli/sub_command_spec.rb +43 -0
  200. data/spec/unit/mb/cli/ui.rb +0 -0
  201. data/spec/unit/mb/cli_client_spec.rb +51 -0
  202. data/spec/unit/mb/cli_gateway_spec.rb +386 -0
  203. data/spec/unit/mb/command_invoker/worker_spec.rb +43 -0
  204. data/spec/unit/mb/command_invoker_spec.rb +230 -0
  205. data/spec/unit/mb/command_runner_spec.rb +299 -0
  206. data/spec/unit/mb/command_spec.rb +76 -0
  207. data/spec/unit/mb/component_spec.rb +185 -0
  208. data/spec/unit/mb/config_manager_spec.rb +31 -0
  209. data/spec/unit/mb/config_spec.rb +408 -0
  210. data/spec/unit/mb/cookbook_metadata_spec.rb +89 -0
  211. data/spec/unit/mb/core_ext/dir_spec.rb +92 -0
  212. data/spec/unit/mb/core_ext/enumerable_spec.rb +104 -0
  213. data/spec/unit/mb/core_ext/file_spec.rb +58 -0
  214. data/spec/unit/mb/core_ext/signal_spec.rb +24 -0
  215. data/spec/unit/mb/environment_manager_spec.rb +166 -0
  216. data/spec/unit/mb/error_handler_spec.rb +173 -0
  217. data/spec/unit/mb/errors_spec.rb +132 -0
  218. data/spec/unit/mb/file_system/tempfile_spec.rb +14 -0
  219. data/spec/unit/mb/file_system_spec.rb +69 -0
  220. data/spec/unit/mb/gear_spec.rb +125 -0
  221. data/spec/unit/mb/gears/dynamic_service_spec.rb +187 -0
  222. data/spec/unit/mb/gears/jmx/action_spec.rb +34 -0
  223. data/spec/unit/mb/gears/jmx_spec.rb +32 -0
  224. data/spec/unit/mb/gears/mysql/action_spec.rb +118 -0
  225. data/spec/unit/mb/gears/mysql_spec.rb +21 -0
  226. data/spec/unit/mb/gears/service/action_runner_spec.rb +182 -0
  227. data/spec/unit/mb/gears/service/action_spec.rb +44 -0
  228. data/spec/unit/mb/gears/service_spec.rb +124 -0
  229. data/spec/unit/mb/group_spec.rb +280 -0
  230. data/spec/unit/mb/job_manager_spec.rb +56 -0
  231. data/spec/unit/mb/job_record_spec.rb +60 -0
  232. data/spec/unit/mb/job_spec.rb +201 -0
  233. data/spec/unit/mb/locks_manager_spec.rb +88 -0
  234. data/spec/unit/mb/logging_spec.rb +133 -0
  235. data/spec/unit/mb/manifest_spec.rb +105 -0
  236. data/spec/unit/mb/mixin/attribute_setting_spec.rb +180 -0
  237. data/spec/unit/mb/mixin/coded_exit_spec.rb +25 -0
  238. data/spec/unit/mb/mixin/locks_spec.rb +32 -0
  239. data/spec/unit/mb/mixin/services_spec.rb +75 -0
  240. data/spec/unit/mb/node_filter_spec.rb +86 -0
  241. data/spec/unit/mb/node_querier_spec.rb +532 -0
  242. data/spec/unit/mb/plugin_manager_spec.rb +724 -0
  243. data/spec/unit/mb/plugin_spec.rb +247 -0
  244. data/spec/unit/mb/provisioner/manager_spec.rb +141 -0
  245. data/spec/unit/mb/provisioner/manifest_spec.rb +182 -0
  246. data/spec/unit/mb/provisioner/provision_data_spec.rb +113 -0
  247. data/spec/unit/mb/provisioner_spec.rb +251 -0
  248. data/spec/unit/mb/provisioners/aws_spec.rb +392 -0
  249. data/spec/unit/mb/provisioners/environment_factory_spec.rb +108 -0
  250. data/spec/unit/mb/rest_gateway_spec.rb +13 -0
  251. data/spec/unit/mb/ridley_ext/cookbook_object_spec.rb +105 -0
  252. data/spec/unit/mb/srv_ctl_spec.rb +142 -0
  253. data/spec/unit/mb/upgrade/manager_spec.rb +37 -0
  254. data/spec/unit/mb/upgrade/worker_spec.rb +219 -0
  255. data/spec/unit/motherbrain_spec.rb +58 -0
  256. data/templates/bootstrap.json +8 -0
  257. data/templates/motherbrain.rb +44 -0
  258. metadata +694 -15
  259. data/Rakefile +0 -1
data/README.md CHANGED
@@ -1,29 +1,317 @@
1
- # Motherbrain
1
+ # motherbrain
2
2
 
3
- TODO: Write a gem description
3
+ motherbrain is an orchestration framework for Chef. In the same way that you
4
+ would use Chef's Knife command to create a single node, you can use
5
+ motherbrain to create and control an entire application environment.
6
+
7
+ ## Other Documentation
8
+
9
+ * [Plugin DSL](PLUGINS.md)
10
+ * [Manifest file format](MANIFESTS.md)
11
+ * [Testing with Vagrant](VAGRANT.md)
12
+ * [Command structure](COMMANDS.md)
13
+
14
+ ## Requirements
15
+
16
+ * Ruby 1.9.3+
17
+ * Chef Server 10 or 11, or Hosted Chef
4
18
 
5
19
  ## Installation
6
20
 
7
- Add this line to your application's Gemfile:
21
+ Install motherbrain via RubyGems:
22
+
23
+ ```sh
24
+ gem install motherbrain
25
+ ```
26
+
27
+ We don't recommend including motherbrain in your Gemfile.
28
+
29
+
30
+ Before using motherbrain, you'll need to create a configuration file with `mb
31
+ configure`:
32
+
33
+ ```
34
+ Enter a Chef API URL:
35
+ Enter a Chef API Client:
36
+ Enter the path to the client's Chef API Key:
37
+ Enter a SSH user:
38
+ Enter a SSH password:
39
+ Config written to: '~/.mb/config.json'
40
+ ```
41
+
42
+ You can verify that motherbrain is installed correctly and pointing to a Chef
43
+ server by running `mb plugin list --remote`:
44
+
45
+ ```
46
+ $ mb plugin list --remote
47
+
48
+ ** listing installed and remote plugins...
49
+
50
+ ```
51
+
52
+ ## Getting Started
53
+
54
+ motherbrain comes with an `init` command to help you get started quickly. Let's
55
+ pretend we have an app called MyFace, our hot new social network. We'll
56
+ be using the myface cookbook for this tutorial:
57
+
58
+ ```
59
+ $ git clone https://github.com/reset/myface-cookbook
60
+ $ cd myface
61
+ myface$
62
+ ```
63
+
64
+ We'll generate a new plugin for the cookbook we're developing:
65
+
66
+ ```
67
+ myface$ mb plugin init
68
+ create bootstrap.json
69
+ create motherbrain.rb
70
+
71
+ motherbrain plugin created.
72
+
73
+ Take a look at motherbrain.rb and bootstrap.json,
74
+ and then bootstrap with:
75
+
76
+ mb myface bootstrap bootstrap.json
77
+
78
+ To see all available commands, run:
79
+
80
+ mb myface help
81
+
82
+ myface$
83
+ ```
84
+
85
+ That command created a plugin for us, as well as told us about some commands we
86
+ can run. Plugins live within cookbooks in a file named `motherbrain.rb`. Notice
87
+ that each command starts with the name of our plugin. Once we're done
88
+ developing our plugin and we upload it to our Chef server, we can run plugins
89
+ from any cookbook on our Chef server.
90
+
91
+ Lets take a look at all of the commands we can run on a plugin:
92
+
93
+ ```
94
+ myface$ mb myface
95
+ using myface (1.1.8)
96
+
97
+ Tasks:
98
+ mb myface app [COMMAND] # Myface application
99
+ mb myface bootstrap MANIFEST # Bootstrap a manifest of node groups
100
+ mb myface help [COMMAND] # Describe subcommands or one specific subcommand
101
+ mb myface nodes # List all nodes grouped by Component and Group
102
+ mb myface provision MANIFEST # Create a cluster of nodes and add them to a Chef environment
103
+ mb myface upgrade # Upgrade an environment to the specified versions
104
+ ```
105
+
106
+ There are a few things plugins can do:
107
+
108
+ * Bootstrap existing nodes and configure an environment
109
+ * Provision nodes from a compute provider, such as Amazon EC2, Vagrant, or
110
+ Eucalyptus
111
+ * List all nodes in an environment, and what they're used for
112
+ * Configure/upgrade an environment with cookbook versions, environment
113
+ attributes, and then run Chef on all affected nodes
114
+ * Run plugin commands, which abstract setting environment attributes and
115
+ running Chef on the nodes
116
+
117
+ Notice that there's one task in the help output called `app` which doesn't map
118
+ to any of those bulletpoints. Let's take a look at the plugin our `init`
119
+ command created:
120
+
121
+ ```rb
122
+ stack_order do
123
+ bootstrap 'app::default'
124
+ end
125
+
126
+ component 'app' do
127
+ description "Myface application"
128
+ versioned
129
+
130
+ group 'default' do
131
+ recipe 'myface::default'
132
+ end
133
+ end
134
+ ```
135
+
136
+ A plugin consists of a few things:
137
+
138
+ * `stack_order` declares the order to bootstrap component groups
139
+ * `component` creates a namespace for different parts of your application
140
+ * `description` provides a friendly summary of the component
141
+ * `versioned` denotes that this component is versioned with an environment
142
+ attribute
143
+ * `group` declares a group of nodes
144
+ * `recipe` defines how we identify nodes in this group
145
+
146
+ This plugin is enough to get our app running on a single node. Let's try it out.
147
+ Edit `bootstrap.json` and fill in a hostname to bootstrap:
148
+
149
+ ```json
150
+ {
151
+ "nodes": [
152
+ {
153
+ "groups": ["app::default"],
154
+ "hosts": ["box1"]
155
+ }
156
+ ]
157
+ }
158
+ ```
159
+
160
+ And then we'll bootstrap our plugin to that node:
161
+
162
+ ```
163
+ myface-cookbook$ knife environment create motherbrain_tutorial
164
+ myface-cookbook$ mb myface bootstrap bootstrap.json -e motherbrain_tutorial
165
+
166
+ using myface (0.4.1)
167
+
168
+ [bootstrap] searching for environment
169
+ [bootstrap] Locking chef_environment:motherbrain_tutorial
170
+ [bootstrap] performing bootstrap on group(s): ["app::default"]
171
+ [bootstrap] Unlocking chef_environment:motherbrain_tutorial
172
+ [bootstrap] Success
173
+ ```
174
+
175
+ That's it! But that's not much different from using `knife bootstrap`, and it
176
+ took a lot more work.
177
+
178
+ ```
179
+ myface-cookbook$ ls recipes/
180
+ database.rb default.rb webserver.rb
181
+ myface-cookbook$ cat recipes/default.rb
182
+ include_recipe "myface::webserver"
183
+ include_recipe "myface::database"
184
+ ```
185
+
186
+ We're currently using the `default` recipe in our plugin, which ends up adding
187
+ both the `webserver` and `database` recipes to our node's runlist. Let's change
188
+ the automatically-generated plugin to better fit the architecture for our
189
+ application:
190
+
191
+ ```rb
192
+ stack_order do
193
+ bootstrap 'app::db'
194
+ bootstrap 'app::web'
195
+ end
196
+
197
+ component 'app' do
198
+ description "Myface application"
199
+ versioned
200
+
201
+ group 'web' do
202
+ recipe 'myface::webserver'
203
+ end
204
+
205
+ group 'db' do
206
+ recipe 'myface::database'
207
+ end
208
+ end
209
+ ```
210
+
211
+ Note that we're bootstrapping the nodes in order, and since our web server
212
+ depends on a database, we'll want to bootstrap the database first.
213
+
214
+ And then change our bootstrap manifest to bootstrap 2 nodes instead of 1:
215
+
216
+ ```json
217
+ {
218
+ "nodes": [
219
+ {
220
+ "groups": ["app::web"],
221
+ "hosts": ["box1"]
222
+ },
223
+ {
224
+ "groups": ["app::db"],
225
+ "hosts": ["box2"]
226
+ }
227
+ ]
228
+ }
229
+ ```
230
+
231
+ And then run the bootstrap again:
232
+
233
+ ```
234
+ myface-cookbook$ mb myface bootstrap bootstrap.json -e motherbrain_tutorial
235
+
236
+ using myface (0.4.1)
237
+
238
+ [bootstrap] searching for environment
239
+ [bootstrap] Locking chef_environment:motherbrain_tutorial
240
+ [bootstrap] performing bootstrap on group(s): ["app::db"]
241
+ [bootstrap] performing bootstrap on group(s): ["app::web"]
242
+ [bootstrap] Unlocking chef_environment:motherbrain_tutorial
243
+ [bootstrap] Success
244
+ ```
245
+
246
+ That's it! We now have our application deployed to 2 nodes.
247
+
248
+ # Service Commands
249
+
250
+ If your cookbook is written using the "service orchestration" pattern,
251
+ motherbrain can make your plugin even simpler.
252
+
253
+ ```
254
+ component "app" do
255
+ description "Myface Application"
256
+ versioned
257
+
258
+ service "app" do
259
+ service\_group "app"
260
+ service\_recipe "myface::service"
261
+ service\_attribute "myface.app.state"
262
+ end
263
+
264
+ group "app" do
265
+ recipe "myface::app"
266
+ end
267
+ end
268
+ ```
269
+
270
+ To start the service, you would run `mb myface service app.app start`.
271
+ This would set the `myface.app.state` attribute to 'start' and then do
272
+ a partial chef run on all nodes that have "myface::app" in their
273
+ default runlist, using an override runlist of "myface::app_service".
274
+ The same command could be used to stop, restart, or change to any
275
+ other state that your service recipe supports.
276
+
277
+ For each service resource in your cookbook, you should use a single
278
+ attribute to define the desired state (stopped, started, restarted).
279
+ The default that motherbrain will look for is
280
+ `component_name.service_name.state` (although you can use anything you
281
+ like).
282
+
283
+ This resource should also be in a dedicated recipe that only works
284
+ with your services.
285
+
286
+
287
+ # Swagger
288
+
289
+ When running as a server, MB mounts various enpoinds using the Grape library. For convenience, the tool Swagger has
290
+ also been integrated into MB's REST API.
8
291
 
9
- gem 'motherbrain'
292
+ First, clone the Swagger UI project from here https://github.com/wordnik/swagger-ui.
10
293
 
11
- And then execute:
294
+ Next, start your MB server. The only requirement here is a properly defined configuration file:
12
295
 
13
- $ bundle
296
+ `bundle exec bin/mbsrv`
14
297
 
15
- Or install it yourself as:
298
+ Next, open up the index.html in the dist/ directory of your cloned swagger-ui. In the top menu bar, paste
299
+ in your MB server's address (and port) plus swagger_doc.json and click Explore.
16
300
 
17
- $ gem install motherbrain
301
+ For a local server, running on the default port, the URL would look like "http://localhost:26100/swagger_doc.json".
18
302
 
19
- ## Usage
303
+ Thats all! You should now be able to explore the REST API of MB using Swagger.
20
304
 
21
- TODO: Write usage instructions here
305
+ # Authors
22
306
 
23
- ## Contributing
307
+ * Jamie Winsor (<jamie@vialstudios.com>)
308
+ * Jesse Howarth (<jhowarth@riotgames.com>)
309
+ * Justin Campbell (<justin@justincampbell.me>)
310
+ * Michael Ivey (<michael.ivey@riotgames.com>)
311
+ * Cliff Dickerson (<cdickerson@riotgames.com>)
312
+ * Andrew Garson (<agarson@riotgames.com>)
313
+ * Kyle Allan (<kallan@riotgames.com>)
314
+ * Josiah Kiehl (<jkiehl@riotgames.com>)
315
+ * Steve Rude (<srude@riotgames.com>)
24
316
 
25
- 1. Fork it
26
- 2. Create your feature branch (`git checkout -b my-new-feature`)
27
- 3. Commit your changes (`git commit -am 'Add some feature'`)
28
- 4. Push to the branch (`git push origin my-new-feature`)
29
- 5. Create new Pull Request
317
+ If you'd like to contribute, please see our [contribution guidelines](https://github.com/RiotGames/motherbrain/blob/master/CONTRIBUTING.md) first.
data/Thorfile ADDED
@@ -0,0 +1,123 @@
1
+ # encoding: utf-8
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+
4
+ require 'bundler'
5
+ require 'bundler/setup'
6
+ require 'thor/rake_compat'
7
+
8
+ require 'motherbrain'
9
+ MB::Logging.setup(location: '/dev/null')
10
+
11
+ class Default < Thor
12
+ include Thor::Actions
13
+ include Thor::RakeCompat
14
+ Bundler::GemHelper.install_tasks
15
+
16
+ desc "build", "Build motherbrain-#{MotherBrain::VERSION}.gem into the pkg directory"
17
+ def build
18
+ Rake::Task["build"].execute
19
+ end
20
+
21
+ desc "install", "Build and install motherbrain-#{MotherBrain::VERSION}.gem into system gems"
22
+ def install
23
+ Rake::Task["install"].execute
24
+ end
25
+
26
+ desc "release", "Create tag v#{MotherBrain::VERSION} and build and push motherbrain-#{MotherBrain::VERSION}.gem to gem in a box"
27
+ def release
28
+ Rake::Task["release"].execute
29
+ end
30
+
31
+ desc "ci", "Run all tests"
32
+ def ci
33
+ ENV['CI'] = 'true' # Travis-CI also sets this, but set it here for local testing
34
+ run "rspec --tag ~focus --color --format=progress spec"
35
+ exit $?.exitstatus unless $?.success?
36
+ run "cucumber --format progress"
37
+ exit $?.exitstatus unless $?.success?
38
+ end
39
+
40
+ desc "routes", "Print all registered REST API routes"
41
+ def routes
42
+ puts MB::API::Application.routes
43
+ end
44
+
45
+ desc "manpage", "Re-generate the man pages"
46
+ def manpage
47
+ require MB.app_root.join('man', 'man_helper')
48
+ say "Generating man page ronn source"
49
+ MB::ManHelper.generate('man/mb.1.ronn.erb', 'man/mb.1.ronn')
50
+ run "ronn man/mb.1.ronn"
51
+ end
52
+
53
+ class Cucumber < Thor
54
+ namespace :cucumber
55
+ default_task :all
56
+
57
+ desc "all", "run all tests"
58
+ def all
59
+ exec "cucumber --require features --tags ~@wip"
60
+ end
61
+ end
62
+
63
+ class Spec < Thor
64
+ namespace :spec
65
+ default_task :all
66
+
67
+ desc "all", "run all tests"
68
+ def all
69
+ exec "rspec --color --format=documentation spec"
70
+ end
71
+
72
+ desc "unit", "run only unit tests"
73
+ def unit
74
+ exec "rspec --color --format=documentation spec --tag ~type:acceptance"
75
+ end
76
+
77
+ desc "acceptance", "run only acceptance tests"
78
+ def acceptance
79
+ exec "rspec --color --format=documentation spec --tag type:acceptance"
80
+ end
81
+ end
82
+
83
+ private
84
+
85
+ def clean?
86
+ sh_with_excode("git diff --exit-code")[1] == 0
87
+ end
88
+
89
+ def tag_version
90
+ sh "git tag -a -m \"Version #{MotherBrain::VERSION}\" #{MotherBrain::VERSION}"
91
+ say "Tagged: #{MotherBrain::VERSION}", :green
92
+ yield if block_given?
93
+ sh "git push --tags"
94
+ rescue => e
95
+ say "Untagging: #{MotherBrain::VERSION} due to error", :red
96
+ sh_with_excode "git tag -d #{MotherBrain::VERSION}"
97
+ say e, :red
98
+ exit 1
99
+ end
100
+
101
+ def source_root
102
+ Pathname.new File.dirname(File.expand_path(__FILE__))
103
+ end
104
+
105
+ def sh(cmd, dir = source_root, &block)
106
+ out, code = sh_with_excode(cmd, dir, &block)
107
+ code == 0 ? out : raise(out.empty? ? "Running `#{cmd}` failed. Run this command directly for more detailed output." : out)
108
+ end
109
+
110
+ def sh_with_excode(cmd, dir = source_root, &block)
111
+ cmd << " 2>&1"
112
+ outbuf = ''
113
+
114
+ Dir.chdir(dir) {
115
+ outbuf = `#{cmd}`
116
+ if $? == 0
117
+ block.call(outbuf) if block
118
+ end
119
+ }
120
+
121
+ [ outbuf, $? ]
122
+ end
123
+ end