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
@@ -16,20 +16,20 @@ module RubyYacht
16
16
  # The type of event that this hook is attached to.
17
17
  attr_accessor :event_type
18
18
 
19
- # The type of server that this hook applies to.
20
- attr_accessor :server_type
19
+ # The type of app server that this hook applies to.
20
+ attr_accessor :app_server_type
21
21
 
22
- # The path to the file that we should copy into the image for this hook.
23
- attr_accessor :copied_file_path
22
+ # The type of database server that this hook applies to.
23
+ attr_accessor :database_server_type
24
24
 
25
- # The command that we should run for this hook.
26
- attr_accessor :command
25
+ # The type of web server that this hook applies to.
26
+ attr_accessor :web_server_type
27
27
 
28
- # The name of the file containing the code for this hook.
29
- def copied_file_name
30
- return '' unless copied_file_path
31
- File.basename(copied_file_path)
32
- end
28
+ # The type of container that this hook applies to.
29
+ attr_accessor :container_type
30
+
31
+ # The behaviors that we will run for this hook.
32
+ attr_accessor :behaviors
33
33
 
34
34
  # This class provides a DSL for configuring hooks.
35
35
  class DSL
@@ -46,59 +46,99 @@ module RubyYacht
46
46
  def initialize(event_time, event_type)
47
47
  @event_time = event_time
48
48
  @event_type = event_type
49
+ @behaviors = []
49
50
  load_custom_attributes
50
51
  end
51
52
 
52
53
  ##
53
- # :method: server_type
54
+ # :method: app_server_type
54
55
  #
55
- # You can call `server_type :rails` to signify that this hook applies to
56
- # rails apps.
57
- add_attribute :server_type
56
+ # You can call `app_server_type :rails` to signify that this hook applies
57
+ # to rails apps.
58
+ add_attribute :app_server_type, :all
58
59
 
59
60
  ##
60
- # :method: command
61
+ # :method: database_server_type
61
62
  #
62
- # You can call `command 'whoami'` to signify that this hook runs the
63
- # command `whoami`. You can also set the command through `run_script`, if
64
- # the hook runs a script file included with the plugin.
65
- add_attribute :command
66
-
63
+ # You can call `database_server_type :mysql` to signify that this hook
64
+ # applies to MySQL databases.
65
+ add_attribute :database_server_type, :all
66
+
67
67
  ##
68
- # :method: copy_file
69
- #
70
- # You can call `copy_file 'foo.txt'` to signify that this hook should
71
- # copy a file called `foo.txt` from the hook's script folder to
72
- # `/var/docker`.
68
+ # :method: web_server_type
73
69
  #
74
- # You can pair this with a command if you want to move it from that
75
- # location in /var/docker into a custom location inside your code folder.
76
- #
77
- # The file copying happens at the time the image has built.
70
+ # You can call `web_server_type :nginx` to signify that this hook
71
+ # applies to nginx web servers.
72
+ add_attribute :web_server_type, :all
73
+
74
+ ##
75
+ # :method: container_type
78
76
  #
79
- # When setting this attribute, you must provide another command using the
80
- # `command` method.
81
- add_attribute :copy_file, nil, false
77
+ # You can call `container_type :app` to signify that this hook applies to
78
+ # app images.
79
+ add_attribute :container_type
82
80
 
83
81
  ##
84
82
  # :method: script_folder
85
83
  #
86
84
  # You can call `script_folder './scripts'` to signify that the scripts for
87
85
  # this hook are found in the `./scripts` folder.
88
- add_attribute :script_folder, nil, false
86
+ add_attribute :script_folder, '.'
89
87
 
90
- # This method sets the name of the script containing the code for the
91
- # hook.
88
+ # This method adds a behavior to run a command when the hook is run.
89
+ #
90
+ # ### Parameters
91
+ #
92
+ # * **cmd: String** The command to run.
93
+ def command(cmd)
94
+ @behaviors << CommandBehavior.new(cmd)
95
+ end
96
+
97
+ # This method adds a behavior to copy a file to the image when the hook is
98
+ # run.
99
+ #
100
+ # ### Parameters
101
+ #
102
+ # * **path: String** The path to the file, relative to the
103
+ # `script_folder`.
104
+ def copy_file(path)
105
+ @behaviors << CopyFileBehavior.new("#{@script_folder}/#{path}")
106
+ end
107
+
108
+ # This method adds a behavior to run a script.
92
109
  #
