ruby_yacht 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +3 -1
  3. data/.rdoc_options +8 -2
  4. data/.rspec +1 -0
  5. data/.travis.yml +17 -1
  6. data/Gemfile.lock +18 -2
  7. data/README.md +28 -10
  8. data/bin/ruby_yacht +5 -0
  9. data/doc/TODO.md +1 -20
  10. data/doc/configuration.md +104 -21
  11. data/doc/configuration_sample.rb +19 -8
  12. data/doc/contributing.md +28 -5
  13. data/doc/plugins.md +105 -45
  14. data/lib/ruby_yacht/dsl/app.rb +14 -18
  15. data/lib/ruby_yacht/dsl/configuration.rb +51 -32
  16. data/lib/ruby_yacht/dsl/database.rb +24 -8
  17. data/lib/ruby_yacht/dsl/dsl.rb +32 -4
  18. data/lib/ruby_yacht/dsl/hook.rb +182 -48
  19. data/lib/ruby_yacht/dsl/project.rb +20 -14
  20. data/lib/ruby_yacht/dsl/server_type.rb +14 -31
  21. data/lib/ruby_yacht/dsl/web_server.rb +87 -0
  22. data/lib/ruby_yacht/dsl.rb +1 -0
  23. data/lib/ruby_yacht/images/app/Dockerfile.erb +17 -6
  24. data/lib/ruby_yacht/images/app/before_startup.bash.erb +5 -3
  25. data/lib/ruby_yacht/images/app/startup.bash.erb +5 -2
  26. data/lib/ruby_yacht/images/app-dependencies/Dockerfile.erb +7 -11
  27. data/lib/ruby_yacht/images/database/Dockerfile.erb +7 -18
  28. data/lib/ruby_yacht/images/database/startup.bash.erb +1 -1
  29. data/lib/ruby_yacht/images/web/Dockerfile.erb +25 -19
  30. data/lib/ruby_yacht/plugins/mysql.rb +18 -8
  31. data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/add_app.rb +5 -5
  32. data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/add_project.rb +3 -3
  33. data/lib/ruby_yacht/plugins/nginx.rb +28 -0
  34. data/lib/ruby_yacht/plugins/rails/scripts/build_new_app.rb +10 -0
  35. data/lib/ruby_yacht/plugins/rails/scripts/update_rails_config.rb +6 -1
  36. data/lib/ruby_yacht/plugins/rails.rb +34 -19
  37. data/lib/ruby_yacht/plugins.rb +2 -1
  38. data/lib/ruby_yacht/runner/build_images.rb +87 -73
  39. data/lib/ruby_yacht/runner/checkout.rb +1 -1
  40. data/lib/ruby_yacht/runner/command.rb +13 -1
  41. data/lib/ruby_yacht/runner/create_new_project.rb +91 -0
  42. data/lib/ruby_yacht/runner/help.rb +1 -1
  43. data/lib/ruby_yacht/runner/run_containers.rb +17 -21
  44. data/lib/ruby_yacht/runner/runner.rb +27 -2
  45. data/lib/ruby_yacht/runner/services.rb +15 -10
  46. data/lib/ruby_yacht/runner/shell.rb +1 -1
  47. data/lib/ruby_yacht/runner/update_hosts.rb +16 -11
  48. data/lib/ruby_yacht/runner.rb +1 -0
  49. data/log/.gitkeep +0 -0
  50. data/ruby_yacht.gemspec +4 -2
  51. data/spec/docker/Dockerfile +19 -3
  52. data/spec/docker/install_gems.bash +5 -0
  53. data/spec/docker/run.bash +44 -0
  54. data/spec/docker/startup.bash +10 -0
  55. data/spec/dsl/app_spec.rb +66 -38
  56. data/spec/dsl/configuration_spec.rb +236 -30
  57. data/spec/dsl/database_spec.rb +103 -4
  58. data/spec/dsl/dsl_spec.rb +46 -3
  59. data/spec/dsl/hook_spec.rb +278 -57
  60. data/spec/dsl/project_spec.rb +75 -45
  61. data/spec/dsl/server_type_spec.rb +52 -12
  62. data/spec/dsl/web_server_spec.rb +160 -0
  63. data/spec/fixtures/apollo-new-project-config +20 -0
  64. data/spec/fixtures/app-dependencies-dockerfile-generic +4 -7
  65. data/spec/fixtures/app-dependencies-dockerfile-generic-with-library-install +6 -10
  66. data/spec/fixtures/app-dependencies-dockerfile-rails +9 -11
  67. data/spec/fixtures/app-dependencies-dockerfile-with-no-repository +20 -0
  68. data/spec/fixtures/database-dockerfile +1 -1
  69. data/spec/fixtures/database-dockerfile-mysql +3 -3
  70. data/spec/fixtures/database-dockerfile-rails +5 -4
  71. data/spec/fixtures/database-dockerfile-rails-with-no-repository +27 -0
  72. data/spec/fixtures/database-dockerfile-with-seed-hooks +3 -3
  73. data/spec/fixtures/database-startup-mysql +2 -1
  74. data/spec/fixtures/mars-before-startup +2 -2
  75. data/spec/fixtures/mars-before-startup-rails +5 -4
  76. data/spec/fixtures/mars-before-startup-with-before-startup-hooks +5 -4
  77. data/spec/fixtures/mars-before-startup-with-custom-file-copy +3 -3
  78. data/spec/fixtures/mars-before-startup-with-no-repository +3 -0
  79. data/spec/fixtures/mars-dockerfile +3 -2
  80. data/spec/fixtures/mars-dockerfile-rails +6 -5
  81. data/spec/fixtures/mars-dockerfile-rails-with-no-repository +32 -0
  82. data/spec/fixtures/mars-dockerfile-with-after-checkout-hooks +5 -4
  83. data/spec/fixtures/mars-dockerfile-with-before-startup-hooks +5 -4
  84. data/spec/fixtures/mars-dockerfile-with-custom-file-copy +4 -3
  85. data/spec/fixtures/mars-dockerfile-with-local-database +4 -2
  86. data/spec/fixtures/mars-dockerfile-with-no-repository +22 -0
  87. data/spec/fixtures/mars-dockerfile-with-remote-database +4 -2
  88. data/spec/fixtures/mars-startup +2 -2
  89. data/spec/fixtures/mars-startup-rails +2 -2
  90. data/spec/fixtures/mars-startup-rails-with-no-repository +5 -0
  91. data/spec/fixtures/mars-startup-with-no-repository +4 -0
  92. data/spec/fixtures/web-dockerfile +18 -11
  93. data/spec/fixtures/web-dockerfile-jupiter +28 -0
  94. data/spec/fixtures/web-dockerfile-nginx +38 -0
  95. data/spec/fixtures/web-dockerfile-with-eponymous-app +16 -10
  96. data/spec/fixtures/web-dockerfile-with-primary-app +16 -10
  97. data/spec/integration/build_images_spec.rb +210 -0
  98. data/spec/integration/build_spec.rb +23 -0
  99. data/spec/integration/checkout_spec.rb +94 -0
  100. data/spec/integration/create_new_project_spec.rb +50 -0
  101. data/spec/integration/implode_spec.rb +20 -0
  102. data/spec/integration/run.rb +93 -0
  103. data/spec/integration/run_containers_spec.rb +279 -0
  104. data/spec/integration/services_spec.rb +99 -0
  105. data/spec/integration/shell_spec.rb +31 -0
  106. data/spec/integration/update_hosts_spec.rb +35 -0
  107. data/spec/plugins/mysql_spec.rb +18 -1
  108. data/spec/plugins/nginx_spec.rb +66 -0
  109. data/spec/plugins/rails_spec.rb +61 -89
  110. data/spec/runner/build_images_spec.rb +111 -58
  111. data/spec/runner/command_spec.rb +55 -3
  112. data/spec/runner/create_new_project_spec.rb +93 -0
  113. data/spec/runner/help_spec.rb +5 -1
  114. data/spec/runner/run_containers_spec.rb +22 -10
  115. data/spec/runner/runner_spec.rb +31 -4
  116. data/spec/runner/services_spec.rb +32 -4
  117. data/spec/runner/update_hosts_spec.rb +2 -1
  118. data/spec/spec_helper.rb +16 -1
  119. data/spec/support/integration_helpers.rb +76 -0
  120. data/spec/support/test_project.rb +15 -3
  121. metadata +97 -14
  122. data/spec/docker/build.bash +0 -10
  123. data/spec/fixtures/deploy-dockerfile +0 -2
  124. data/spec/fixtures/multi-project-web-dockerfile +0 -25
  125. /data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/app_config.erb +0 -0
  126. /data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/index.html.erb +0 -0
  127. /data/lib/ruby_yacht/{images/web → plugins/nginx/scripts}/index_config.erb +0 -0
