ruby_yacht 0.5.0 → 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
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
  #