93
110
  # The script will be understood to be in the script folder that was given
94
111
  # when the DSL was created.
95
112
  #
96
113
  # ### Parameters
97
114
  #
98
- # * **name: String** The filename of the script.
99
- def run_script(name)
100
- @copy_file = name
101
- @command = "/var/docker/#{name}"
115
+ # * **interpreter: Symbol** The interpreter that should process the
116
+ # script. e.g. ruby or bash
117
+ # * **name: String** The filename of the script.
118
+ def run_script(interpreter, name)
119
+ copy_file name
120
+ destination = "/var/docker/#{name}"
121
+ command "#{interpreter} #{destination}"
122
+ end
123
+
124
+ # This method adds a behavior to set an environment variable.
125
+ #
126
+ # The variable's value can be defined literally, by passing a value as the
127
+ # second parameter to this method, or at build-time, by passing a block.
128
+ #
129
+ # ### Parameters
130
+ #
131
+ # * **name: String** The name of the environment variable.
132
+ # * **value: String** A literal value to set for the environment
133
+ # variable.
134
+ # * **block: Proc** A block for providing the environment variable.
135
+ def set_environment_variable(name, value=nil, &block)
136
+ if value
137
+ value_proc = Proc.new { value }
138
+ else
139
+ value_proc = block
140
+ end
141
+ @behaviors << EnvironmentVariableBehavior.new(name, value_proc)
102
142
  end
103
143
 
104
144
  # This method checks that all of the required attributes have been set on
@@ -109,18 +149,112 @@ module RubyYacht
109
149
  # This will also check that the app type is valid.
110
150
  def check_required_attributes
111
151
  super
112
- unless RubyYacht.configuration.find_server_type(@server_type)
113
- raise "Hook has invalid app type `#{@server_type}`"
152
+ if @app_server_type != :all
153
+ check_server_type @app_server_type, :app
154
+ end
155
+ if @database_server_type != :all
156
+ check_server_type @database_server_type, :database
157
+ end
158
+ if @web_server_type != :all
159
+ check_server_type @web_server_type, :web
114
160
  end
115
161
  end
116
-
117
- # This method creates a Hook object from the DSL.
118
- def create_object
119
- @copied_file_path = File.join(@script_folder || '.', @copy_file) if @copy_file
120
- super
162
+
163
+ creates_object RubyYacht::Hook, %w(event_time event_type app_server_type
164
+ database_server_type web_server_type container_type behaviors)
165
+ end
166
+
167
+ # This class is the base class for behaviors in hooks.
168
+ class Behavior
169
+ # The command that should be run in a Dockerfile for this behavior.
170
+ def dockerfile_command
171
+ ''
121
172
  end
122
173
 