data/doc/plugins.md CHANGED
@@ -29,8 +29,8 @@ You can add the following fields to fill out the server type:
29
29
  <tr>
30
30
  <td>container_type</td>
31
31
  <td>
32
- The type of container that this server type applies to. This can be either
33
- `app` or `database`.
32
+ The type of container that this server type applies to. This can be `app`,
33
+ `database`, or `web`.
34
34
  </td>
35
35
  <td>
36
36
  <code>container_type :app</code>
@@ -45,7 +45,8 @@ You can add the following fields to fill out the server type:
45
45
  these servers.
46
46
  </p>
47
47
  <p>
48
- This is currently only used for the app images.
48
+ This is currently ignored for database images, since those are built off
49
+ of the app dependencies image.
49
50
  </p>
50
51
  </td>
51
52
  <td>
@@ -91,34 +92,23 @@ You can add the following fields to fill out the server type:
91
92
  <td>None; no custom server attributes</td>
92
93
  </tr>
93
94
  <tr>
94
- <td>environment_variable</td>
95
- <td>
96
- <p>
97
- A custom environment variable that is set in an image for this plugin.
98
- </p>
99
- <p>
100
- This accepts two parameters (image and name), as well as a block. The
101
- image is the type of image this is set on: app, app_dependencies, or
102
- database. The block provides a value for the variable. The block will
103
- have access to the context of the image we're building, as
104
- <code>@project</code>, <code>@app</code>, and <code>@database</code>.
105
- </p>
106
- <p>
107
- An app type plugin can also provide custom environment variable for a
108
- database server.
109
- </p>
110
- <p>
111
- You can call this multiple times to define multiple environment variables.
112
- </p>
113
- </td>
114
- <td>
115
- <code>
116
- environment_variable :app_dependencies, 'RAILS_ENV' do
117
- @project.rails_environment
118
- end
119
- </code>
120
- </td>
121
- <td>None; no custom environment variables.</td>
95
+ <td>server_default</td>
96
+ <td>
97
+ <p>
98
+ This defines a default value for an existing attribute on servers of
99
+ this type.
100
+ </p>
101
+ <p>
102
+ This accepts hash of options. The keys in this hash are the names of the
103
+ attributes, and the values are the default values.
104
+ </p>
105
+ <p>
106
+ You can call this multiple times, and it will add the new defaults to
107
+ the list.
108
+ </p>
109
+ </td>
110
+ <td><code>server_default port: 3000</code></td>
111
+ <td>None; no custom default values.</td>
122
112
  </tr>
