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
@@ -4,36 +4,25 @@ ENV DATABASE_USERNAME <%= @database.username %>
4
4
  ENV DATABASE_PASSWORD <%= @database.password %>
5
5
  ENV DATABASE_NAME <%= @database.name %>
6
6
  ENV DATABASE_TYPE <%= @database.server_type %>
7
- <%= include_environment_variables :database %>
8
- <% with_each_app_type do %>
9
- <%= include_environment_variables :database %>
10
- <% end %>
11
7
 
12
8
  COPY checkout.bash /var/docker/checkout.bash
13
9
  COPY startup.bash /var/docker/startup.bash
14
- <%= copy_hooks [:install_libraries, :create_databases, :startup] %>
15
- <% with_each_app_type do %>
16
- <%= copy_hooks [:load_database_seeds] %>
17
- <% end %>
10
+ <%= copy_hooks @database, [:startup] %>
18
11
 
19
12
  RUN chmod u+x /var/docker/*
20
13
 
21
- <%= include_event :install_libraries %>
14
+ <%= include_event @database, :install_libraries %>
22
15
 
23
- <%= include_event :create_databases %>
16
+ <%= include_event @database, :create_databases %>
24
17
 
25
- <% original_server_type = @server_type %>
26
- <% apps = @project.apps.select { |app| app.database_name == @database.name } %>
27
- <% apps.each do |app| %>
28
- <% @server_type = RubyYacht.configuration.find_server_type(app.server_type) %>
18
+ <% @database.apps.each do |app| %>
29
19
 
20
+ <% next unless app.repository_name %>
30
21
  RUN /var/docker/checkout.bash <%= @project.repository %> <%= app.name %> <%= app.repository_name %>
31
22
  WORKDIR /var/code/<%= app.name %>
32
- <%= include_event :load_database_seeds %>
23
+ <%= include_event @database, :load_database_seeds %>
33
24
  <% end %>
34
25
 
35
- <% @server_type = original_server_type %>
36
-
37
26
  RUN rm -r /var/code
38
27
  WORKDIR /
39
28
 
@@ -41,6 +30,6 @@ ENV DATABASE_USERNAME ''
41
30
  ENV DATABASE_PASSWORD ''
42
31
  ENV DATABASE_NAME ''
43
32
 
44
- EXPOSE 3306
33
+ EXPOSE <%= @database.port %>
45
34
 
46
35
  CMD /var/docker/startup.bash
@@ -1,3 +1,3 @@
1
1
  #! /bin/bash
2
2
 
3
- <%= include_event :startup, [:before, :during], in_bash: true %>
3
+ <%= include_event @database, :startup, [:before, :during], in_bash: true %>
@@ -2,31 +2,37 @@ FROM nginx
2
2
 
3
3
  RUN apt-get update
4
4
  RUN apt-get upgrade -y
5
- RUN apt-get install -y ruby
5
+ <%= include_event @server, :install_libraries %>
6
6
 
7
7
  RUN mkdir -p /var/docker
8
8
 
9
- COPY add_project.rb /var/docker/add_project.rb
10
- COPY add_app.rb /var/docker/add_app.rb
11
- COPY index.html.erb /var/docker/index.html.erb
12
- COPY index_config.erb /var/docker/index_config.erb
13
- COPY app_config.erb /var/docker/app_config.erb
14
-
15
- <% @projects.each do |project| %>
16
- <% primary_app = project.primary_app %>
17
- <% if project.apps.any? { |app| app.name == project.system_prefix } %>
18
- <% primary_app = project.system_prefix %>
9
+ <% primary_app = @project.primary_app %>
10
+ <% if @project.apps.any? { |app| app.name == @project.system_prefix } %>
11
+ <% primary_app = @project.system_prefix %>
19
12
  <% end %>
20
- <% if primary_app == nil %>
21
- <% app_list = project.apps.map(&:name).join(',') %>
22
13
 
23
- RUN ruby /var/docker/add_project.rb <%= project.system_prefix %> <%= project.domain %> <%= app_list %>
24
- <% end %>
25
- <% project.apps.each do |app| %>
26
- RUN ruby /var/docker/add_app.rb <%= project.system_prefix %> <%= project.domain %> <%= app.name %> <%= app.port %> <%= app.name == primary_app %>
14
+ ENV PROJECT <%= @project.system_prefix %>
15
+ ENV DOMAIN <%= @server.domain %>
16
+
17
+ <% if primary_app == nil %>
18
+ <% app_list = @project.apps.map(&:name).join(',') %>
19
+ ENV APP_LIST <%= app_list %>
20
+ <%= include_event @server, :add_project_landing %>
27
21
  <% end %>
22
+
23
+ <% @project.apps.each do |app| %>
24
+
25
+ ENV APP_NAME <%= app.name %>
26
+ ENV APP_PORT <%= app.port %>
27
+ ENV APP_PRIMARY <%= app.name == primary_app %>
28
+ <%= include_event @server, :add_app_config %>
28
29
  <% end %>
29
30
 
30
31
  RUN rm -r /var/docker
31
- RUN apt-get remove -y ruby
32
- RUN apt-get autoremove -y
32
+
33
+ ENV PROJECT ""
34
+ ENV DOMAIN ""
35
+ ENV APP_LIST ""
36
+ ENV APP_NAME ""
37
+ ENV APP_PORT ""
38
+ ENV APP_PRIMARY ""
@@ -7,18 +7,28 @@ module RubyYacht::Plugins
7
7
  server_type :mysql do
8
8
  container_type :database
9
9
  baseline_image 'mysql'
10
-
11
- environment_variable :database, 'DEBIAN_FRONTEND' do
12
- 'noninteractive'
13
- end
10
+ server_default port: 3306
14
11
  end
15
12
  end
16
13
 
17
14
  RubyYacht.configure do
18
- add_hooks(server_type: :mysql, folder: File.join(File.dirname(__FILE__), 'mysql', 'scripts')) do
19
- during(:install_libraries) { command 'apt-get install -y mysql-server' }
20
- during(:create_databases) { run_script 'setup.bash' }
21
- during(:startup) { command 'mysqld_safe --bind-address=0.0.0.0' }
15
+ add_hooks(database_server_type: :mysql, container_type: :database, script_folder: File.join(File.dirname(__FILE__), 'mysql', 'scripts')) do
16
+ during(:install_libraries) do
17
+ set_environment_variable 'DEBIAN_FRONTEND', 'noninteractive'
18
+ command 'apt-get install -y mysql-server'
19
+ end
20
+ during(:create_databases) { run_script :bash, 'setup.bash' }
21
+
22
+ before(:startup) do
23
+ set_environment_variable('MYSQL_PORT') { @database.port }
24
+ end
25
+
26
+ during(:startup) { command 'mysqld_safe --bind-address=0.0.0.0 --port=$MYSQL_PORT' }
27
+
28
+ during :install_libraries do
29
+ container_type :app
30
+ command 'apt-get install -y mysql-client'
31
+ end
22
32
  end
23
33
  end
24
34
  end
@@ -1,10 +1,10 @@
1
1
  #! /usr/local/bin/ruby
2
2
  require 'erb'
3
3
 
4
- @project = ARGV.shift
5
- @domain = ARGV.shift
6
- @app = ARGV.shift
7
- @port = ARGV.shift
4
+ @project = ENV['PROJECT']
5
+ @domain = ENV['DOMAIN']
6
+ @app = ENV['APP_NAME']
7
+ @port = ENV['APP_PORT']
8
8
 
9
9
  if @project == @app
10
10
  @container_name = @project
@@ -12,7 +12,7 @@ else
12
12
  @container_name = "#{@project}-#{@app}"
13
13
  end
14
14
 
15
- @is_primary_app = ARGV.shift == 'true'
15
+ @is_primary_app = ENV['APP_PRIMARY'] == 'true'
16
16
 
17
17
  File.open(File.join("/etc/nginx/conf.d/#{@container_name}.conf"), 'w') do |file|
18
18
  file.write(ERB.new(File.read('/var/docker/app_config.erb')).result(binding))
@@ -1,9 +1,9 @@
1
1
  #! /usr/local/bin/ruby
2
2
  require 'erb'
3
3
 
4
- @project = ARGV.shift
5
- @domain = ARGV.shift
6
- @app_names = ARGV.shift.split(',')
4
+ @project = ENV['PROJECT']
5
+ @domain = ENV['DOMAIN']
6
+ @app_names = ENV['APP_LIST'].split(',')
7
7
 
8
8
  File.open(File.join("/usr/share/nginx/html/#{@project}.html"), 'w') do |file|
9
9
  file.write(ERB.new(File.read('/var/docker/index.html.erb')).result(binding))
@@ -0,0 +1,28 @@
1
+ module RubyYacht::Plugins
2
+ # This module provides the plugin for managing nginx web servers.
3
+ module Nginx
4
+ # This method loads the configuration for the nginx plugin.
5
+ def self.load
6
+ RubyYacht.configure do
7
+ server_type :nginx do
8
+ container_type :web
9
+ baseline_image 'nginx'
10
+ end
11
+ end
12
+
13
+ RubyYacht.configure do
14
+ add_hooks container_type: :web, web_server_type: :nginx, script_folder: File.join(File.dirname(__FILE__), 'nginx', 'scripts') do
15
+ during(:install_libraries) { command 'apt-get install -y ruby' }
16
+ during(:install_libraries) { copy_file 'index.html.erb' }
17
+ during(:install_libraries) { copy_file 'index_config.erb' }
18
+ during(:install_libraries) { copy_file 'app_config.erb' }
19
+
20
+ during(:add_project_landing) { run_script :ruby, 'add_project.rb' }
21
+ during(:add_app_config) { run_script :ruby, 'add_app.rb' }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
27
+
28
+ RubyYacht::Plugins::Nginx.load
@@ -0,0 +1,10 @@
1
+ #! /usr/local/bin/ruby
2
+
3
+ if `which rails` == ''
4
+ system "gem install rails"
5
+ end
6
+
7
+ unless File.exist?('/var/code/Gemfile')
8
+ system "rails new /var/code"
9
+ system "sed -e \"s/# gem 'therubyracer'/gem 'therubyracer'/\" -i Gemfile"
10
+ end
@@ -2,6 +2,10 @@
2
2
  require 'yaml'
3
3
 
4
4
  database_host = ENV['DATABASE_HOST']
5
+
6
+ if database_host == nil
7
+ exit(0)
8
+ end
5
9
 
6
10
  common_config = {
7
11
  'adapter' => 'mysql2',
@@ -9,7 +13,8 @@ common_config = {
9
13
  'password' => ENV['DATABASE_PASSWORD'],
10
14
  'reconnect' => true,
11
15
  'host' => database_host,
12
- 'database' => ENV['DATABASE_NAME']
16
+ 'database' => ENV['DATABASE_NAME'],
17
+ 'port' => ENV['DATABASE_PORT']
13
18
  }
14
19
 
15
20
  database_config = {
@@ -3,6 +3,12 @@ module RubyYacht::Plugins
3
3
  module Rails
4
4
  # This method loads the configuration for the Rails plugin.
5
5
  def self.load
6
+ load_server_type
7
+ load_hooks
8
+ end
9
+
10
+ # This method loads the configuration for the Rails server type.
11
+ def self.load_server_type
6
12
  RubyYacht.configure do
7
13
  server_type :rails do
8
14
  container_type :app
@@ -10,33 +16,42 @@ module RubyYacht::Plugins
10
16
  project_attribute name: :environment, default: 'development'
11
17
  project_attribute name: :excluded_gem_groups, default: []
12
18
  project_attribute name: :secret_key_base
13
-
14
- environment_variable :app_dependencies, 'RAILS_ENV' do
15
- @project.rails_environment
16
- end
17
-
18
- environment_variable :app, 'SECRET_KEY_BASE' do
19
- @project.rails_secret_key_base
20
- end
21
-
22
- environment_variable :app_dependencies, 'EXCLUDED_GEM_GROUPS' do
23
- groups = @project.rails_excluded_gem_groups.join(' ')
24
- groups = '""' if groups == ''
25
- groups
26
- end
27
19
  end
28
20
  end
21
+ end
29
22
 
23
+ # This method loads the configuration for the Rails hooks.
24
+ def self.load_hooks
30
25
  RubyYacht.configure do
31
- add_hooks(server_type: :rails, folder: File.join(File.dirname(__FILE__), 'rails', 'scripts')) do
32
- during(:install_libraries) { run_script 'install_gems.rb' }
26
+ add_hooks(app_server_type: :rails, container_type: :app, script_folder: File.join(File.dirname(__FILE__), 'rails', 'scripts')) do
27
+ during :initialize_app_environment do
28
+ set_environment_variable 'RAILS_ENV' do
29
+ @project.rails_environment
30
+ end
31
+ set_environment_variable 'SECRET_KEY_BASE' do
32
+ @project.rails_secret_key_base
33
+ end
34
+ set_environment_variable 'EXCLUDED_GEM_GROUPS' do
35
+ groups = @project.rails_excluded_gem_groups.join(' ')
36
+ groups = '""' if groups == ''
37
+ groups
38
+ end
39
+ end
40
+ during(:install_libraries) { run_script :ruby, 'install_gems.rb' }
33
41
 
34
42
  after(:build_checkout) { command 'bundle install --clean' }
35
43
 
36
- during(:load_database_seeds) { run_script 'load_seeds.rb' }
44
+ during :load_database_seeds do
45
+ container_type :database
46
+ run_script :ruby, 'load_seeds.rb'
47
+ end
48
+
49
+ during :build_new_app do
50
+ run_script :ruby, 'build_new_app.rb'
51
+ end
37
52
 
38
- before(:startup) { run_script 'update_rails_config.rb' }
39
- before(:startup) { run_script 'prepare_rails_for_launch.rb' }
53
+ before(:startup) { run_script :ruby, 'update_rails_config.rb' }
54
+ before(:startup) { run_script :ruby, 'prepare_rails_for_launch.rb' }
40
55
 
41
56
  during(:startup) { command 'rails s -b 0.0.0.0 -p $APP_PORT -e $RAILS_ENV' }
42
57
  end
@@ -4,4 +4,5 @@ module RubyYacht
4
4
  end
5
5
  end
6
6
  require 'ruby_yacht/plugins/rails'
7
- require 'ruby_yacht/plugins/mysql'
7
+ require 'ruby_yacht/plugins/mysql'
8
+ require 'ruby_yacht/plugins/nginx'
@@ -20,36 +20,48 @@ module RubyYacht::Runner
20
20
 
21
21
  projects.each do |project|
22
22
  log "Building images for #{project.name}"
23
- @project = project
24
23
 
25
24
  id_path = File.join(ENV['HOME'], '.ssh', 'id_rsa')
26
25
  tmp_id_path = File.join('tmp', 'id_rsa')
27
26
  FileUtils.cp(id_path, tmp_id_path) if File.exist?(id_path)
27
+
28
+ build_images(project)
29
+ end
28
30
 
29
- project.apps.map(&:server_type).uniq.each do |type_name|
30
- @server_type = RubyYacht.configuration.find_server_type(type_name)
31
- build_image 'app-dependencies', "#{@project.system_prefix}-#{@server_type.name}-app-dependencies"
32
- end
33
-
34
- @app_server_type = RubyYacht.configuration.find_server_type(project.apps.first.server_type)
35
- project.databases.select(&:local?).each do |database|
36
- @database = database
37
- @server_type = RubyYacht.configuration.find_server_type(@database.server_type)
38
- build_image 'database', @database.container_name(@project)
39
- end
40
-
41
- @project.apps.each do |app|
42
- @app = app
43
- @server_type = RubyYacht.configuration.find_server_type(@app.server_type)
44
- build_image 'app', @app.container_name(@project)
45
- end
46
- @app = nil
31
+ true
32
+ end
33
+
34
+ # This method builds the images for a project.
35
+ #
36
+ # ### Parameters
37
+ #
38
+ # * **project: Project** The project we are building.
39
+ def build_images(project)
40
+ @project = project
41
+ project.apps.map(&:server_type).uniq.each do |type_name|
42
+ @server_type = RubyYacht.configuration.find_server_type(type_name)
43
+ build_image 'app-dependencies', "#{@project.system_prefix}-#{@server_type.name}-app-dependencies"
47
44
  end
48
45
 
49
- @projects = projects
50
- build_image 'web', "#{default_system_prefix}-web"
46
+ @app_server_type = RubyYacht.configuration.find_server_type(project.apps.first.server_type)
47
+ project.databases.select(&:local?).each do |database|
48
+ @database = database
49
+ @server_type = RubyYacht.configuration.find_server_type(@database.server_type)
50
+ build_image 'database', @database.container_name
51
+ end
52
+ @database = nil
51
53
 
52
- true
54
+ @project.apps.each do |app|
55
+ @app = app
56
+ @server_type = RubyYacht.configuration.find_server_type(@app.server_type)
57
+ build_image 'app', @app.container_name
58
+ end
59
+ @app = nil
60
+
61
+ project.web_servers.each do |server|
62
+ @server = server
63
+ build_image 'web', @server.container_name
64
+ end
53
65
  end
54
66
 
55
67
  # This method builds an image.
@@ -79,13 +91,9 @@ module RubyYacht::Runner
79
91
 
80
92
  set_image_settings(folder_name)
81
93
 
82
- @hook_events.each do |event|
83
- @server_types.each do |server_type|
84
- RubyYacht.configuration.fetch_hooks(server_type: server_type, event_type: event).each do |hook|
85
- next unless hook.copied_file_path
86
- FileUtils.cp hook.copied_file_path, "tmp"
87
- end
88
- end
94
+ fetch_behaviors(@hook_servers, @hook_events).each do |behavior|
95
+ next unless behavior.is_a?(RubyYacht::Hook::CopyFileBehavior)
96
+ FileUtils.cp behavior.file_path, "tmp"
89
97
  end
90
98
 
91
99
  @templates.each do |template_name|
@@ -107,7 +115,7 @@ module RubyYacht::Runner
107
115
 
108
116
  # This method establishes settings for building an image.
109
117
  #
110
- # This will set the `@templates`, `@hook_events`, and `@server_types`
118
+ # This will set the `@templates`, `@hook_events`, and `@hook_servers`
111
119
  # instance variables.
112
120
  #
113
121
  # ### Parameters
@@ -119,21 +127,26 @@ module RubyYacht::Runner
119
127
  case folder_name
120
128
  when 'app' then ['Dockerfile', 'before_startup.bash', 'startup.bash']
121
129
  when 'database' then ['Dockerfile', 'startup.bash']
130
+ when 'web' then ['Dockerfile']
122
131
  else ['Dockerfile']
123
132
  end
124
133
 
125
134
  @hook_events =
126
135
  case folder_name
127
- when 'app' then [:startup, :build_checkout]
128
- when 'app-dependencies' then [:install_libraries]
136
+ when 'app' then [:startup, :build_checkout, :build_new_app]
137
+ when 'app-dependencies' then [:initialize_app_environment, :install_libraries]
129
138
  when 'database' then [:create_databases, :install_libraries, :load_database_seeds]
139
+ when 'web' then [:install_libraries, :add_project_landing, :add_app_config]
130
140
  else []
131
141
  end
132
142
 
133
- @server_types =
143
+ @hook_servers =
134
144
  case folder_name
135
- when 'database' then [@server_type.name] + @project.apps.map(&:server_type).uniq
136
- else [@server_type.name]
145
+ when 'database' then [@database]
146
+ when 'app' then [@app]
147
+ when 'app-dependencies' then @project.apps
148
+ when 'web' then [@server]
149
+ else []
137
150
  end
138
151
  end
139
152
 
@@ -145,6 +158,8 @@ module RubyYacht::Runner
145
158
  #
146
159
  # ### Parameters
147
160
  #
161
+ # * **servers: Database/App/Array**: The server or servers whose hooks we
162
+ # are running.
148
163
  # * **event_type: Symbol** The event whose hooks we are running.
149
164
  # * **times: [Symbol]** The event times whose hooks we want to
150
165
  # include. You can also pass a symbol to this
@@ -161,7 +176,7 @@ module RubyYacht::Runner
161
176
  # ### Returns
162
177
  #
163
178
  # A String with the contents of the Dockerfile for running the hooks.
164
- def include_event(event_type, times = [:before, :during, :after], options = {})
179
+ def include_event(servers, event_type, times = [:before, :during, :after], options = {})
165
180
  result = ""
166
181
  if times.is_a?(Symbol)
167
182
  times = [times]
@@ -172,11 +187,13 @@ module RubyYacht::Runner
172
187
  result += "\n"
173
188
  next
174
189
  end
175
- RubyYacht.configuration.fetch_hooks(server_type: @server_type.name, event_type: event_type, event_time: time).each do |hook|
190
+
191
+ fetch_behaviors(servers, [event_type], time).each do |behavior|
192
+ behavior.context = self
176
193
  if options[:in_bash]
177
- result += "#{hook.command};\n"
194
+ result += "#{behavior.shell_command}\n"
178
195
  else
179
- result += "RUN #{hook.command}\n"
196
+ result += "#{behavior.dockerfile_command}\n"
180
197
  end
181
198
  end
182
199
  end
@@ -184,56 +201,53 @@ module RubyYacht::Runner
184
201
  result
185
202
  end
186
203
 
187
- # This method includes the app environment variables for the current app
188
- # type.
189
- #
190
- # ### Parameters
191
- #
192
- # * **image_type: Symbol** The image type that we're building. This can
193
- # be `app_dependencies`, `app`, or `database`.
194
- #
195
- # ### Returns
196
- #
197
- # A String with the contents of the Dockerfile for adding the environment
198
- # variables.
199
- def include_environment_variables(image_type)
200
- result = ""
201
- @server_type.environment_variables.select { |variable| variable[:image] == image_type }.each do |variable|
202
- result += "ENV #{variable[:name]} #{instance_eval(&variable[:block])}\n"
203
- end
204
- result
205
- end
206
-
207
204
  # This method includes commands for copying script files for the hooks for
208
205
  # the current app type.
209
206
  #
210
207
  # ### Parameters
211
208
  #
209
+ #
210
+ # * **servers: Database/App/Array**: The server or servers whose hooks we
211
+ # are running.
212
212
  # * **event_types: [Symbol]** The events whose hooks we should include.
213
213
  #
214
214
  # ### Returns
215
215
  #
216
216
  # A String with the contents of the Dockerfile for copying the script.
217
- def copy_hooks(event_types)
217
+ def copy_hooks(servers, event_types)
218
218
  result = ""
219
- RubyYacht.configuration.fetch_hooks(server_type: @server_type.name).each do |hook|
220
- next if hook.copied_file_name == ''
221
- next unless event_types.include?(hook.event_type)
222
- result += "COPY #{hook.copied_file_name} /var/docker/#{hook.copied_file_name}\n"
219
+
220
+ fetch_behaviors(servers, event_types).each do |behavior|
221
+ next unless behavior.is_a?(RubyYacht::Hook::CopyFileBehavior)
222
+ result += behavior.dockerfile_command + "\n"
223
223
  end
224
224
  result
225
225
  end
226
226
 
227
- # This method goes through all the app types for the apps in the project,
228
- # sets each one as the `@server_type` instance variable, and then yields to the
229
- # block passed to the method.
230
- def with_each_app_type
231
- original_server_type = @server_type
232
- @project.apps.map(&:server_type).uniq.each do |server_type|
233
- @server_type = RubyYacht.configuration.find_server_type(server_type)
234
- yield
227
+ private
228
+
229
+ # This method fetches the behaviors for the hooks for an event.
230
+ #
231
+ #
232
+ # * **servers: Database/App/Array**: The server or servers whose hooks we
233
+ # are running.
234
+ # * **event_types: Array**: The events for the hooks we are running.
235
+ # * **event_time: Symbol**: The time relative to the event for the hooks
236
+ # we are running. If this is nil, it will
237
+ # include all event times.
238
+ def fetch_behaviors(servers, event_types, event_time = nil)
239
+ unless servers.is_a?(Array)
240
+ servers = [servers]
241
+ end
242
+ hooks = servers.collect do |server|
243
+ event_types.collect do |type|
244
+ RubyYacht.configuration.fetch_hooks(server, type)
245
+ end
246
+ end.flatten.uniq
247
+ hooks = hooks.select do |hook|
248
+ event_time.nil? || event_time == hook.event_time
235
249
  end
236
- @server_type = original_server_type
250
+ hooks.map(&:behaviors).flatten
237
251
  end
238
252
  end
239
253
  end
@@ -57,7 +57,7 @@ module RubyYacht::Runner
57
57
  return false unless project
58
58
 
59
59
  app = project.apps.find { |a| a.name == app_name.to_sym }
60
- container_name = app.container_name(project)
60
+ container_name = app.container_name
61
61
 
62
62
  docker "exec #{container_name} bash -c 'cd /var/code; git fetch; git checkout .; git checkout #{branch}; git pull'"
63
63
  docker "exec #{container_name} /var/docker/before_startup.bash"
@@ -111,7 +111,19 @@ module RubyYacht::Runner
111
111
  # ### Returns
112
112
  # The response from docker-machine.
113
113
  def get_machine_info(property)
114
- backtick("docker-machine inspect default -f {{#{property}}}").strip
114
+ return '' if docker_machine == ''
115
+ backtick("#{docker_machine} inspect default -f {{#{property}}}").strip
116
+ end
117
+
118
+ # This method gets the path to the docker-machine binary.
119
+ #
120
+ # If docker-machine is not installed or is disabled, this will be blank.
121
+ #
122
+ # ### Returns
123
+ # String
124
+ def docker_machine
125
+ return '' if RubyYacht.configuration.disable_docker_machine
126
+ backtick('which docker-machine').strip
115
127
  end
116
128
 
117
129
  # Stubbing