123
- creates_object RubyYacht::Hook, %w(event_time event_type copied_file_path server_type command)
174
+ # The command that should be run in a shell script for this behavior.
175
+ def shell_command
176
+ ''
177
+ end
178
+
179
+ # This context in which the command is being generated.
180
+ attr_accessor :context
181
+ end
182
+
183
+ # This class provides a behavior for running a command in the image.
184
+ class CommandBehavior < Behavior
185
+ # This initializer creates the behavior.
186
+ #
187
+ # ### Parameters
188
+ #
189
+ # * **command: String** The command to run.
190
+ def initialize(command)
191
+ @command = command
192
+ end
193
+
194
+ # The command that should be run in a Dockerfile for this behavior.
195
+ def dockerfile_command
196
+ "RUN #{@command}"
197
+ end
198
+
199
+ # The command that should be run in a shell script for this behavior.
200
+ def shell_command
201
+ @command
202
+ end
203
+ end
204
+
205
+ # This class provides a behavior for copying a file from the host machine
206
+ # to the image.
207
+ class CopyFileBehavior < Behavior
208
+ # This initialize creates the behavior.
209
+ #
210
+ # ### Parameters
211
+ #
212
+ # * **file_path: String** The path to the file, relative to the root of
213
+ # the project.
214
+ def initialize(file_path)
215
+ @file_path = file_path
216
+ end
217
+
218
+ # The command that should be run in a Dockerfile for this behavior.
219
+ def dockerfile_command
220
+ "COPY #{File.basename(file_path)} /var/docker/"
221
+ end
222
+
223
+ # :method: file_path
224
+ # The path to the file that this behavior copies.
225
+ attr_reader :file_path
226
+ end
227
+
228
+ # This class provides a behavior for setting an environment variable in the
229
+ # image.
230
+ class EnvironmentVariableBehavior < Behavior
231
+ # This initializer creates the behavior.
232
+ #
233
+ # ### Parameters
234
+ #
235
+ # * **name: String** The name of the environment variable to create.
236
+ # * **proc: Proc** The proc for generating the value for the
237
+ # environment variable.
238
+ def initialize(name, proc)
239
+ @name = name
240
+ @proc = proc
241
+ @context = self
242
+ end
243
+
244
+ # The value for the environment variable.
245
+ def value
246
+ context.instance_eval(&@proc)
247
+ end
248
+
249
+ # The command that should be run in a Dockerfile for this behavior.
250
+ def dockerfile_command
251
+ "ENV #{@name} #{value}"
252
+ end
253
+
254
+ # The command that should be run in a shell script for this behavior.
255
+ def shell_command
256
+ "export #{@name}=\"#{value}\""
257
+ end
124
258
  end
125
259
  end
126
260
  end
@@ -1,6 +1,7 @@
1
1
  require_relative 'dns_server'
2
2
  require_relative 'app'
3
3
  require_relative 'database'
4
+ require_relative 'web_server'
4
5
 
5
6
  module RubyYacht
6
7
  # This class provides a configuration for a project in our system.
@@ -17,9 +18,6 @@ module RubyYacht
17
18
  # project.
18
19
  attr_accessor :system_prefix
19
20
 
20
- # The domain that the apps for this project are accessed under.
21
- attr_accessor :domain
22
-
23
21
  # The hostname for the repository that contains the code for the apps.
24
22
  attr_accessor :repository
25
23
 
@@ -32,6 +30,10 @@ module RubyYacht
32
30
 
33
31
  # The configuration for the apps. Each entry is a RubyYacht::App.
34
32
  attr_accessor :apps
33
+
34
+ # The configuration for the web servers. Each entry is a
35
+ # RubyYacht::WebServer.
36
+ attr_accessor :web_servers
35
37
 
36
38
  # The configuration for the DNS for the apps. This is a
37
39
  # RubyYacht::DnsServer.
@@ -73,12 +75,6 @@ module RubyYacht
73
75
  # system_prefix` to `my-apps`
74
76
  add_attribute :system_prefix
75
77
 
76
- ##
77
- # :method: domain
78
- # You can call `domain 'test.com'` to set the project's `domain` to
79
- # test.com
80
- add_attribute :domain
81
-
82
78
  ##
83
79
  # :method: repository
84
80
  # You can call `repository 'github.com'` to set the project's `repository`
@@ -114,6 +110,14 @@ module RubyYacht
114
110
  # call methods in RubyYacht::Database::DSL
115
111
  add_object_list :database, RubyYacht::Database::DSL
116
112
 
113
+ ##
114
+ # :method: web_server
115
+ #
116
+ # You can call `web_server` to configure a web server for the project.
117
+ # This takes a block for configuring the server, which allows you to
118
+ # call methods in RubyYacht::WebServer::DSL
119
+ add_object_list :web_server, RubyYacht::WebServer::DSL
120
+
117
121
  ##
118
122
  # :method: dns_server
119
123
  #
@@ -133,14 +137,16 @@ module RubyYacht
133
137
  # method on the DSL that builds an app with the type `foo`.