123
113
  </table>
124
114
 
@@ -151,9 +141,22 @@ These are the event types that you can hook into:
151
141
  The code for an app is being checked out when building an app image.
152
142
  </td>
153
143
  </tr>
144
+ <tr>
145
+ <td>build_new_app</td>
146
+ <td>
147
+ An app is being created from scratch rather than checked out from a
148
+ repository.
149
+ </td>
150
+ </tr>
154
151
  <tr>
155
152
  <td>install_libraries</td>
156
- <td>The libraries for an app or database server are being installed.</td>
153
+ <td>The libraries for a server are being installed.</td>
154
+ </tr>
155
+ <tr>
156
+ <td>initialize_app_environment</td>
157
+ <td>
158
+ The envrionment variables for the app-dependencies image are being set.
159
+ </td>
157
160
  </tr>
158
161
  <tr>
159
162
  <td>create_databases</td>
@@ -163,6 +166,17 @@ These are the event types that you can hook into:
163
166
  <td>load_database_seeds</td>
164
167
  <td>The seed data for the app is being loaded on the database server.</td>
165
168
  </tr>
169
+ <tr>
170
+ <td>add_project_landing</td>
171
+ <td>
172
+ We are adding the configuration for a project's landing page to a web
173
+ server.
174
+ </td>
175
+ </tr>
176
+ <tr>
177
+ <td>add_app_config</td>
178
+ <td>We are adding the configuration for a single app to a web server.</td>
179
+ </tr>
166
180
  </table>
