ruby_yacht 0.1.1 → 0.2.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.
- checksums.yaml +7 -0
- data/Gemfile.lock +1 -1
- data/doc/TODO.md +16 -6
- data/doc/configuration_sample.rb +8 -9
- data/lib/ruby_yacht/dsl/app.rb +29 -1
- data/lib/ruby_yacht/dsl/app_type.rb +112 -0
- data/lib/ruby_yacht/dsl/configuration.rb +163 -2
- data/lib/ruby_yacht/dsl/dsl.rb +51 -9
- data/lib/ruby_yacht/dsl/hook.rb +105 -0
- data/lib/ruby_yacht/dsl/project.rb +17 -21
- data/lib/ruby_yacht/dsl.rb +2 -0
- data/lib/ruby_yacht/images/app/Dockerfile.erb +20 -13
- data/lib/ruby_yacht/images/app/before_startup.bash.erb +8 -0
- data/lib/ruby_yacht/images/app/checkout.bash +6 -0
- data/lib/ruby_yacht/images/app/startup.bash.erb +5 -0
- data/lib/ruby_yacht/images/app-dependencies/Dockerfile.erb +23 -5
- data/lib/ruby_yacht/images/database/Dockerfile.erb +25 -11
- data/lib/ruby_yacht/images/database/checkout.bash +10 -0
- data/lib/ruby_yacht/images/database/setup.bash +15 -0
- data/lib/ruby_yacht/images/web/Dockerfile.erb +4 -3
- data/lib/ruby_yacht/plugins/rails/scripts/install_gems.rb +3 -0
- data/lib/ruby_yacht/plugins/rails/scripts/load_seeds.rb +34 -0
- data/lib/ruby_yacht/{images/app/startup.rb → plugins/rails/scripts/prepare_rails_for_launch.rb} +2 -8
- data/lib/ruby_yacht/{images/app/update_database_config.rb → plugins/rails/scripts/update_rails_config.rb} +0 -1
- data/lib/ruby_yacht/plugins/rails.rb +40 -0
- data/lib/ruby_yacht/plugins.rb +6 -0
- data/lib/ruby_yacht/runner/build_images.rb +72 -5
- data/lib/ruby_yacht/runner/checkout.rb +1 -1
- data/lib/ruby_yacht.rb +2 -1
- data/ruby_yacht.gemspec +2 -1
- data/spec/docker/Dockerfile +1 -1
- data/spec/dsl/app_spec.rb +34 -0
- data/spec/dsl/app_type_spec.rb +176 -0
- data/spec/dsl/configuration_spec.rb +161 -2
- data/spec/dsl/dsl_spec.rb +3 -3
- data/spec/dsl/hook_spec.rb +111 -0
- data/spec/dsl/project_spec.rb +19 -83
- data/spec/fixtures/app-dependencies-dockerfile-generic +21 -0
- data/spec/fixtures/app-dependencies-dockerfile-generic-with-library-install +28 -0
- data/spec/fixtures/app-dependencies-dockerfile-rails +32 -0
- data/spec/fixtures/database-dockerfile +16 -15
- data/spec/fixtures/database-dockerfile-rails +35 -0
- data/spec/fixtures/database-dockerfile-with-seed-hooks +34 -0
- data/spec/fixtures/hooks/hook1.rb +0 -0
- data/spec/fixtures/hooks/hook2.rb +0 -0
- data/spec/fixtures/mars-before-startup +4 -0
- data/spec/fixtures/mars-before-startup-rails +7 -0
- data/spec/fixtures/mars-before-startup-with-before-startup-hooks +7 -0
- data/spec/fixtures/mars-dockerfile +9 -14
- data/spec/fixtures/mars-dockerfile-rails +33 -0
- data/spec/fixtures/mars-dockerfile-with-after-checkout-hooks +30 -0
- data/spec/fixtures/mars-dockerfile-with-before-startup-hooks +29 -0
- data/spec/fixtures/mars-startup +3 -0
- data/spec/fixtures/mars-startup-rails +3 -0
- data/spec/fixtures/multi-project-web-dockerfile +0 -10
- data/spec/fixtures/web-dockerfile +0 -6
- data/spec/plugins/rails_spec.rb +198 -0
- data/spec/runner/build_images_spec.rb +181 -15
- data/spec/runner/checkout_spec.rb +2 -2
- data/spec/support/test_project.rb +16 -8
- metadata +62 -30
- data/lib/ruby_yacht/images/app/checkout.rb +0 -7
- data/lib/ruby_yacht/images/app-dependencies/install_gems.rb +0 -12
- data/lib/ruby_yacht/images/database/load_seeds.rb +0 -42
- data/lib/ruby_yacht/images/database/setup.rb +0 -19
- data/lib/ruby_yacht/images/database/setup_database.sql.erb +0 -12
- data/spec/fixtures/app-dependencies-dockerfile +0 -25
@@ -7,6 +7,8 @@ module RubyYacht
|
|
7
7
|
#
|
8
8
|
# A project is a family of apps that communicate with each other and
|
9
9
|
# share a database.
|
10
|
+
#
|
11
|
+
# You can configure this with RubyYacht::Project::DSL
|
10
12
|
class Project
|
11
13
|
# The name of the project.
|
12
14
|
attr_accessor :name
|
@@ -21,12 +23,6 @@ module RubyYacht
|
|
21
23
|
# The hostname for the repository that contains the code for the apps.
|
22
24
|
attr_accessor :repository
|
23
25
|
|
24
|
-
# The secret key that the apps should use for signing cookies.
|
25
|
-
attr_accessor :secret_key_base
|
26
|
-
|
27
|
-
# The environment that the apps should run in.
|
28
|
-
attr_accessor :rails_environment
|
29
|
-
|
30
26
|
# Whether we should check out the code on the host machine, rather than
|
31
27
|
# keeping it entirely inside the container.
|
32
28
|
attr_accessor :check_out_locally
|
@@ -59,6 +55,8 @@ module RubyYacht
|
|
59
55
|
# * *name: String* The name of the project
|
60
56
|
def initialize(name)
|
61
57
|
@name = name.to_sym
|
58
|
+
load_custom_attributes
|
59
|
+
load_app_initializers
|
62
60
|
end
|
63
61
|
|
64
62
|
add_attribute :name
|
@@ -75,27 +73,12 @@ module RubyYacht
|
|
75
73
|
# test.com
|
76
74
|
add_attribute :domain
|
77
75
|
|
78
|
-
##
|
79
|
-
# :method: secret_key_base
|
80
|
-
# You can call `secret_key_base '1234kj1234k;lj1234jklh'` to set the
|
81
|
-
# project's `secret_key_base` to `1234kj1234k;lj1234jklh`.
|
82
|
-
add_attribute :secret_key_base
|
83
|
-
|
84
76
|
##
|
85
77
|
# :method: repository
|
86
78
|
# You can call `repository 'github.com'` to set the project's `repository`
|
87
79
|
# to `github.com`
|
88
80
|
add_attribute :repository
|
89
81
|
|
90
|
-
##
|
91
|
-
# :method: rails_environment
|
92
|
-
#
|
93
|
-
# You can call `rails_environment 'staging'` to set the project's
|
94
|
-
# `rails_environment` to `staging`.
|
95
|
-
#
|
96
|
-
# The default is `development`.
|
97
|
-
add_attribute :rails_environment, 'development'
|
98
|
-
|
99
82
|
##
|
100
83
|
# :method: check_out_locally
|
101
84
|
#
|
@@ -139,6 +122,19 @@ module RubyYacht
|
|
139
122
|
add_object :dns_server, RubyYacht::DnsServer::DSL, required: false
|
140
123
|
|
141
124
|
creates_object Project
|
125
|
+
|
126
|
+
# This method loads the special DSL methods for defining apps of a certain
|
127
|
+
# type.
|
128
|
+
#
|
129
|
+
# For the app type with the name `foo`, this will create a `foo_app`
|
130
|
+
# method on the DSL that builds an app with the type `foo`.
|
131
|
+
def load_app_initializers
|
132
|
+
RubyYacht.configuration.app_types.each do |app_type|
|
133
|
+
define_singleton_method "#{app_type.name}_app" do |name, &block|
|
134
|
+
app name, app_type.name, &block
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
142
138
|
end
|
143
139
|
end
|
144
140
|
end
|
data/lib/ruby_yacht/dsl.rb
CHANGED
@@ -1,32 +1,39 @@
|
|
1
|
-
FROM <%= @project.system_prefix %>-app-dependencies
|
1
|
+
FROM <%= @project.system_prefix %>-<%= @app.app_type %>-app-dependencies
|
2
2
|
|
3
3
|
ENV DATABASE_HOST <%= @project.database.host %>
|
4
4
|
ENV DATABASE_NAME <%= @project.database.name %>
|
5
5
|
ENV DATABASE_PASSWORD <%= @project.database.password %>
|
6
6
|
ENV DATABASE_USERNAME <%= @project.database.username %>
|
7
|
-
ENV
|
8
|
-
ENV RAILS_PORT <%= @app.port %>
|
7
|
+
ENV APP_PORT <%= @app.port %>
|
9
8
|
ENV REPOSITORY_HOST <%= @project.repository %>
|
10
|
-
ENV SECRET_KEY_BASE <%= @project.secret_key_base %>
|
11
9
|
ENV SYSTEM_PREFIX <%= @project.system_prefix %>
|
10
|
+
<% app_type = RubyYacht.configuration.find_app_type(@app.app_type) %>
|
11
|
+
<% app_type.environment_variables.select { |variable| variable[:image] == :app }.each do |variable| %>
|
12
|
+
ENV <%= variable[:name] %> <%= instance_eval(&variable[:block]) %>
|
13
|
+
<% end %>
|
12
14
|
|
13
15
|
RUN rm -r /var/code
|
14
16
|
RUN mkdir -p /var/code
|
15
17
|
|
16
|
-
COPY startup.rb /var/docker/startup.rb
|
17
|
-
COPY checkout.rb /var/docker/checkout.rb
|
18
|
-
COPY update_database_config.rb /var/docker/update_database_config.rb
|
19
|
-
|
20
|
-
RUN chmod u+x /var/docker/*.rb
|
21
|
-
|
22
18
|
ENV REPOSITORY_NAME <%= @app.repository_name %>
|
19
|
+
COPY checkout.bash /var/docker/checkout.bash
|
20
|
+
RUN bash /var/docker/checkout.bash
|
21
|
+
|
22
|
+
COPY before_startup.bash /var/docker/before_startup.bash
|
23
|
+
COPY startup.bash /var/docker/startup.bash
|
24
|
+
<% RubyYacht.configuration.fetch_hooks(app_type: @app.app_type).select { |hook| hook.script_name != '' }.each do |hook| %>
|
25
|
+
<% next unless [:startup, :build_checkout].include?(hook.event_type) %>
|
26
|
+
COPY <%= hook.script_name %> /var/docker/<%= hook.script_name %>
|
27
|
+
<% end %>
|
23
28
|
|
24
|
-
RUN /var/docker
|
29
|
+
RUN chmod u+x /var/docker/*
|
25
30
|
|
26
31
|
WORKDIR /var/code
|
27
32
|
|
28
|
-
|
33
|
+
<% RubyYacht.configuration.fetch_hooks(app_type: @app.app_type, event_time: :after, event_type: :build_checkout).each do |hook| %>
|
34
|
+
RUN <%= hook.command %>
|
35
|
+
<% end %>
|
29
36
|
|
30
37
|
EXPOSE <%= @app.port %>
|
31
38
|
|
32
|
-
CMD /var/docker/startup.
|
39
|
+
CMD /var/docker/startup.bash
|
@@ -1,23 +1,41 @@
|
|
1
|
-
# This Dockerfile creates an image for installing all of the
|
1
|
+
# This Dockerfile creates an image for installing all of the dependencies
|
2
2
|
# for all of the apps.
|
3
3
|
#
|
4
4
|
# This is a slow process, so this should be kept as simple as possible so that
|
5
5
|
# it can remain unchanged.
|
6
6
|
|
7
|
-
FROM
|
7
|
+
FROM <%= @app_type.baseline_image %>
|
8
8
|
|
9
9
|
RUN mkdir -p /root/.ssh
|
10
10
|
COPY id_rsa /root/.ssh
|
11
11
|
RUN ssh-keyscan <%= @project.repository %> >> /root/.ssh/known_hosts
|
12
12
|
|
13
13
|
RUN mkdir -p /var/docker/
|
14
|
-
|
14
|
+
|
15
|
+
<% library_scripts = RubyYacht.configuration.fetch_hooks(app_type: @app_type.name, event_time: :during, event_type: :install_libraries).select { |hook| hook.script_name != '' } %>
|
16
|
+
<% library_scripts.each do |hook |%>
|
17
|
+
COPY <%= hook.script_name %> /var/docker/<%= hook.script_name %>
|
18
|
+
<% end %>
|
19
|
+
|
20
|
+
<% if library_scripts.any? %>
|
21
|
+
RUN chmod u+x /var/docker/*
|
22
|
+
<% end %>
|
15
23
|
|
16
24
|
<% @project.apps.each do |app| %>
|
17
|
-
|
25
|
+
<% next unless app.app_type == @app_type.name %>
|
26
|
+
|
27
|
+
RUN git clone git@<%= @project.repository %>:<%= app.repository_name %> /var/code/<%= app.name %>
|
28
|
+
WORKDIR /var/code/<%= app.name %>
|
29
|
+
<% RubyYacht.configuration.fetch_hooks(app_type: @app_type.name, event_time: :during, event_type: :install_libraries).each do |hook |%>
|
30
|
+
RUN <%= hook.command %>
|
31
|
+
<% end %>
|
32
|
+
<% end %>
|
33
|
+
|
34
|
+
<% if library_scripts.any? %>
|
35
|
+
RUN rm /var/docker/*
|
18
36
|
<% end %>
|
19
37
|
|
20
|
-
|
38
|
+
WORKDIR /
|
21
39
|
|
22
40
|
RUN apt-get update && apt-get upgrade -y
|
23
41
|
RUN apt-get install -y mysql-client
|
@@ -1,26 +1,40 @@
|
|
1
|
-
FROM <%= @project.system_prefix %>-app-dependencies
|
2
|
-
|
1
|
+
FROM <%= @project.system_prefix %>-<%= @app_type.name %>-app-dependencies
|
3
2
|
<% database = @project.database %>
|
4
3
|
|
5
4
|
ENV DEBIAN_FRONTEND noninteractive
|
6
5
|
RUN apt-get install -y mysql-server
|
7
6
|
|
8
|
-
|
9
|
-
|
10
|
-
|
7
|
+
ENV DATABASE_USERNAME <%= @project.database.username %>
|
8
|
+
ENV DATABASE_PASSWORD <%= @project.database.password %>
|
9
|
+
ENV DATABASE_NAME <%= @project.database.name %>
|
10
|
+
|
11
|
+
COPY setup.bash /var/docker/setup.bash
|
12
|
+
COPY checkout.bash /var/docker/checkout.bash
|
13
|
+
<% @project.apps.map(&:app_type).uniq.each do |app_type| %>
|
14
|
+
<% RubyYacht.configuration.fetch_hooks(app_type: app_type, event_type: :load_database_seeds).each do |hook| %>
|
15
|
+
COPY <%= hook.script_name %> /var/docker/<%= hook.script_name %>
|
16
|
+
<% end %>
|
17
|
+
<% end %>
|
18
|
+
|
19
|
+
RUN chmod u+x /var/docker/*
|
11
20
|
|
12
|
-
RUN
|
21
|
+
RUN /var/docker/setup.bash <%= database.name %> <%= database.username %> <%= database.password %>
|
13
22
|
|
14
|
-
<% initialized = false %>
|
15
23
|
<% @project.apps.each do |app| %>
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
24
|
+
|
25
|
+
RUN /var/docker/checkout.bash <%= @project.repository %> <%= app.name %> <%= app.repository_name %>
|
26
|
+
WORKDIR /var/code/<%= app.name %>
|
27
|
+
<% @app_type = RubyYacht.configuration.find_app_type(app.app_type) %>
|
28
|
+
<%= include_event :load_database_seeds %>
|
20
29
|
<% end %>
|
30
|
+
|
21
31
|
RUN rm -r /var/docker
|
22
32
|
RUN rm -r /var/code
|
23
33
|
|
34
|
+
ENV DATABASE_USERNAME ''
|
35
|
+
ENV DATABASE_PASSWORD ''
|
36
|
+
ENV DATABASE_NAME ''
|
37
|
+
|
24
38
|
EXPOSE 3306
|
25
39
|
|
26
40
|
CMD mysqld_safe --bind-address=0.0.0.0
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#! /bin/bash
|
2
|
+
|
3
|
+
DATABASE_NAME=$1
|
4
|
+
DATABASE_USER=$2
|
5
|
+
DATABASE_PASSWORD=$3
|
6
|
+
|
7
|
+
service mysql start;
|
8
|
+
COMMAND="CREATE USER '$DATABASE_USER'@'localhost' IDENTIFIED BY '$DATABASE_PASSWORD';";
|
9
|
+
COMMAND="$COMMAND CREATE USER '$DATABASE_USER'@'%' IDENTIFIED BY '$DATABASE_PASSWORD';";
|
10
|
+
|
11
|
+
COMMAND="$COMMAND GRANT ALL ON $DATABASE_NAME.* to '$DATABASE_USER'@'localhost';";
|
12
|
+
COMMAND="$COMMAND GRANT ALL ON $DATABASE_NAME.* to '$DATABASE_USER'@'%';";
|
13
|
+
COMMAND="$COMMAND CREATE DATABASE $DATABASE_NAME;";
|
14
|
+
|
15
|
+
mysql -uroot -e "$COMMAND";
|
@@ -13,11 +13,12 @@ COPY index_config.erb /var/docker/index_config.erb
|
|
13
13
|
COPY app_config.erb /var/docker/app_config.erb
|
14
14
|
|
15
15
|
<% @projects.each do |project| %>
|
16
|
-
|
16
|
+
|
17
|
+
<% app_list = project.apps.map(&:name).join(',') %>
|
17
18
|
RUN ruby /var/docker/add_project.rb <%= project.system_prefix %> <%= project.domain %> <%= app_list %>
|
18
|
-
|
19
|
+
<% project.apps.each do |app| %>
|
19
20
|
RUN ruby /var/docker/add_app.rb <%= project.system_prefix %> <%= project.domain %> <%= app.name %> <%= app.port %>
|
20
|
-
|
21
|
+
<% end %>
|
21
22
|
<% end %>
|
22
23
|
|
23
24
|
RUN rm -r /var/docker
|
@@ -0,0 +1,34 @@
|
|
1
|
+
#! /usr/local/bin/ruby
|
2
|
+
|
3
|
+
require 'yaml'
|
4
|
+
require 'fileutils'
|
5
|
+
|
6
|
+
puts "Loading seeds"
|
7
|
+
|
8
|
+
system "service mysql start"
|
9
|
+
|
10
|
+
config_path = "./config/database.yml"
|
11
|
+
|
12
|
+
database_config = {
|
13
|
+
'development' => {
|
14
|
+
'adapter' => 'mysql2',
|
15
|
+
'encoding' => 'utf8',
|
16
|
+
'reconnect' => true,
|
17
|
+
'username' => ENV['DATABASE_USERNAME'],
|
18
|
+
'password' => ENV['DATABASE_PASSWORD'],
|
19
|
+
'host' => 'localhost',
|
20
|
+
'database' => ENV['DATABASE_NAME']
|
21
|
+
}
|
22
|
+
}
|
23
|
+
|
24
|
+
File.open(config_path, "w") do |file|
|
25
|
+
file.write(database_config.to_yaml)
|
26
|
+
end
|
27
|
+
|
28
|
+
system "bundle install"
|
29
|
+
tables = `mysql -uroot -e "SHOW TABLES" #{ENV['DATABASE_NAME']}`
|
30
|
+
if tables == ''
|
31
|
+
system "bundle exec rake db:reset"
|
32
|
+
else
|
33
|
+
system "bundle exec rake db:migrate; bundle exec rake db:seed"
|
34
|
+
end
|
data/lib/ruby_yacht/{images/app/startup.rb → plugins/rails/scripts/prepare_rails_for_launch.rb}
RENAMED
@@ -1,17 +1,11 @@
|
|
1
1
|
#! /usr/local/bin/ruby
|
2
2
|
|
3
3
|
require 'fileutils'
|
4
|
-
require_relative 'checkout'
|
5
|
-
require_relative 'update_database_config'
|
6
|
-
|
7
|
-
FileUtils.cd '/var/code'
|
8
4
|
|
9
5
|
system "bundle install"
|
10
6
|
system "rake db:migrate"
|
11
|
-
|
12
7
|
system "rails r Rails.cache.clear"
|
8
|
+
|
13
9
|
if ENV['RAILS_ENV'] != 'development'
|
14
10
|
system "rake assets:precompile"
|
15
|
-
end
|
16
|
-
|
17
|
-
exec "rails s -b 0.0.0.0 -p $RAILS_PORT -e $RAILS_ENV"
|
11
|
+
end
|
@@ -23,7 +23,6 @@ database_config = {
|
|
23
23
|
if ENV['RAILS_ENV'] == 'development' && local_database
|
24
24
|
database_config['test'] = common_config.dup
|
25
25
|
database_config['test']['database'] += '_test'
|
26
|
-
database_config['development']['database'] += '_development'
|
27
26
|
end
|
28
27
|
|
29
28
|
File.open('/var/code/config/database.yml', 'w') do |file|
|
@@ -0,0 +1,40 @@
|
|
1
|
+
module RubyYacht::Plugins
|
2
|
+
# This module provides the plugin for managing Ruby on Rails apps.
|
3
|
+
module Rails
|
4
|
+
# This method loads the configuration for the Rails plugin.
|
5
|
+
def self.load
|
6
|
+
RubyYacht.configure do
|
7
|
+
app_type :rails do
|
8
|
+
baseline_image 'ruby:2.3'
|
9
|
+
project_attribute name: :environment, default: 'development'
|
10
|
+
project_attribute name: :secret_key_base
|
11
|
+
|
12
|
+
environment_variable :app, 'RAILS_ENV' do
|
13
|
+
@project.rails_environment
|
14
|
+
end
|
15
|
+
|
16
|
+
environment_variable :app, 'SECRET_KEY_BASE' do
|
17
|
+
@project.rails_secret_key_base
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
RubyYacht.configure do
|
23
|
+
add_hooks(app_type: :rails, folder: File.join(File.dirname(__FILE__), 'rails', 'scripts')) do
|
24
|
+
during(:install_libraries) { run_script 'install_gems.rb' }
|
25
|
+
|
26
|
+
after(:build_checkout) { command 'bundle install && bundle clean --force' }
|
27
|
+
|
28
|
+
during(:load_database_seeds) { run_script 'load_seeds.rb' }
|
29
|
+
|
30
|
+
before(:startup) { run_script 'update_rails_config.rb' }
|
31
|
+
before(:startup) { run_script 'prepare_rails_for_launch.rb' }
|
32
|
+
|
33
|
+
during(:startup) { command 'rails s -b 0.0.0.0 -p $APP_PORT -e $RAILS_ENV' }
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
RubyYacht::Plugins::Rails.load
|
@@ -28,13 +28,19 @@ module RubyYacht::Runner
|
|
28
28
|
FileUtils.cp(id_path, tmp_id_path)
|
29
29
|
end
|
30
30
|
|
31
|
-
|
31
|
+
project.apps.map(&:app_type).uniq.each do |type_name|
|
32
|
+
@app_type = RubyYacht.configuration.find_app_type(type_name)
|
33
|
+
build_image 'app-dependencies', "#{@project.system_prefix}-#{@app_type.name}-app-dependencies"
|
34
|
+
end
|
35
|
+
|
32
36
|
build_image 'database' if project.database.local?
|
33
37
|
|
34
38
|
@project.apps.each do |app|
|
35
39
|
@app = app
|
40
|
+
@app_type = RubyYacht.configuration.find_app_type(@app.app_type)
|
36
41
|
build_image 'app', "#{@project.system_prefix}-#{app.name}"
|
37
42
|
end
|
43
|
+
@app = nil
|
38
44
|
|
39
45
|
if @project.create_deploy_container
|
40
46
|
build_image 'deploy'
|
@@ -55,6 +61,10 @@ module RubyYacht::Runner
|
|
55
61
|
# current context, and write it to the Dockerfile in the tmp folder. It will
|
56
62
|
# then build the image, and clear out the tmp folder.
|
57
63
|
#
|
64
|
+
# Depending on the image type, it may also copy and interpret other template
|
65
|
+
# files. For instance, for app containers we also have erb files for the
|
66
|
+
# `startup.bash` and `before_startup.bash` scripts.
|
67
|
+
#
|
58
68
|
# ### Parameters
|
59
69
|
#
|
60
70
|
# * **folder_name: String** The name of the folder containing the
|
@@ -65,12 +75,46 @@ module RubyYacht::Runner
|
|
65
75
|
# dash, followed by the folder name.
|
66
76
|
def build_image(folder_name, image_name = nil)
|
67
77
|
Dir[File.join(File.dirname(File.dirname(__FILE__)), 'images', folder_name, '*')].each do |path|
|
68
|
-
FileUtils.cp(path, 'tmp')
|
78
|
+
FileUtils.cp(path, File.join('tmp', File.basename(path)))
|
69
79
|
end
|
80
|
+
|
81
|
+
templates =
|
82
|
+
case folder_name
|
83
|
+
when 'app' then ['Dockerfile', 'before_startup.bash', 'startup.bash']
|
84
|
+
else ['Dockerfile']
|
85
|
+
end
|
86
|
+
|
87
|
+
hook_events =
|
88
|
+
case folder_name
|
89
|
+
when 'app' then [:startup, :build_checkout]
|
90
|
+
when 'app-dependencies' then [:install_libraries]
|
91
|
+
when 'database' then [:load_database_seeds]
|
92
|
+
else []
|
93
|
+
end
|
94
|
+
|
95
|
+
app_types =
|
96
|
+
case folder_name
|
97
|
+
when 'database' then @project.apps.map(&:app_type).uniq
|
98
|
+
else [@app_type.name]
|
99
|
+
end
|
70
100
|
|
71
|
-
|
72
|
-
|
73
|
-
|
101
|
+
hook_events.each do |event|
|
102
|
+
app_types.each do |app_type|
|
103
|
+
RubyYacht.configuration.fetch_hooks(app_type: app_type, event_type: event).each do |hook|
|
104
|
+
next unless hook.script_path
|
105
|
+
FileUtils.cp hook.script_path, "tmp"
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
templates.each do |template_name|
|
111
|
+
File.open(File.join('tmp', template_name), 'w') do |file|
|
112
|
+
template_contents = File.read(File.join('tmp', template_name + '.erb'))
|
113
|
+
file_contents = ERB.new(template_contents, nil, '<>').result(binding)
|
114
|
+
file_contents.gsub!(/\n\n\n+/, "\n\n")
|
115
|
+
file_contents.gsub!(/\n*\Z/, "")
|
116
|
+
file.write(file_contents)
|
117
|
+
end
|
74
118
|
end
|
75
119
|
|
76
120
|
image_name ||= "#{@project.system_prefix}-#{folder_name}"
|
@@ -78,5 +122,28 @@ module RubyYacht::Runner
|
|
78
122
|
|
79
123
|
FileUtils.rm(Dir[File.join("tmp", "*")])
|
80
124
|
end
|
125
|
+
|
126
|
+
# This method includes the hooks for an event in a Dockerfile.
|
127
|
+
#
|
128
|
+
# It will run the commands for the before hooks, then the during hooks, then
|
129
|
+
# the after hooks.
|
130
|
+
#
|
131
|
+
# ### Parameters
|
132
|
+
#
|
133
|
+
# * **event_type: Symbol** The event whose hooks we are running.
|
134
|
+
#
|
135
|
+
# ### Returns
|
136
|
+
#
|
137
|
+
# A String with the contents of the Dockerfile for running the hooks.
|
138
|
+
def include_event(event_type)
|
139
|
+
result = ""
|
140
|
+
[:before, :during, :after].each do |time|
|
141
|
+
before_hooks = RubyYacht.configuration.fetch_hooks(app_type: @app_type.name, event_type: event_type, event_time: time).each do |hook|
|
142
|
+
result += "RUN #{hook.command}\n"
|
143
|
+
end
|
144
|
+
end
|
145
|
+
|
146
|
+
result
|
147
|
+
end
|
81
148
|
end
|
82
149
|
end
|
@@ -59,7 +59,7 @@ module RubyYacht::Runner
|
|
59
59
|
container_name = "#{project.system_prefix}-#{app}"
|
60
60
|
|
61
61
|
docker "exec #{container_name} bash -c 'cd /var/code; git fetch; git checkout .; git checkout #{branch}; git pull'"
|
62
|
-
docker "exec #{container_name}
|
62
|
+
docker "exec #{container_name} /var/docker/before_startup.bash"
|
63
63
|
docker "restart #{container_name}"
|
64
64
|
|
65
65
|
true
|
data/lib/ruby_yacht.rb
CHANGED
data/ruby_yacht.gemspec
CHANGED
@@ -1,7 +1,8 @@
|
|
1
1
|
Gem::Specification.new do |spec|
|
2
2
|
spec.name = 'ruby_yacht'
|
3
|
-
spec.version = '0.
|
3
|
+
spec.version = '0.2.0'
|
4
4
|
spec.date = '2016-04-17'
|
5
|
+
spec.description = "A DSL for building docker containers for a family of Rails apps"
|
5
6
|
spec.summary = "A DSL for building docker containers for a family of Rails apps"
|
6
7
|
spec.authors = ["John Brownlee"]
|
7
8
|
spec.email = 'apps@mail.johnbrownlee.com'
|
data/spec/docker/Dockerfile
CHANGED
data/spec/dsl/app_spec.rb
CHANGED
@@ -5,28 +5,62 @@ RSpec.describe RubyYacht::App do
|
|
5
5
|
let(:name) { :test_app }
|
6
6
|
let(:app) { RubyYacht::App::DSL.new(name).run(@builder).create_object }
|
7
7
|
|
8
|
+
before do
|
9
|
+
RubyYacht.configuration.clear
|
10
|
+
RubyYacht.configure do
|
11
|
+
app_type :test do
|
12
|
+
baseline_image 'ubuntu'
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
8
17
|
it "creates an app with all fields" do
|
9
18
|
@builder = Proc.new do
|
10
19
|
repository_name 'brownleej/test-app'
|
20
|
+
app_type :test
|
11
21
|
port 3000
|
12
22
|
end
|
13
23
|
expect(app.name).to eq :test_app
|
14
24
|
expect(app.repository_name).to eq 'brownleej/test-app'
|
25
|
+
expect(app.app_type).to eq :test
|
15
26
|
expect(app.port).to eq 3000
|
16
27
|
end
|
17
28
|
|
18
29
|
it "requires the repository name" do
|
19
30
|
@builder = Proc.new do
|
20
31
|
port 3000
|
32
|
+
app_type :test
|
21
33
|
end
|
22
34
|
expect do
|
23
35
|
self.app
|
24
36
|
end.to raise_exception("Missing required attribute repository_name for RubyYacht::App::DSL")
|
25
37
|
end
|
26
38
|
|
39
|
+
it "requires the app type" do
|
40
|
+
@builder = Proc.new do
|
41
|
+
repository_name 'brownleej/test-app'
|
42
|
+
port 3000
|
43
|
+
end
|
44
|
+
expect do
|
45
|
+
self.app
|
46
|
+
end.to raise_exception("Missing required attribute app_type for RubyYacht::App::DSL")
|
47
|
+
end
|
48
|
+
|
49
|
+
it "requires a defined app type" do
|
50
|
+
@builder = Proc.new do
|
51
|
+
app_type :invalid
|
52
|
+
repository_name 'brownleej/test-app'
|
53
|
+
port 3000
|
54
|
+
end
|
55
|
+
expect do
|
56
|
+
self.app
|
57
|
+
end.to raise_exception("App has invalid app type `invalid`")
|
58
|
+
end
|
59
|
+
|
27
60
|
it "defaults the port to 8080" do
|
28
61
|
@builder = Proc.new do
|
29
62
|
repository_name 'brownleej/test-app'
|
63
|
+
app_type :test
|
30
64
|
end
|
31
65
|
expect(app.port).to eq 8080
|
32
66
|
end
|