134
138
  def load_app_initializers
135
139
  RubyYacht.configuration.server_types.each do |server_type|
136
- method_name = "#{server_type.name}_#{server_type.container_type}"
137
- define_singleton_method method_name do |name, &block|
140
+ main_method = server_type.container_type.to_s
141
+ main_method += "_server" if server_type.container_type == :web
142
+ method_name = "#{server_type.name}_#{main_method}"
143
+ define_singleton_method method_name do |*args, &block|
138
144
  self.public_send(
139
- server_type.container_type,
140
- name,
145
+ main_method,
141
146
  server_type.name,
147
+ *args,
142
148
  &block
143
- )
149
+ )
144
150
  end
145
151
  end
146
152
  end
@@ -40,23 +40,16 @@ module RubyYacht
40
40
  # it will be called `rails_environment` on the server's DSL. This prevents
41
41
  # conflicts with attributes from other plugins.
42
42
  attr_accessor :server_attributes
43
+
44
+ # The default values for the servers with this server type.
45
+ #
46
+ # Each entry will be a hash where the keys are the names of attributes, and
47
+ # the values are the default values.
48
+ attr_accessor :server_defaults
43
49
 
44
50
  # The docker image that we use as the source for the server images.
45
51
  attr_accessor :baseline_image
46
52
 
47
- # The custom environment variables that we set in the images for this server
48
- # type.
49
- #
50
- # Each entry will be a hash with the following keys:
51
- #
52
- # * **name: String** The name of the environment variable
53
- # * **image: String** The type of image that this is set in (e.g. server
54
- # or database).
55
- # * **block** A block that will be called inside the Dockerfile
56
- # ERB for providing the value of the environment
57
- # variable.
58
- attr_accessor :environment_variables
59
-
60
53
  # This class provides a DSL for configuring a RubyYacht::ServerType.
61
54
  class DSL
62
55
  include RubyYacht::DSL::Base
@@ -69,7 +62,6 @@ module RubyYacht
69
62
  # * **name: Symbol** The name of the server type.
70
63
  def initialize(name)
71
64
  @name = name
72
- @environment_variables = []
73
65
  load_custom_attributes
74
66
  end
75
67
 
@@ -96,27 +88,18 @@ module RubyYacht
96
88
  #
97
89
  # :method: server_attribute
98
90
  # You can call `server_attribute name: :environment, default: 'staging'`
99
- # to add an attribute to the app DSL.
91
+ # to add an attribute to the server DSL.
100
92
  add_list :server_attribute
101
93
 
94
+ #
95
+ # :method: server_default
96
+ # You can call `server_default port: 3306` to specify that the servers
97
+ # should have a default value of 3306 for the `port` attribute.
98
+ add_list :server_default
99
+
102
100
  creates_object RubyYacht::ServerType, [:name, :baseline_image,
103
101
  :container_type, :project_attributes, :server_attributes,
104
- :environment_variables]
105
-
106
- # This method defines a new environment variable set for this app type.
107
- #
108
- # ### Parameters
109
- #
110
- # * **image: Symbol** The type of image this environment variable is set
111
- # for.
112
- # * **name: String** The name of the environment variable.
113
- # * **block** A block for generating the environment variable.
114
- # This will have access to the project (as @project)
115
- # and the server (as @server) that we are building
116
- # the image for.
117
- def environment_variable(image, name, &block)
118
- @environment_variables << {image: image, name: name, block: block}
119
- end
102
+ :server_defaults]
120
103
  end
121
104
  end
122
105
  end