167
181
 
168
182
  ### Fields
@@ -177,20 +191,29 @@ The hook DSL allows you to set the following fields:
177
191
  <th>Default</th>
178
192
  </tr>
179
193
  <tr>
180
- <td>server_type</td>
181
- <td>The name of the server type that this hook applies to</td>
182
- <td><code>server_type :rails</code></td>
194
+ <td>container_type</td>
195
+ <td>The name of the container type that this hook applies to</td>
196
+ <td><code>container_type :app</code></td>
183
197
  <td>None; this is required</td>
184
198
  </tr>
185
199
  <tr>
186
- <td>command</td>
187
- <td>The shell command that should be run when the hook executes</td>
188
- <td><code>command 'cp /var/docker/database.yml /var/code/config/'</code></td>
189
- <td>
190
- None; this is required. However, it can also be set by calling
191
- `run_script`.
192
- </td>
200
+ <td>app_server_type</td>
201
+ <td>The name of the app server type that this hook applies to</td>
202
+ <td><code>app_server_type :rails</code></td>
203
+ <td>all, meaning all app server types</td>
193
204
  </tr>
205
+ <tr>
206
+ <td>database_server_type</td>
207
+ <td>The name of the database server type that this hook applies to</td>
208
+ <td><code>database_server_type :mysql</code></td>
209
+ <td>all, meaning all database server types</td>
210
+ </tr
211
+ <tr>
212
+ <td>web_server_type</td>
213
+ <td>The name of the web server type that this hook applies to</td>
214
+ <td><code>web_server_type :nginx</code></td>
215
+ <td>all, meaning all web server types</td>
216
+ </tr
194
217
  <tr>
195
218
  <td>script_folder</td>
196
219
  <td>
@@ -200,6 +223,30 @@ The hook DSL allows you to set the following fields:
200
223
  <td><code>script_folder './scripts'</code></td>
201
224
  <td>The working directory</td>
202
225
  </tr>
226
+ </table>
227
+
228
+ You can constrain a hook by multiple types of servers at once.. For instance,
229
+ you can set the app_server_type to :rails and the database_server_type to :mysql
230
+ to specify that the hook only applies to Rails apps backed by a MySQL database.
231
+ By default, hooks apply to all server types. You also have to specify the
232
+ container_type to say whether the hook is triggered by events on app images,
233
+ database images, or web server images. For instance,
234
+ both app images and database images have a `startup` event, and they'll need
235
+ different behaviors defined.
236
+
237
+ You can define the behaviors for the hooks with these methods:
238
+
239
+ <table>
240
+ <tr>
241
+ <th>Method Name</th>
242
+ <th>Description</th>
243
+ <th>Example</th>
244
+ </tr>
245
+ <tr>
246
+ <td>command</td>
247
+ <td>The shell command that should be run when the hook executes</td>
248
+ <td><code>command 'cp /var/docker/database.yml /var/code/config/'</code></td>
249
+ </tr>
203
250
  <tr>
204
251
  <td>copy_file</td>
205
252
  <td>
@@ -207,7 +254,6 @@ The hook DSL allows you to set the following fields:
207
254
  image. This is relative to the hook's script folder.
208
255
  </td>
209
256
  <td><code>copy_file 'setup.rb'</code></td>
210
- <td>None, meaning that no files are copied for this hook.</td>
211
257
  </tr>
212
258
  <tr>
213
259
  <td>run_script</td>
@@ -216,7 +262,20 @@ The hook DSL allows you to set the following fields:
216
262
  will set the `copy_file` and the `command`.
217
263
  </td>
218
264
  <td><code>run_script 'setup.rb'</code></td>
219
- <td>None; if you are not using this you must call `command` instead.</td>
265
+ </tr>
266
+ <tr>
267
+ <td>set_environment_variable</td>
268
+ <td>
269
+ This sets an environment variable in the image. The value can be set in
270
+ either a block or a literal value passed as the second parameter.
271
+ </td>
272
+ <td>
273
+ <code>
274
+ set_environment_variable 'RAILS_ENV' do
275
+ @project.rails_environment
276
+ end
277
+ </code>
278
+ </td>
220
279
  </tr>
