ruby_yacht 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (82) hide show
  1. checksums.yaml +7 -0
  2. data/.codeclimate.yml +27 -0
  3. data/.gitignore +4 -0
  4. data/.rdoc_options +29 -0
  5. data/.rspec +1 -0
  6. data/.rubocop.yml +1156 -0
  7. data/.travis.yml +4 -0
  8. data/Gemfile +3 -0
  9. data/Gemfile.lock +44 -0
  10. data/LICENSE +8 -0
  11. data/README.md +216 -0
  12. data/doc/CONTRIBUTING.md +12 -0
  13. data/doc/TODO.md +28 -0
  14. data/doc/configuration_sample.rb +87 -0
  15. data/lib/ruby_yacht/dsl/app.rb +59 -0
  16. data/lib/ruby_yacht/dsl/configuration.rb +55 -0
  17. data/lib/ruby_yacht/dsl/database.rb +57 -0
  18. data/lib/ruby_yacht/dsl/dns_server.rb +38 -0
  19. data/lib/ruby_yacht/dsl/dsl.rb +252 -0
  20. data/lib/ruby_yacht/dsl/project.rb +140 -0
  21. data/lib/ruby_yacht/dsl.rb +6 -0
  22. data/lib/ruby_yacht/images/app/Dockerfile.erb +32 -0
  23. data/lib/ruby_yacht/images/app/checkout.rb +7 -0
  24. data/lib/ruby_yacht/images/app/startup.rb +17 -0
  25. data/lib/ruby_yacht/images/app/update_database_config.rb +45 -0
  26. data/lib/ruby_yacht/images/app-dependencies/Dockerfile.erb +23 -0
  27. data/lib/ruby_yacht/images/app-dependencies/install_gems.rb +12 -0
  28. data/lib/ruby_yacht/images/database/Dockerfile.erb +26 -0
  29. data/lib/ruby_yacht/images/database/load_seeds.rb +42 -0
  30. data/lib/ruby_yacht/images/database/setup.rb +19 -0
  31. data/lib/ruby_yacht/images/database/setup_database.sql.erb +12 -0
  32. data/lib/ruby_yacht/images/deploy/Dockerfile.erb +2 -0
  33. data/lib/ruby_yacht/images/web/Dockerfile.erb +25 -0
  34. data/lib/ruby_yacht/images/web/add_app.rb +12 -0
  35. data/lib/ruby_yacht/images/web/add_project.rb +14 -0
  36. data/lib/ruby_yacht/images/web/app_config.erb +11 -0
  37. data/lib/ruby_yacht/images/web/index.html.erb +10 -0
  38. data/lib/ruby_yacht/images/web/index_config.erb +12 -0
  39. data/lib/ruby_yacht/images/web/setup.rb +22 -0
  40. data/lib/ruby_yacht/runner/build.rb +21 -0
  41. data/lib/ruby_yacht/runner/build_images.rb +82 -0
  42. data/lib/ruby_yacht/runner/checkout.rb +68 -0
  43. data/lib/ruby_yacht/runner/command.rb +161 -0
  44. data/lib/ruby_yacht/runner/help.rb +55 -0
  45. data/lib/ruby_yacht/runner/implode.rb +33 -0
  46. data/lib/ruby_yacht/runner/run_containers.rb +105 -0
  47. data/lib/ruby_yacht/runner/runner.rb +42 -0
  48. data/lib/ruby_yacht/runner/services.rb +79 -0
  49. data/lib/ruby_yacht/runner/shell.rb +66 -0
  50. data/lib/ruby_yacht/runner/update_hosts.rb +72 -0
  51. data/lib/ruby_yacht/runner.rb +18 -0
  52. data/lib/ruby_yacht.rb +6 -0
  53. data/ruby_yacht.gemspec +18 -0
  54. data/spec/docker/Dockerfile +5 -0
  55. data/spec/docker/build.bash +10 -0
  56. data/spec/dsl/app_spec.rb +47 -0
  57. data/spec/dsl/configuration_spec.rb +64 -0
  58. data/spec/dsl/database_spec.rb +75 -0
  59. data/spec/dsl/dns_server_spec.rb +25 -0
  60. data/spec/dsl/dsl_spec.rb +298 -0
  61. data/spec/dsl/project_spec.rb +266 -0
  62. data/spec/fixtures/app-dependencies-dockerfile +25 -0
  63. data/spec/fixtures/database-dockerfile +31 -0
  64. data/spec/fixtures/deploy-dockerfile +2 -0
  65. data/spec/fixtures/mars-dockerfile +32 -0
  66. data/spec/fixtures/multi-project-web-dockerfile +35 -0
  67. data/spec/fixtures/web-dockerfile +27 -0
  68. data/spec/runner/build_images_spec.rb +164 -0
  69. data/spec/runner/build_spec.rb +86 -0
  70. data/spec/runner/checkout_spec.rb +128 -0
  71. data/spec/runner/command_spec.rb +94 -0
  72. data/spec/runner/help_spec.rb +73 -0
  73. data/spec/runner/implode_spec.rb +62 -0
  74. data/spec/runner/run_containers_spec.rb +141 -0
  75. data/spec/runner/runner_spec.rb +117 -0
  76. data/spec/runner/services_spec.rb +135 -0
  77. data/spec/runner/shell_spec.rb +123 -0
  78. data/spec/runner/update_hosts_spec.rb +163 -0
  79. data/spec/spec_helper.rb +10 -0
  80. data/spec/support/docker_stubbing.rb +93 -0
  81. data/spec/support/test_project.rb +56 -0
  82. metadata +193 -0