@@ -0,0 +1,87 @@
1
+ module RubyYacht
2
+ # This class models a web server that's part of the local system.
3
+ #
4
+ # See RubyYacht::WebServer::DSL for information on configuring the server.
5
+ class WebServer
6
+ # The name of the server
7
+ attr_accessor :name
8
+
9
+ # The domain that this web server listens on.
10
+ attr_accessor :domain
11
+
12
+ # The port that this web server listens on.
13
+ attr_accessor :port
14
+
15
+ # The name of the web server plugin for this server.
16
+ attr_accessor :server_type
17
+
18
+ # The project that includes this web server.
19
+ def project
20
+ RubyYacht.configuration.projects.find { |project| project.web_servers.include?(self) }
21
+ end
22
+
23
+ # This method gets the name of the image / container that this server will
24
+ # run in.
25
+ def container_name
26
+ project = self.project
27
+ return "#{project.system_prefix}-#{self.name}"
28
+ end
29
+
30
+ # This class provide's the DSL for configuring a web server.
31
+ #
32
+ # Inside of the project configuration, you can call `web_server [name]` to
33
+ # add a web server, and then pass it a block to configure the server, which
34
+ # will allow you to call these DSL methods.
35
+ #
36
+ # You can also call `web_server` with no argument, which will give it the
37
+ # name `web`.
38
+ class DSL
39
+ include RubyYacht::DSL::Base
40
+ extend RubyYacht::DSL::Base::ClassMethods
41
+
42
+ # This initializer starts the DSL for the server.
43
+ #
44
+ # ### Parameters
45
+ #
46
+ # * **server_type: Symbol** The type of server this is.
47
+ # * **name: String** The name of the server.
48
+ def initialize(server_type, name=:web)
49
+ @server_type = server_type
50
+ @name = name.to_sym
51
+ load_custom_attributes
52
+ end
53
+
54
+ add_attribute :name
55
+
56
+ ##
57
+ # :method: domain
58
+ # You can call `domain 'test.com'` to tell the web server to create
59
+ # subdomains under test.com.
60
+ add_attribute :domain
61
+
62
+ ##
63
+ # :method: server_type
64
+ # You can call `server_type :foo` to set the app's `server_type`.
65
+ add_attribute :server_type
66
+
67
+ ##
68
+ # :method: port
69
+ # You can call `port 8080` to set the server's `port`. It defaults to 80.
70
+ add_attribute :port, 80
71
+
72
+ creates_object WebServer
73
+
74
+ # This method checks that all of the required attributes have been set on
75
+ # the object.
76
+ #
77
+ # If they haven't, this will raise an exception.
78
+ #
79
+ # It also checks that the server type has been defined in the
80
+ # configuration.
81
+ def check_required_attributes
82
+ super
83
+ check_server_type @server_type, :web
84
+ end
85
+ end
86
+ end
87
+ end
@@ -3,6 +3,7 @@ require 'ruby_yacht/dsl/configuration'
3
3
  require 'ruby_yacht/dsl/project'
4
4
  require 'ruby_yacht/dsl/app'
5
5
  require 'ruby_yacht/dsl/database'
6
+ require 'ruby_yacht/dsl/web_server'
6
7
  require 'ruby_yacht/dsl/dns_server'
7
8
  require 'ruby_yacht/dsl/hook'
8
9
  require 'ruby_yacht/dsl/server_type'
@@ -1,18 +1,20 @@
1
1
  FROM <%= @project.system_prefix %>-<%= @app.server_type %>-app-dependencies
2
2
 
3
- <% database = @app.database(@project) %>
3
+ <% database = @app.database %>
4
4
  <% if database %>
5
- ENV DATABASE_HOST <%= database.local? ? database.container_name(@project) : database.host %>
5
+ ENV DATABASE_HOST <%= database.local? ? database.container_name : database.host %>
6
6
  ENV DATABASE_NAME <%= database.name %>
7
7
  ENV DATABASE_PASSWORD <%= database.password %>
8
8
  ENV DATABASE_USERNAME <%= database.username %>
9
9
  ENV DATABASE_TYPE <%= database.server_type %>
10
+ ENV DATABASE_PORT <%= database.port %>
10
11
  <% end %>
11
12
  ENV APP_PORT <%= @app.port %>
12
13
  ENV REPOSITORY_HOST <%= @project.repository %>
13
- ENV REPOSITORY_NAME <%= @app.repository_name %>
14
14
  ENV SYSTEM_PREFIX <%= @project.system_prefix %>