221
280
  </table>
222
281
 
@@ -227,4 +286,5 @@ settings, so you can set defaults for them by calling `add_hooks`. This method
227
286
  takes a hash containing options for the hooks, and a block for adding them. Any
228
287
  hooks added in the block will have those options set.
229
288
 
230
- The supported options are `script_folder` and `server_type`.
289
+ The supported options are `script_folder`, `app_server_type`,
290
+ `database_server_type`, `web_server_type`, and `container_type`.
@@ -22,13 +22,15 @@ module RubyYacht
22
22
  # The name of the database that this app uses as its data store.
23
23
  attr_accessor :database_name
24
24
 
25
+ # The project that includes this app.
26
+ def project
27
+ RubyYacht.configuration.projects.find { |project| project.apps.include?(self) }
28
+ end
29
+
25
30
  # This method gets the name of the image / container that this app will run
26
31
  # in.
27
- #
28
- # ### Parameters
29
- #
30
- # * *project: RubyYacht::Project* The project the app is running in.
31
- def container_name(project)
32
+ def container_name
33
+ project = self.project
32
34
  if project.system_prefix == self.name
33
35
  return "#{project.system_prefix}"
34
36
  else
@@ -38,13 +40,9 @@ module RubyYacht
38
40
 
39
41
  # This method gets the database that the app connects to.
40
42
  #
41
- # ### Parameters
42
- #
43
- # * *project: RubyYacht::Project* The project the app is running in.
44
- #
45
43
  # ### Returns
46
44
  # RubyYacht::Database
47
- def database(project)
45
+ def database
48
46
  project.databases.find { |database| database.name == database_name }
49
47
  end
50
48
 
@@ -61,10 +59,11 @@ module RubyYacht
61
59
  #
62
60
  # ### Parameters
63
61
  #
64
- # * *name: String* The name of the app.
65
- def initialize(name, server_type = nil)
66
- @name = name.to_sym
62
+ # * **server_type: Symbol** The type of server this is.
63
+ # * **name: String** The name of the app.
64
+ def initialize(server_type, name)
67
65
  @server_type = server_type
66
+ @name = name.to_sym
68
67
  load_custom_attributes
69
68
  end
70
69
 
@@ -73,7 +72,7 @@ module RubyYacht
73
72
  ##
74
73
  # :method: repository_name
75
74
  # You can call `repository_name 'foo/bar'` to set the app's `repository_name`.
76
- add_attribute :repository_name
75
+ add_attribute :repository_name, nil, false
77
76
 
78
77
  ##
79
78
  # :method: database_name
@@ -102,10 +101,7 @@ module RubyYacht
102
101
  # configuration.
103
102
  def check_required_attributes
104
103
  super
105
- server_type = RubyYacht.configuration.find_server_type(@server_type)
106
- unless server_type && server_type.container_type == :app
107
- raise "App has invalid server type `#{@server_type}`"
108
- end
104
+ check_server_type @server_type, :app
109
105
  end
110
106
  end
111
107
  end
@@ -17,6 +17,7 @@ module RubyYacht
17
17
  @projects = []
18
18
  @hooks = []
19
19
  @server_types = []
20
+ @avoid_docker_machine = false
20
21
  end
21
22
 
22
23
  # The projects that are part of this system.
@@ -31,24 +32,51 @@ module RubyYacht
31
32
  # Each entry is a Symbol.
32
33
  attr_accessor :server_types
33
34
 
34
- # This method pulls up the hooks that we have defined.
35
+ # Whether we should avoid using docker-machine even if it is installed.
35
36
  #
36
- # The hooks can be filtered by the attributes on the hook, like `event_type`
37
- # and `event_time`.
37
+ # If docker-machine is not installed, the value of this flag will be
38
+ # ignored.
39
+ attr_accessor :disable_docker_machine
40
+
41
+ # This method pulls up the hooks that we have defined.
38
42
  #
39
43
  # ### Parameters
40
44
  #
41
- # * **attributes: Hash** The attributes to look for in the returned
42
- # hooks.
45
+ # * **server: App/Database**: The server we are fetching hooks for.
46
+ # * **event_type: Symbol**: The event that we are fetching hooks for.
43
47
  #