@@ -0,0 +1,12 @@
1
+ #! /usr/local/bin/ruby
2
+ require 'erb'
3
+
4
+ @project = ARGV.shift
5
+ @domain = ARGV.shift
6
+ @app = ARGV.shift
7
+ @port = ARGV.shift
8
+ @container_name = "#{@project}-#{@app}"
9
+
10
+ File.open(File.join("/etc/nginx/conf.d/#{@container_name}.conf"), 'w') do |file|
11
+ file.write(ERB.new(File.read('/var/docker/app_config.erb')).result(binding))
12
+ end
@@ -0,0 +1,14 @@
1
+ #! /usr/local/bin/ruby
2
+ require 'erb'
3
+
4
+ @project = ARGV.shift
5
+ @domain = ARGV.shift
6
+ @app_names = ARGV.shift.split(',')
7
+
8
+ File.open(File.join("/usr/share/nginx/html/#{@project}.html"), 'w') do |file|
9
+ file.write(ERB.new(File.read('/var/docker/index.html.erb')).result(binding))
10
+ end
11
+
12
+ File.open(File.join("/etc/nginx/conf.d/#{@project}-index.conf"), 'w') do |file|
13
+ file.write(ERB.new(File.read('/var/docker/index_config.erb')).result(binding))
14
+ end
@@ -0,0 +1,11 @@
1
+ server {
2
+ listen 80;
3
+ server_name <%= @app %>.<%= @domain %>;
4
+
5
+ location / {
6
+ proxy_pass http://<%= @container_name %>:<%= @port %>;
7
+ proxy_redirect off;
8
+ proxy_set_header Host $host;
9
+ proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
10
+ }
11
+ }
@@ -0,0 +1,10 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <body>
4
+ <ul>
5
+ <% @app_names.each do |name| %>
6
+ <li><a href="http://<%= name %>.<%= @domain %>/"><%= name %></li>
7
+ <% end %>
8
+ </ul>
9
+ </body>
10
+ </html>
@@ -0,0 +1,12 @@
1
+ server {
2
+ listen 80;
3
+ server_name <%= @domain %>;
4
+
5
+ #charset koi8-r;
6
+ #access_log /var/log/nginx/log/host.access.log main;
7
+
8
+ location / {
9
+ root /usr/share/nginx/html;
10
+ index <%= @project %>.html ;
11
+ }
12
+ }
@@ -0,0 +1,22 @@
1
+ #! /usr/local/bin/ruby
2
+ require 'erb'
3
+ require 'fileutils'
4
+
5
+ @project = ARGV.shift
6
+ @domain = ARGV.shift
7
+ @app_names = ARGV.shift.split(',')
8
+ @app_ports = ARGV.shift.split(',')
9
+
10
+ File.open(File.join("/usr/share/nginx/html/#{@project}.html"), 'w') do |file|
11
+ file.write(ERB.new(File.read('/var/docker/index.html.erb')).result(binding))
12
+ end
13
+
14
+ File.open(File.join("/etc/nginx/conf.d/#{@project}.conf"), 'w') do |file|
15
+ file.write(ERB.new(File.read('/var/docker/index_config.erb')).result(binding))
16
+ @app_names.each_with_index do |app, port|
17
+ @app = app
18
+ @app_port = port
19
+ @container_name = @project + '-' + @app
20
+ file.write(ERB.new(File.read('/var/docker/app_config.erb')).result(binding))
21
+ end
22
+ end
@@ -0,0 +1,21 @@
1
+ module RubyYacht::Runner
2
+ # This class provides a command for building the system.
3
+ #
4
+ # It will build the images, run the containers, and update the hosts file.
5
+ class Build < Command
6
+ # The identifier for the command.
7
+ def self.command; 'build'; end
8
+
9
+ # The description for the command.
10
+ def self.description
11
+ "Build images and run containers"
12
+ end
13
+
14
+ # This method runs the logic for this command.
15
+ def run
16
+ return BuildImages.new.run &&
17
+ RunContainers.new.run &&
18
+ UpdateHosts.new.run
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,82 @@
1
+ require 'erb'
2
+
3
+ module RubyYacht::Runner
4
+ # This command builds the images for the system.
5
+ class BuildImages < Command
6
+ # The identifier for the command.
7
+ def self.command; 'build_images'; end
8
+
9
+ # The description for the command.
10
+ def self.description
11
+ "Build images for your environment"
12
+ end
13
+
14
+ # This method runs the logic for the command.
15
+ def run
16
+ FileUtils.mkdir_p 'tmp'
17
+
18
+ default_system_prefix = projects.first.system_prefix
19
+ docker "network create #{default_system_prefix} 2> /dev/null"
20
+
21
+ projects.each do |project|
22
+ log "Building images for #{project.name}"
23
+ @project = project
24
+
25
+ id_path = File.join(ENV['HOME'], '.ssh', 'id_rsa')
26
+ tmp_id_path = File.join('tmp', 'id_rsa')
27
+ if File.exist?(id_path)
28
+ FileUtils.cp(id_path, tmp_id_path)
29
+ end
30
+
31
+ build_image 'app-dependencies'
32
+ build_image 'database' if project.database.local?
33
+
34
+ @project.apps.each do |app|
35
+ @app = app
36
+ build_image 'app', "#{@project.system_prefix}-#{app.name}"
37
+ end
38
+
39
+ if @project.create_deploy_container
40
+ build_image 'deploy'
41
+ end
42
+ end
43
+
44
+ @projects = projects
45
+ build_image 'web', "#{default_system_prefix}-web"
46
+
47
+ true
48
+ end
49
+
50
+ # This method builds an image.
51
+ #
52
+ # This will copy a Dockerfile template from a folder underneath the `images`
53
+ # folder, as well as any other files in that folder, into the tmp folder.
54
+ # It will then evaluate the Dockerfile.erb file, using the binding from the
55
+ # current context, and write it to the Dockerfile in the tmp folder. It will
56
+ # then build the image, and clear out the tmp folder.
57
+ #
58
+ # ### Parameters
59
+ #
60
+ # * **folder_name: String** The name of the folder containing the
61
+ # Dockerfile and related files.
62
+ # * **image_name: String** The name for the new image. If this is not
63
+ # provided, the image name will be the
64
+ # current project's prefix, followed by a
65
+ # dash, followed by the folder name.
66
+ def build_image(folder_name, image_name = nil)
67
+ Dir[File.join(File.dirname(File.dirname(__FILE__)), 'images', folder_name, '*')].each do |path|
68
+ FileUtils.cp(path, 'tmp')
69
+ end
70
+
71
+ File.open(File.join('tmp', 'Dockerfile'), 'w') do |file|
72
+ contents = ERB.new(File.read(File.join('tmp', 'Dockerfile.erb'))).result(binding)
73
+ file.write(contents)
74
+ end
75
+
76
+ image_name ||= "#{@project.system_prefix}-#{folder_name}"
77
+ docker "build -t #{image_name} tmp"
78
+
79
+ FileUtils.rm(Dir[File.join("tmp", "*")])
80
+ end
81
+ end
82
+ end
@@ -0,0 +1,68 @@
1
+ module RubyYacht::Runner
2
+ # This class provides a command for checking out a new branch for an app.
3
+ class Checkout < Command
4
+ # The name of the command.
5
+ def self.command; 'checkout'; end
6
+
7
+ # The short description for the command.
8
+ def self.description
9
+ "Check out a new branch for an app"
10
+ end
11
+
12
+ # The name of the project that the app is in.
13
+ attr_accessor :project_name
14
+
15
+ # The name of the app.
16
+ attr_accessor :app
17
+
18
+ # The branch that we are checking out.
19
+ attr_accessor :branch
20
+
21
+ # This OptionParser for parsing command-line flags.
22
+ #
23
+ # This command accepts the project name as an optional flag.
24
+ def option_parser
25
+ OptionParser.new do |options|
26
+ options.banner = "Usage: #{Command.short_script_name} checkout [options] [APP] [BRANCH]"
27
+ options.separator "Options:"
28
+
29
+ options.on('-p', '--project PROJECT', "The project with the app we are checking out the branch in. Default: #{default_project.name}") do |name|
30
+ self.project_name = name.to_sym
31
+ end
32
+ end
33
+ end
34
+
35
+ # This method extracts the positional arguments from the command line.
36
+ #
37
+ # This will take the app name and branch from the command line.
38
+ def parse_positional_arguments(arguments)
39
+ self.app = arguments.shift
40
+ self.branch = arguments.shift
41
+ end
42
+
43
+ # This method runs the logic for the command.
44
+ def run
45
+ if app.nil?
46
+ log "You must provide an app name"
47
+ log "Run #{Command.short_script_name} help checkout for more information"
48
+ return false
49
+ end
50
+ if branch.nil?
51
+ log "You must provide a branch"
52
+ log "Run #{Command.short_script_name} help checkout for more information"
53
+ return false
54
+ end
55
+
56
+ project = self.project_named(self.project_name)
57
+ return false unless project
58
+
59
+ container_name = "#{project.system_prefix}-#{app}"
60
+
61
+ docker "exec #{container_name} bash -c 'cd /var/code; git fetch; git checkout .; git checkout #{branch}; git pull'"
62
+ docker "exec #{container_name} bash -c '/var/docker/update_database_config.rb; rake db:migrate'"
63
+ docker "restart #{container_name}"
64
+
65
+ true
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,161 @@
1
+ require 'optparse'
2
+
3
+ module RubyYacht::Runner
4
+ # This class is the base class for the commands that users can run for
5
+ # managing their system.
6
+ class Command
7
+ # Command information
8
+
9
+ # The name of the command that users run to trigger this command.
10
+ # This implementation raises an error. Subclasses must implement it to
11
+ # provide the command name.
12
+ def self.command
13
+ raise "Command not defined for #{self}"
14
+ end
15
+
16
+ # This class gets a short description of the command.
17
+ # This implementation raises an error. Subclasses must implement it to
18
+ # provide the command description.
19
+ def self.description
20
+ raise "Description not defined for #{self}"
21
+ end
22
+
23
+ # This method gets the command-line options for invoking this script.
24
+ #
25
+ # This must return an OptionParser.
26
+ #
27
+ # The default implementation returns an OptionParser with the command name
28
+ # and description. Subclasses should implement this if they want to accept
29
+ # other command-line options.
30
+ def option_parser
31
+ OptionParser.new do |options|
32
+ options.banner = "Usage: #{Command.short_script_name} #{self.class.command}\n\n#{self.class.description}"
33
+ end
34
+ end
35
+
36
+ # This method extracts the positional arguments from the command line.
37
+ #
38
+ # This will be called after all the flags have been consumed by the
39
+ # OptionParser.
40
+ #
41
+ # The default implementation does nothing. Subclasses should implement this
42
+ # if they want to extract arguments from the command line.
43
+ #
44
+ # ### Parameters
45
+ #
46
+ # * **arguments: Array** The remaining arguments from the command line.
47
+ def parse_positional_arguments(arguments)
48
+ end
49
+
50
+ # This method runs the logic for the command.
51
+ #
52
+ # The default implementation raises an exception. Subclasses must implement
53
+ # this with their command-specific logic.
54
+ #
55
+ # ### Returns
56
+ #
57
+ # This must return a Boolean indicating whether the command succeeded or
58
+ # not.
59
+ def run
60
+ raise "Run method not defined for #{self}"
61
+ end
62
+
63
+ # Helpers
64
+
65
+ # This method gets the name of the script that was invoked to run the
66
+ # commands.
67
+ #
68
+ # This will just be the filename of the script.
69
+ def self.short_script_name
70
+ return File.basename($0)
71
+ end
72
+
73
+ # This method gets the projects that have been configured.
74
+ def projects
75
+ RubyYacht.configuration.projects
76
+ end
77
+
78
+ # The project that we will use if they do not provide one from the command
79
+ # line.
80
+ def default_project
81
+ projects.first
82
+ end
83
+
84
+ # This method finds a project by name.
85
+ #
86
+ # If the name is nil, this will use the default project. If the name is
87
+ # provided, but does not match any project, this will log an error and
88
+ # return nil.
89
+ #
90
+ # ### Parameters
91
+ #
92
+ # * **name: Symbol** The name of the project.
93
+ def project_named(name)
94
+ if self.project_name
95
+ project = projects.find { |p| p.name == name }
96
+ unless project
97
+ log "There is no project named #{name}"
98
+ end
99
+ project
100
+ else
101
+ self.default_project
102
+ end
103
+ end
104
+
105
+ # This method gets a property from the default docker machine.
106
+ #
107
+ # ### Parameters
108
+ #
109
+ # * **property: String** The docker machine property to fetch.
110
+ #
111
+ # ### Returns
112
+ # The response from docker-machine.
113
+ def get_machine_info(property)
114
+ backtick("docker-machine inspect default -f {{#{property}}}").strip
115
+ end
116
+
117
+ # Stubbing
118
+
119
+ # This method logs a message to standard out. It allows us to stub out and
120
+ # test the logging behavior of the commands.
121
+ def log(message)
122
+ $stdout.puts message
123
+ end
124
+
125
+ # This method sends a command to docker.
126
+ #
127
+ # This should start with exec, run, build, etc.
128
+ #
129
+ # This allows us to stub out and test the docker commands that get sent.
130
+ #
131
+ # ### Parameters
132
+ # * **command: String** The command to execute.
133
+ def docker(command)
134
+ system "docker #{command}"
135
+ end
136
+
137
+ # This method sends a command to the system.
138
+ #
139
+ # This is a proxy for Kernel.system that allows us to stub out and test the
140
+ # system interaction.
141
+ #
142
+ # ### Parameters
143
+ # * **command: String** The command to execute.
144
+ def system(command)
145
+ Kernel.system(command)
146
+ end
147
+
148
+ # This method runs a command using the backtick operator.
149
+ #
150
+ # This allows us to stub and and test the system interaction.
151
+ #
152
+ # ### Parameters
153
+ # * **command: String** The command to execute.
154
+ #
155
+ # ### Returns
156
+ # This returns the output from the command.
157
+ def backtick(command)
158
+ `#{command}`
159
+ end
160
+ end
161
+ end
@@ -0,0 +1,55 @@
1
+ module RubyYacht::Runner
2
+ # This command provides help information about other commands.
3
+ class Help < Command
4
+ # The name of the command.
5
+ def self.command; 'help'; end
6
+
7
+ # The short description of the command.
8
+ def self.description
9
+ "Get information on available commands"
10
+ end
11
+
12
+ # The command that we are getting help in.
13
+ attr_accessor :command
14
+
15
+ # This method gets the command-line options for the command.
16
+ def option_parser
17
+ OptionParser.new do |options|
18
+ options.banner = "Usage: #{Command.short_script_name} help [command]\n\n#{self.class.description}"
19
+ end
20
+ end
21
+
22
+ # This method extracts arguments from the command line.
23
+ #
24
+ # ### Parameters
25
+ #
26
+ # * **arguments: Array** The command line arguments.
27
+ def parse_positional_arguments(arguments)
28
+ self.command = arguments.shift
29
+ end
30
+
31
+ # This method runs the logic for the command.
32
+ def run
33
+ if self.command
34
+ RubyYacht::Runner.commands.each do |command|
35
+ if command.command == self.command
36
+ log command.new.option_parser.to_s
37
+ return true
38
+ end
39
+ end
40
+
41
+ log "Command not available: #{self.command}"
42
+ log "Run #{Command.short_script_name} help for more options"
43
+ return false
44
+ end
45
+
46
+ log "Available commands: \n\n"
47
+ RubyYacht::Runner.commands.each do |command|
48
+ log "#{command.name}: #{command.description}"
49
+ end
50
+
51
+ log "\nRun #{Command.short_script_name} help [command] for more information on a command"
52
+ true
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,33 @@
1
+ module RubyYacht::Runner
2
+ # This class provides a command for destroying the local docker environment.
3
+ class Implode < Command
4
+ # The name of the command.
5
+ def self.command; 'implode'; end
6
+
7
+ # The description of the command.
8
+ def self.description
9
+ "Destroy your local environment"
10
+ end
11
+
12
+ # This method runs the logic of the command.
13
+ def run
14
+ projects.each do |project|
15
+ system_prefix = project.system_prefix
16
+
17
+ machines = backtick("docker ps -a | grep #{system_prefix}").split("\n").map { |line| line.split(/\s+/)[0] }
18
+ machines.each do |machine|
19
+ docker "rm -f #{machine}"
20
+ end
21
+
22
+ images = backtick("docker images | grep #{system_prefix}").split("\n").map { |line| line.split(/\s+/)[0] }
23
+ images.each do |image|
24
+ docker "rmi #{image}"
25
+ end
26
+ end
27
+
28
+ backtick("docker images -q --filter dangling=true").split("\n").each do |image|
29
+ docker "rmi #{image}"
30
+ end
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,105 @@
1
+ module RubyYacht::Runner
2
+ # This class provides a command for running all the images in new containers.
3
+ #
4
+ # It will also remove any existing containers with conflicting names.
5
+ class RunContainers < Command
6
+ # THe name of the command.
7
+ def self.command; 'run_containers'; end
8
+
9
+ # The short description of the command.
10
+ def self.description; 'Runs containers for all the apps'; end
11
+
12
+ # This method runs the logic of the command.
13
+ def run
14
+ @network = projects.first.system_prefix
15
+
16
+ projects.each do |project|
17
+ @project = project
18
+ if @project.check_out_locally
19
+ FileUtils.mkdir_p File.join(ENV["PWD"], '..', 'code')
20
+ end
21
+
22
+ if project.database.local?
23
+ run_container :database
24
+ end
25
+
26
+ project.apps.each do |app|
27
+ run_container app.name
28
+ end
29
+
30
+ if @project.create_deploy_container
31
+ run_container :deploy
32
+ end
33
+ end
34
+
35
+ @project = projects.first
36
+
37
+ run_container :web
38
+
39
+ true
40
+ end
41
+
42
+ # This method gets the flags for defining DNS server config when running
43
+ # a container.
44
+ def dns_server_flags
45
+ flags = []
46
+ if @project.dns_server
47
+ flags += @project.dns_server.servers.map { |server| "--dns=#{server}" }
48
+ flags += @project.dns_server.search_domains.map { |domain| "--dns-search=#{domain}" }
49
+ end
50
+ flags
51
+ end
52
+
53
+ # This method gets the flags for mapping the code volume to a local path for
54
+ # a container.
55
+ #
56
+ # ### Parameters
57
+ #
58
+ # * **container_name: Symbol** The name of the container, not including
59
+ # the system prefix.
60
+ def volume_flags(container_name)
61
+ if @project.check_out_locally && ![:database, :web].include?(container_name)
62
+ if container_name == :deploy
63
+ return ["-v $PWD/../code:/var/code"]
64
+ else
65
+ return ["-v $PWD/../code/#{container_name}:/var/code"]
66
+ end
67
+ else
68
+ return []
69
+ end
70
+ end
71
+
72
+ # This method runs a container.
73
+ #
74
+ # It will also remove any existing containers with conflicting names.
75
+ #
76
+ # ### Parameters
77
+ #
78
+ # * **name: Symbol** The name of the container, not including the system
79
+ # prefix.
80
+ def run_container(name)
81
+ container_name = "#{@project.system_prefix}-#{name}"
82
+ remove_container container_name
83
+
84
+ flags = ["-d"]
85
+ flags += dns_server_flags
86
+ flags += volume_flags(name)
87
+ flags << "-it" if name == :deploy
88
+ flags << "-p 80:80" if name == :web
89
+ flags << "--net=#{@network}"
90
+ flags << "--net-alias=#{container_name}"
91
+
92
+ flag_text = flags.join(' ')
93
+ docker "run #{flag_text} --name=#{container_name} #{container_name}"
94
+ end
95
+
96
+ # This method removes a container.
97
+ #
98
+ # ### Parameters
99
+ #
100
+ # * **container_name: String** The full name of the container.
101
+ def remove_container(container_name)
102
+ IO.popen("docker rm -f #{container_name}", err: :close) {}
103
+ end
104
+ end
105
+ end
@@ -0,0 +1,42 @@
1
+ module RubyYacht::Runner
2
+ # This method provides the commands that we can run.
3
+ def self.commands
4
+ [Help, Build, BuildImages, RunContainers, Services, Checkout, Shell, UpdateHosts, Implode]
5
+ end
6
+
7
+ # This method gets the arguments for the current command.
8
+ def self.arguments
9
+ ARGV
10
+ end
11
+
12
+ # This method runs a command based on the command line arguments.
13
+ def self.run
14
+ arg = arguments[0]
15
+
16
+ if arg == '' || arg == nil
17
+ puts "You must provide a command to run"
18
+ puts "Run `#{$0} help` for more information"
19
+ exit(1)
20
+ return
21
+ end
22
+
23
+ command = self.commands.find { |c| c.command == arg }
24
+ if command
25
+ command_arguments = arguments
26
+ command_arguments.shift
27
+
28
+ instance = command.new
29
+ instance.option_parser.parse! command_arguments
30
+ instance.parse_positional_arguments command_arguments
31
+
32
+ success = instance.run
33
+ unless success
34
+ exit(1)
35
+ end
36
+ else
37
+ puts "Command not recognized: #{arg}"
38
+ puts "Run `#{$0} help` for more information"
39
+ exit(1)
40
+ end
41
+ end
42
+ end