15
- <%= include_environment_variables :app %>
15
+ <% if @app.repository_name %>
16
+ ENV REPOSITORY_NAME <%= @app.repository_name %>
17
+ <% end %>
16
18
 
17
19
  RUN rm -r /var/code
18
20
  RUN mkdir -p /var/code
@@ -20,11 +22,20 @@ RUN mkdir -p /var/code
20
22
  COPY checkout.bash /var/docker/checkout.bash
21
23
  COPY before_startup.bash /var/docker/before_startup.bash
22
24
  COPY startup.bash /var/docker/startup.bash
23
- <%= copy_hooks [:startup, :build_checkout] %>
25
+ <%= copy_hooks @app, [:startup] %>
26
+ <% if @app.repository_name == nil %>
27
+ <%= copy_hooks @app, [:build_new_app] %>
28
+ <% end %>
24
29
 
25
30
  RUN chmod u+x /var/docker/*
26
31
 
27
- <%= include_event(:build_checkout) { "RUN /var/docker/checkout.bash\nWORKDIR /var/code"} %>
32
+ WORKDIR /var/code
33
+
34
+ <% if @app.repository_name %>
35
+ <%= include_event(@app, :build_checkout) { "RUN /var/docker/checkout.bash" } %>
36
+ <% else %>
37
+ <%= include_event(@app, :build_new_app) %>
38
+ <% end %>
28
39
 
29
40
  EXPOSE <%= @app.port %>
30
41
 
@@ -1,6 +1,8 @@
1
1
  #! /bin/bash
2
2
 
3
- cd /var/code;
4
- /var/docker/checkout.bash;
3
+ cd /var/code
4
+ <% if @app.repository_name %>
5
+ /var/docker/checkout.bash
6
+ <% end %>
5
7
 
6
- <%= include_event :startup, :before, in_bash: true %>
8
+ <%= include_event @app, :startup, :before, in_bash: true %>
@@ -1,3 +1,6 @@
1
1
  #! /bin/bash
2
- /var/docker/before_startup.bash;
3
- <%= include_event :startup, [:during, :after], in_bash: true %>
2
+ <% if @app.repository_name == nil %>
3
+ <%= include_event @app, :build_new_app, [:before, :during, :after], in_bash: true %>
4
+ <% end %>
5
+ /var/docker/before_startup.bash
6
+ <%= include_event @app, :startup, [:during, :after], in_bash: true %>
@@ -6,30 +6,26 @@
6
6
 
7
7
  FROM <%= @server_type.baseline_image %>
8
8
 
9
- <%= include_environment_variables :app_dependencies %>
9
+ <%= include_event @project.apps, :initialize_app_environment %>
10
10
 
11
11
  RUN mkdir -p /root/.ssh
12
12
  COPY id_rsa /root/.ssh
13
13
  RUN ssh-keyscan <%= @project.repository %> >> /root/.ssh/known_hosts
14
14
 
15
15
  RUN mkdir -p /var/docker/
16
- RUN touch /var/docker/.keep
16
+ RUN mkdir -p /var/code/
17
17
 
18
- <%= copy_hooks [:install_libraries] %>
19
-
20
- RUN chmod u+x /var/docker/*
18
+ RUN apt-get update && apt-get upgrade -y
21
19
 
22
20
  <% @project.apps.each do |app| %>
23
21
  <% next unless app.server_type == @server_type.name %>
22
+ <% next unless app.repository_name %>
24
23
 
25
24
  RUN git clone git@<%= @project.repository %>:<%= app.repository_name %> /var/code/<%= app.name %>
26
25
  WORKDIR /var/code/<%= app.name %>
27
- <%= include_event :install_libraries %>
26
+ <%= include_event app, :install_libraries %>
28
27
  <% end %>
29
28
 
30
- RUN rm /var/docker/*
29
+ RUN rm -f /var/docker/*
31
30
 
32
- WORKDIR /
33
-
34
- RUN apt-get update && apt-get upgrade -y
35
- RUN apt-get install -y mysql-client
31
+ WORKDIR /