44
48
  # ### Returns
45
49
  #
46
50
  # The matching hooks. This will be an Array where each item is a Hook.
47
- def fetch_hooks(attributes={})
51
+ def fetch_hooks(server, event_type)
52
+ case server
53
+ when App
54
+ app_types = [server.server_type,:all]
55
+ database_types = [:all]
56
+ database = server.database
57
+ database_types << database.server_type if database
58
+ web_server_types = [:all] + server.project.web_servers.map(&:server_type).uniq
59
+ container_type = :app
60
+ when Database
61
+ database_types = [server.server_type, :all]
62
+ app_types = [:all]
63
+ app_types += server.apps.map(&:server_type)
64
+ web_server_types = [:all] + server.project.web_servers.map(&:server_type).uniq
65
+ container_type = :database
66
+ when WebServer
67
+ app_types = [:all] + server.project.apps.map(&:server_type).uniq
68
+ database_types = [:all] + server.project.databases.map(&:server_type).uniq
69
+ web_server_types = [:all, server.server_type]
70
+ container_type = :web
71
+ else
72
+ return []
73
+ end
48
74
  self.hooks.select do |hook|
49
- attributes.keys.all? do |key|
50
- hook.send(key) == attributes[key]
51
- end
75
+ hook.event_type == event_type &&
76
+ app_types.include?(hook.app_server_type) &&
77
+ database_types.include?(hook.database_server_type) &&
78
+ web_server_types.include?(hook.web_server_type) &&
79
+ hook.container_type == container_type
52
80
  end
53
81
  end
54
82
 
@@ -73,6 +101,7 @@ module RubyYacht
73
101
  # This initializer creates an empty configuration DSL.
74
102
  def initialize
75
103
  self.load_custom_attributes
104
+ @hook_options = {}
76
105
  end
77
106
 
78
107
  ##
@@ -105,34 +134,24 @@ module RubyYacht
105
134
  # RubyYacht::ServerType::DSL.
106
135
  add_object_list :server_type, RubyYacht::ServerType::DSL
107
136
 
108
- # The path for files and other resources from configuration hooks.
109
- attr_accessor :hook_folder
110
-
111
- # The app type for hooks that we are defining in the current block.
112
- attr_accessor :hook_server_type
137
+ # The default options for the hooks we're defining in the current block.
138
+ attr_accessor :hook_options
113
139
 
114
140
  # This method sets default attributes for a group of hooks.
115
141
  #
116
- # Any hooks that you create in the associated block will have their script
117
- # folder and app type specified by the attached properties.
142
+ # Any hooks that you create in the associated block will have the included
143
+ # options set on them automatically. You will also be able to override
144
+ # these options in the configuration blocks for individual hooks.
118
145
  #
119
146
  # ### Parameters
120
147
  #
121
- # * **folder: String** The full path to the script folder.
148
+ # * **options: Hash** The fields to set on the hooks.
122
149
  # * **block** A block for adding the hooks.
123
150
  def add_hooks(options = {}, &block)
124
- keys = [:folder, :server_type]
125
- old_options = {}
126
- keys.each do |key|
127
- old_options[key] = self.send("hook_#{key}")
128
- self.send("hook_#{key}=", options[key]) if options.has_key?(key)
129
- end
130
-
151
+ old_options = hook_options.dup
152
+ self.hook_options = options
131
153
  block.call
132
-
133
- keys.each do |key|
134
- self.send("hook_#{key}=", old_options[key])
135
- end
154
+ self.hook_options = old_options
136
155
  end
137
156
 
138
157
  # This method adds a before hook.
@@ -179,11 +198,11 @@ module RubyYacht
179
198
  private
180
199
 
181
200
  def add_hook(event_time, event_type, &block)
182
- folder = hook_folder
183
- type = hook_server_type
201
+ hook_options = self.hook_options
184
202
  hook event_time, event_type do
185
- script_folder folder
186
- server_type type
203
+ hook_options.each do |key, value|
204
+ public_send(key, value)
205
+ end
187
206
  instance_eval(&block)
188
207
  end
189
208
  end
@@ -17,6 +17,9 @@ module RubyYacht
17
17
 
18
18
  # The password we use to connect to the database
19
19
  attr_accessor :password
20
+
21
+ # The port the database server should listen on.
22
+ attr_accessor :port
20
23
 
