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
@@ -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