21
24
  # The database-specific part of the container name for this database.
22
25
  attr_accessor :container_label
@@ -26,11 +29,21 @@ module RubyYacht
26
29
  host == 'localhost'
27
30
  end
28
31
 
32
+ # The project that contains this database.
33
+ def project
34
+ RubyYacht.configuration.projects.find { |project| project.databases.include?(self) }
35
+ end
36
+
37
+ # The apps that connect to this database.
38
+ def apps
39
+ project.apps.select { |app| app.database_name == self.name }
40
+ end
41
+
29
42
  # This method gets the name of the container and image for this database.
30
43
  #
31
44
  # This will be the project's prefix followed by the database's container
32
45
  # label.
33
- def container_name(project)
46
+ def container_name
34
47
  "#{project.system_prefix}-#{container_label}"
35
48
  end
36
49
 
@@ -46,11 +59,11 @@ module RubyYacht
46
59
  #
47
60
  # ### Parameters
48
61
  #
62
+ # * **server_type: Symbol** The type of database this is.
49
63
  # * **name: String** The name of the database.
50
- # * **server_type: Symbol** The type of database server this is.
51
- def initialize(name, server_type = nil)
52
- @name = name
64
+ def initialize(server_type, name)
53
65
  @server_type = server_type
66
+ @name = name.to_sym
54
67
  load_custom_attributes
55
68
  end
56
69
 
@@ -83,6 +96,12 @@ module RubyYacht
83
96
  # password `testpass`.
84
97
  add_attribute :password
85
98
 
99
+ ##
100
+ # :method: port
101
+ # You can call `port 1234` to tell the database server to listen on port
102
+ # 1234.
103
+ add_attribute :port
104
+
86
105
  ##
87
106
  # :method: container_label
88
107
  # You can call `container_label 'mysql'` to give this database a container
@@ -100,10 +119,7 @@ module RubyYacht
100
119
  # configuration.
101
120
  def check_required_attributes
102
121
  super
103
- server_type = RubyYacht.configuration.find_server_type(@server_type)
104
- unless server_type && server_type.container_type == :database
105
- raise "Database has invalid server type `#{@server_type}`"
106
- end
122
+ check_server_type @server_type, :database
107
123
  end
108
124
  end
109
125
  end
@@ -164,9 +164,7 @@ module RubyYacht
164
164
  variable_name = "@#{name}s"
165
165
  list = instance_variable_get(variable_name)
166
166
  object_config = type.new(*args)
167
- if config_block
168
- object_config.run(config_block)
169
- end
167
+ object_config.run(config_block)
170
168
  value = object_config.create_object
171
169
  list << value
172
170
  instance_variable_set(variable_name, list)
@@ -276,7 +274,20 @@ module RubyYacht
276
274
  end
277
275
  instance_variable_set("@#{name}", copy)
278
276
  end
279
- instance_eval(&block)
277
+ if block
278
+ instance_eval(&block)
279
+ end
280
+
281
+ type = RubyYacht.configuration.find_server_type(@server_type)
282
+ if type
283
+ type.server_defaults.each do |server_defaults|
284
+ server_defaults.each do |key, value|
285
+ if instance_variable_get("@#{key}") == nil
286
+ instance_variable_set("@#{key}", value)
287
+ end
288
+ end
289
+ end
290
+ end
280
291
  self
281
292
  end
282
293
 
@@ -293,6 +304,23 @@ module RubyYacht
293
304
  end
294
305
  end
295
306
  end
307
+
308
+ # This method checks that a server type has been registered.
309
+ #
310
+ # If it has not, this will raise an exception.
311
+ #
312
+ # ### Parameters
313
+ #
314
+ # * **server_type: Symbol** The server type that has been set on this
315
+ # DSL instance.
316
+ # * **container_type: Symbol** The container type that the server type
317
+ # must be registered for.
318
+ def check_server_type(server_type, container_type)
319
+ result = RubyYacht.configuration.find_server_type(server_type)
320
+ unless result && result.container_type == container_type
321
+ raise "#{self.class.name} has invalid #{container_type} server type `#{server_type}`"
322
+ end
323
+ end
296
324
 
297
325
  # This method creates an object with the attributes from this instance.
298
326
  #