conjure 0.2.10 → 0.3.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.md +8 -0
- data/README.md +35 -76
- data/lib/conjure.rb +1 -12
- data/lib/conjure/delayed_job.rb +39 -0
- data/lib/conjure/digital_ocean/droplet.rb +5 -2
- data/lib/conjure/docker/host.rb +75 -0
- data/lib/conjure/docker/template.rb +71 -0
- data/lib/conjure/instance.rb +31 -76
- data/lib/conjure/passenger.rb +123 -0
- data/lib/conjure/postgres.rb +67 -0
- data/lib/conjure/rails_application.rb +32 -0
- data/lib/conjure/server.rb +41 -0
- data/lib/conjure/swap.rb +28 -0
- data/lib/conjure/{provision/templates → templates}/application-no-ssl.conf.erb +2 -1
- data/lib/conjure/{provision/templates → templates}/application-ssl.conf.erb +2 -1
- data/lib/conjure/version.rb +1 -1
- metadata +12 -41
- data/lib/conjure/application.rb +0 -35
- data/lib/conjure/command.rb +0 -74
- data/lib/conjure/command_target.rb +0 -25
- data/lib/conjure/config.rb +0 -44
- data/lib/conjure/data_set.rb +0 -7
- data/lib/conjure/identity.rb +0 -25
- data/lib/conjure/log.rb +0 -26
- data/lib/conjure/provider.rb +0 -26
- data/lib/conjure/provision.rb +0 -1
- data/lib/conjure/provision/docker/host.rb +0 -32
- data/lib/conjure/provision/docker/image.rb +0 -55
- data/lib/conjure/provision/docker/template.rb +0 -55
- data/lib/conjure/provision/instance.rb +0 -52
- data/lib/conjure/provision/local_docker.rb +0 -16
- data/lib/conjure/provision/passenger.rb +0 -111
- data/lib/conjure/provision/postgres.rb +0 -70
- data/lib/conjure/provision/server.rb +0 -78
- data/lib/conjure/service/cloud_server.rb +0 -112
- data/lib/conjure/service/database.rb +0 -25
- data/lib/conjure/service/database/mysql.rb +0 -69
- data/lib/conjure/service/database/postgres.rb +0 -77
- data/lib/conjure/service/digital_ocean_account.rb +0 -31
- data/lib/conjure/service/docker_host.rb +0 -259
- data/lib/conjure/service/docker_shell.rb +0 -46
- data/lib/conjure/service/forwarded_shell.rb +0 -25
- data/lib/conjure/service/rails_codebase.rb +0 -67
- data/lib/conjure/service/rails_console.rb +0 -10
- data/lib/conjure/service/rails_log_view.rb +0 -14
- data/lib/conjure/service/rails_server.rb +0 -91
- data/lib/conjure/service/rake_task.rb +0 -11
- data/lib/conjure/service/remote_file_set.rb +0 -24
- data/lib/conjure/service/remote_shell.rb +0 -73
- data/lib/conjure/service/repository_link.rb +0 -52
- data/lib/conjure/service/volume.rb +0 -28
- data/lib/conjure/target.rb +0 -19
- data/lib/conjure/view/application_view.rb +0 -42
- data/lib/conjure/view/table_view.rb +0 -38
data/History.md
CHANGED
@@ -1,3 +1,11 @@
|
|
1
|
+
### Version 0.3.0
|
2
|
+
2016-01-04
|
3
|
+
|
4
|
+
* Remove command-line app in favor of the provisioning API
|
5
|
+
* Revise API with support for updating existing Instances
|
6
|
+
* Monitor and restart background workers for deployed apps using DelayedJob
|
7
|
+
* Upgrade to Passenger base images v0.9.18
|
8
|
+
|
1
9
|
### Version 0.2.10
|
2
10
|
2015-06-24
|
3
11
|
|
data/README.md
CHANGED
@@ -4,36 +4,27 @@
|
|
4
4
|
[![Code Climate](https://codeclimate.com/github/brianauton/conjure.png)](https://codeclimate.com/github/brianauton/conjure)
|
5
5
|
[![Dependency Status](https://gemnasium.com/brianauton/conjure.png)](https://gemnasium.com/brianauton/conjure)
|
6
6
|
|
7
|
+
Conjure is a Ruby library for creating and updating cloud server instances as part of a Rails deployment workflow.
|
7
8
|
|
8
|
-
|
9
|
+
Conjure creates a cloud server instance, and uses Docker to start separate containers for the database and the web server. It sets up data volume containers for both of these service containers, so all data will be preserved if any individual containers or the server itself are restarted.
|
9
10
|
|
10
|
-
|
11
|
-
|
12
|
-
Deploying a Rails application with Conjure currently requires the
|
13
|
-
following:
|
14
|
-
|
15
|
-
* A DigitalOcean account
|
11
|
+
Conjure sets up an environment suitable for running the Rails application into which you've installed the Conjure gem, but it does not install your application. See the [capistrano-conjure](https://github.com/brianauton/capistrano-conjure) gem for an easy way to combine Conjure with deployment of your application.
|
16
12
|
|
17
|
-
|
18
|
-
servers. Generating a new keypair for this purpose is recommended.
|
13
|
+
WARNING: Conjure creates server instances and other resources using service provider accounts that you specify. In most cases this incurs service charges that will recur until you explicitly cancel them. You are responsible for all charges incurred through your use of Conjure.
|
19
14
|
|
20
|
-
|
15
|
+
WARNING: Conjure attempts to have a good security model and to treat your code and data responsibly, but this is not guaranteed. You are responsible for the security and confidentiality of the code of applications deployed with Conjure, the data handled by these applications, and your service credentials and public keys used for deployment.
|
21
16
|
|
22
|
-
|
23
|
-
Ruby to run
|
17
|
+
### Requirements
|
24
18
|
|
25
|
-
|
26
|
-
or MySQL database (any existing database.yml will be ignored)
|
19
|
+
* A DigitalOcean account (other cloud services may be supported in the future).
|
27
20
|
|
28
|
-
|
29
|
-
`origin` remote
|
21
|
+
* A public SSH key located in `~/.ssh/id_rsa.pub`. This public key will be uploaded to the instance to allow subsequent access to the server. (other methods of granting server access to developers may be supported in the future).
|
30
22
|
|
31
|
-
|
32
|
-
the project from `origin`
|
23
|
+
* A Rails app that uses Postgres as its database (other databases may be supported in the future).
|
33
24
|
|
34
25
|
### Getting Started
|
35
26
|
|
36
|
-
First, install the Conjure gem by
|
27
|
+
First, install the Conjure gem either by adding it to your Gemfile
|
37
28
|
|
38
29
|
group :development do
|
39
30
|
gem "conjure"
|
@@ -43,84 +34,52 @@ and then running `bundle`, OR by installing it directly:
|
|
43
34
|
|
44
35
|
gem install conjure
|
45
36
|
|
46
|
-
Then
|
47
|
-
`config/conjure.yml`. This should be a YAML file with the following
|
48
|
-
fields:
|
49
|
-
|
50
|
-
* `digitalocean_client_id` and `digitalocean_api_key`: These
|
51
|
-
credentials are available after logging in to your Digital Ocean
|
52
|
-
account.
|
53
|
-
|
54
|
-
* `digitalocean_region`: The geographic region for deploying new
|
55
|
-
cloud servers. If unsure, use "New York 1".
|
56
|
-
|
57
|
-
* `private_key_file` and `public_key_file` (optional): Pathnames to
|
58
|
-
local files (absolute paths, or relative to your project's
|
59
|
-
`config` directory) that contain the private and public SSH keys
|
60
|
-
to use for deployment. If these aren't specified, Conjure will try
|
61
|
-
to find identity files in `~/.ssh`.
|
62
|
-
|
63
|
-
Here's an example conjure.yml file:
|
64
|
-
|
65
|
-
digitalocean_client_id: XXXXXXXX
|
66
|
-
digitalocean_api_key: XXXXXXXX
|
67
|
-
digitalocean_region: New York 1
|
37
|
+
Then set the DIGITALOCEAN_API_TOKEN environment variable to your DigitalOcean API token. Note that you need a single token that was generated for DigitalOcean's v2 API, not a key and secret pair as were used with their older v1 API.
|
68
38
|
|
69
|
-
|
39
|
+
export DIGITALOCEAN_API_TOKEN=xxxxxxxxxxxxxxxx
|
70
40
|
|
71
|
-
|
41
|
+
Now you're ready to provision a new instance of the Rails app. Here's an example of Ruby code you could run from the Rails console or from a Rake task in your Rails app:
|
72
42
|
|
73
|
-
|
74
|
-
deployed server. Repeating the command will reuse the existing server
|
75
|
-
rather than deploying a new one. Specify a branch to deploy with
|
76
|
-
`--branch` or `-b` (default is `master`):
|
43
|
+
Conjure::Instance.create app_name: "widget_store", rails_env: "demo", ruby_version: "2.0"
|
77
44
|
|
78
|
-
|
45
|
+
### Creating a new instance
|
79
46
|
|
80
|
-
|
47
|
+
To create a new instance on a new DigitalOcean droplet, call `Conjure::Instance.create` with a list of options. The following options are required:
|
81
48
|
|
82
|
-
|
83
|
-
deploy`.
|
49
|
+
* app_name: The application name; included in the name of the DigitalOcean droplet for easy identification.
|
84
50
|
|
85
|
-
|
51
|
+
Conjure will create the instance, and then give you a summary of information about the instance (including its IP address) that you'll need in order to access the instance and deploy your application.
|
86
52
|
|
87
|
-
|
88
|
-
currently-deployed server's production database, and save it to the
|
89
|
-
local file `FILE`.
|
53
|
+
### Updating an existing instance
|
90
54
|
|
91
|
-
|
55
|
+
To update an existing instance, call `Conjure::Instance.update` with a list of options. The following options are required:
|
92
56
|
|
93
|
-
|
57
|
+
* ip_address: The IP address of the DigitalOcean droplet to update.
|
94
58
|
|
95
|
-
|
96
|
-
with a dump from the local file `FILE`. The dump should be in the same
|
97
|
-
format as that produced by the `export` command (either a Postgres or
|
98
|
-
MySQL dump according to the database type).
|
59
|
+
Updating an instance simply involves checking that all the necessary Docker containers are running, and starting any that aren't running (after building them according to the supplied options). This means that if you want to change the configuration of your Rails application's web server, you can SSH to the droplet and manually stop and remove the `passenger` container, then run an update to have it rebuilt. This will preserve all your application's data, since that is stored in volume containers. An easier method for changing the options on existing instances may be added in the future.
|
99
60
|
|
100
|
-
|
61
|
+
### Options
|
101
62
|
|
102
|
-
|
63
|
+
The following additional options are supported for both `create` and `update`:
|
103
64
|
|
104
|
-
|
105
|
-
of lines with `-n`, and use --tail to continue streaming new lines as
|
106
|
-
they are added to the log.
|
65
|
+
* max_upload_mb: The maximum size in megabytes of uploaded files that the web server should allow. Default is 20.
|
107
66
|
|
108
|
-
|
67
|
+
* rails_env: The Rails environment, e.g. "staging" or "production". Default is "staging".
|
109
68
|
|
110
|
-
|
69
|
+
* ruby_version: Valid values are "1.9", "2.0", "2.1", and "2.2" (the default).
|
111
70
|
|
112
|
-
|
71
|
+
* rubygems_version: Use this only if your application requires a specific version of RubyGems, otherwise a reasonably recent version will be used.
|
113
72
|
|
114
|
-
|
73
|
+
* ssl_hostname: Optionally configure the web server to respond to SSL connections at the given hostname. Currently this requires you to upload certificate and key files to the server after the instance is created.
|
115
74
|
|
116
|
-
|
75
|
+
* system_packages: An array of the names of any additional `apt` packages that should be installed in the Ubuntu container that runs your Rails app.
|
117
76
|
|
118
|
-
|
77
|
+
### Development
|
119
78
|
|
120
|
-
|
79
|
+
After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake spec` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment. Run `bundle exec conjure` to use the gem in this directory, ignoring other installed copies of this gem.
|
121
80
|
|
122
|
-
|
81
|
+
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
123
82
|
|
124
|
-
|
83
|
+
### Contributing
|
125
84
|
|
126
|
-
|
85
|
+
Bug reports and pull requests are welcome on GitHub at [https://github.com/brianauton/conjure](https://github.com/brianauton/conjure).
|
data/lib/conjure.rb
CHANGED
@@ -1,12 +1 @@
|
|
1
|
-
|
2
|
-
require File.join(File.dirname(__FILE__), "conjure/provider")
|
3
|
-
Dir[File.join(File.dirname(__FILE__), "conjure/**/*.rb")].each { |f| require f }
|
4
|
-
|
5
|
-
def self.config
|
6
|
-
@config ||= Config.load Dir.pwd
|
7
|
-
end
|
8
|
-
|
9
|
-
def self.identity
|
10
|
-
@identity ||= Identity.new(config)
|
11
|
-
end
|
12
|
-
end
|
1
|
+
require "conjure/instance"
|
@@ -0,0 +1,39 @@
|
|
1
|
+
module Conjure
|
2
|
+
class DelayedJob
|
3
|
+
def initialize(options)
|
4
|
+
@rails_env = options[:rails_env]
|
5
|
+
end
|
6
|
+
|
7
|
+
def apply(template)
|
8
|
+
template.add_file_data monit_rc, "/etc/monit/monitrc"
|
9
|
+
template.run "chmod 0600 /etc/monit/monitrc"
|
10
|
+
template.add_file_data monit_run, "/etc/service/monit/run"
|
11
|
+
template.run "chmod 0700 /etc/service/monit/run"
|
12
|
+
end
|
13
|
+
|
14
|
+
def system_packages
|
15
|
+
["monit"]
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
def monit_rc
|
21
|
+
command = "/usr/bin/env RAILS_ENV=#{@rails_env} /home/app/application/current/bin/delayed_job"
|
22
|
+
'set daemon 10
|
23
|
+
set logfile /var/log/monit.log
|
24
|
+
set idfile /var/lib/monit/id
|
25
|
+
set statefile /var/lib/monit/state
|
26
|
+
check process delayed_job
|
27
|
+
with pidfile /home/app/application/shared/tmp/pids/delayed_job.pid
|
28
|
+
start program = "' + command + ' start" as uid "app" and gid "app"
|
29
|
+
stop program = "' + command + ' stop" as uid "app" and gid "app"
|
30
|
+
'
|
31
|
+
end
|
32
|
+
|
33
|
+
def monit_run
|
34
|
+
'#!/bin/sh
|
35
|
+
exec /usr/bin/monit -I
|
36
|
+
'
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require "conjure/digital_ocean/account"
|
2
2
|
require "conjure/digital_ocean/key_set"
|
3
|
+
require "securerandom"
|
3
4
|
|
4
5
|
module Conjure
|
5
6
|
module DigitalOcean
|
@@ -20,9 +21,10 @@ module Conjure
|
|
20
21
|
private
|
21
22
|
|
22
23
|
def create
|
24
|
+
puts "Creating DigitalOcean droplet..."
|
23
25
|
response = account.post("droplets", {
|
24
26
|
image: @options[:image],
|
25
|
-
name: @options[:
|
27
|
+
name: "#{@options[:name_prefix]}-#{SecureRandom.hex 4}",
|
26
28
|
region: @options[:region],
|
27
29
|
size: @options[:size],
|
28
30
|
ssh_keys: [key.id],
|
@@ -39,7 +41,8 @@ module Conjure
|
|
39
41
|
end
|
40
42
|
|
41
43
|
def account
|
42
|
-
|
44
|
+
raise "Error: DIGITALOCEAN_API_TOKEN must be set." unless ENV["DIGITALOCEAN_API_TOKEN"]
|
45
|
+
@account ||= Account.new(:token => ENV["DIGITALOCEAN_API_TOKEN"])
|
43
46
|
end
|
44
47
|
|
45
48
|
def key
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module Conjure
|
2
|
+
module Docker
|
3
|
+
class Host
|
4
|
+
def initialize(server)
|
5
|
+
@server = server
|
6
|
+
end
|
7
|
+
|
8
|
+
def start(image_name, daemon_command, options = {})
|
9
|
+
container_name = options[:name]
|
10
|
+
all_options = "#{start_options options} #{image_name} #{daemon_command}"
|
11
|
+
if running? container_name
|
12
|
+
puts "Detected #{container_name} container running."
|
13
|
+
else
|
14
|
+
puts "Starting #{container_name} container..."
|
15
|
+
@server.run("docker run #{all_options}").strip
|
16
|
+
sleep 2
|
17
|
+
raise "Container failed to start" unless running? container_name
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def build(image_source_files)
|
22
|
+
Dir.mktmpdir do |dir|
|
23
|
+
image_source_files.each { |filename, data| File.write "#{dir}/#{filename}", data }
|
24
|
+
result = with_directory(dir) { |remote_dir| @server.run "docker build #{remote_dir}" }
|
25
|
+
match = result.match(/Successfully built ([0-9a-z]+)/)
|
26
|
+
raise "Failed to build Docker image, output was #{result}" unless match
|
27
|
+
match[1]
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
def running?(container_name)
|
32
|
+
running_container_names.include? container_name
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
def with_directory(local_path, &block)
|
38
|
+
local_archive = remote_archive = "/tmp/archive.tar.gz"
|
39
|
+
remote_path = "/tmp/unpacked_archive"
|
40
|
+
`cd #{local_path}; tar czf #{local_archive} *`
|
41
|
+
@server.send_file local_archive, remote_archive
|
42
|
+
@server.run "mkdir #{remote_path}; cd #{remote_path}; tar mxzf #{remote_archive}"
|
43
|
+
yield remote_path
|
44
|
+
ensure
|
45
|
+
`rm #{local_archive}`
|
46
|
+
@server.run "rm -Rf #{remote_path} #{remote_archive}"
|
47
|
+
end
|
48
|
+
|
49
|
+
def start_options(options)
|
50
|
+
[
|
51
|
+
"-d",
|
52
|
+
"--restart=always",
|
53
|
+
mapped_options("--link", options[:linked_containers]),
|
54
|
+
("--name #{options[:name]}" if options[:name]),
|
55
|
+
mapped_options("-p", options[:ports]),
|
56
|
+
listed_options("--volumes-from", options[:volume_containers]),
|
57
|
+
].flatten.compact.join(" ")
|
58
|
+
end
|
59
|
+
|
60
|
+
def listed_options(command, values)
|
61
|
+
values ||= []
|
62
|
+
values.map { |v| "#{command} #{v}" }
|
63
|
+
end
|
64
|
+
|
65
|
+
def mapped_options(command, values)
|
66
|
+
values ||= {}
|
67
|
+
values.map { |from, to| "#{command} #{from}:#{to}" }
|
68
|
+
end
|
69
|
+
|
70
|
+
def running_container_names
|
71
|
+
@server.run("docker ps --format='{{.Names}}'").split("\n").compact
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,71 @@
|
|
1
|
+
require "conjure/docker/host"
|
2
|
+
require "tmpdir"
|
3
|
+
|
4
|
+
module Conjure
|
5
|
+
module Docker
|
6
|
+
class Template
|
7
|
+
def initialize(base_image_name)
|
8
|
+
@commands = ["FROM #{base_image_name}"]
|
9
|
+
@file_data = {}
|
10
|
+
end
|
11
|
+
|
12
|
+
def add_file(filename, remote_name)
|
13
|
+
add_file_data File.read(filename), remote_name
|
14
|
+
end
|
15
|
+
|
16
|
+
def add_file_data(data, remote_name)
|
17
|
+
local_name = "file#{@file_data.length+1}"
|
18
|
+
@file_data[local_name] = data
|
19
|
+
@commands << "ADD #{local_name} #{remote_name}"
|
20
|
+
end
|
21
|
+
|
22
|
+
def run(command)
|
23
|
+
@commands << "RUN #{command}"
|
24
|
+
end
|
25
|
+
|
26
|
+
def volume(name)
|
27
|
+
@commands << "VOLUME #{name}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def source
|
31
|
+
@commands.join "\n"
|
32
|
+
end
|
33
|
+
|
34
|
+
def environment(hash)
|
35
|
+
hash.each { |key, value| @commands << "ENV #{key} #{value}" }
|
36
|
+
end
|
37
|
+
|
38
|
+
def start(container_host, command, options = {})
|
39
|
+
if container_names(options).all? { |name| container_host.running? name }
|
40
|
+
puts "Detected all #{options[:name]} containers running."
|
41
|
+
else
|
42
|
+
puts "Building #{options[:name]} base image..."
|
43
|
+
image_name = container_host.build(image_source_files)
|
44
|
+
options = options.merge(volume_options(container_host, image_name, options)) if options[:volumes]
|
45
|
+
container_host.start(image_name, command, options)
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
private
|
50
|
+
|
51
|
+
def container_names(options)
|
52
|
+
[options[:name]] + options[:volumes].to_h.keys
|
53
|
+
end
|
54
|
+
|
55
|
+
def volume_options(container_host, image_name, options)
|
56
|
+
{
|
57
|
+
volume_containers: options[:volumes].map do |name, path|
|
58
|
+
volume_template = Docker::Template.new(image_name)
|
59
|
+
volume_template.volume path
|
60
|
+
volume_template.start(container_host, "/bin/true", name: name)
|
61
|
+
name
|
62
|
+
end
|
63
|
+
}
|
64
|
+
end
|
65
|
+
|
66
|
+
def image_source_files
|
67
|
+
@file_data.merge "Dockerfile" => @commands.join("\n")
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
data/lib/conjure/instance.rb
CHANGED
@@ -1,102 +1,57 @@
|
|
1
|
+
require "conjure/docker/host"
|
2
|
+
require "conjure/rails_application"
|
3
|
+
require "conjure/server"
|
4
|
+
require "conjure/swap"
|
5
|
+
require "yaml"
|
6
|
+
|
1
7
|
module Conjure
|
2
8
|
class Instance
|
3
|
-
def initialize(options)
|
4
|
-
@
|
5
|
-
@
|
6
|
-
@rails_environment = options[:rails_environment]
|
7
|
-
@server = options[:server]
|
9
|
+
def initialize(ip_address, options)
|
10
|
+
@server = Server.new ip_address
|
11
|
+
@options = options
|
8
12
|
end
|
9
13
|
|
10
|
-
def self.
|
11
|
-
|
14
|
+
def self.create(options)
|
15
|
+
@server = Server.create server_name_prefix(options), options
|
16
|
+
new(@server.ip_address, options).tap(&:update)
|
12
17
|
end
|
13
18
|
|
14
|
-
def
|
15
|
-
|
19
|
+
def self.update(options)
|
20
|
+
ip_address = options.delete(:ip_address)
|
21
|
+
new(ip_address, options).tap(&:update)
|
16
22
|
end
|
17
23
|
|
18
|
-
def
|
19
|
-
|
24
|
+
def update
|
25
|
+
components.each(&:install)
|
20
26
|
end
|
21
27
|
|
22
28
|
def ip_address
|
23
29
|
@server.ip_address
|
24
30
|
end
|
25
31
|
|
26
|
-
def
|
27
|
-
|
28
|
-
end
|
29
|
-
|
30
|
-
def branch
|
31
|
-
@branch ||= codebase.branch
|
32
|
+
def port
|
33
|
+
2222
|
32
34
|
end
|
33
35
|
|
34
|
-
def
|
35
|
-
|
36
|
+
def user
|
37
|
+
"app"
|
36
38
|
end
|
37
39
|
|
38
|
-
def
|
39
|
-
|
40
|
-
deploy
|
40
|
+
def pending_files
|
41
|
+
components.flat_map(&:pending_files)
|
41
42
|
end
|
42
43
|
|
43
|
-
|
44
|
-
Log.info "[deploy] Deploying #{branch} to #{rails_environment}"
|
45
|
-
codebase.install
|
46
|
-
rails_server.run
|
47
|
-
Log.info "[deploy] Application deployed to #{ip_address}"
|
48
|
-
end
|
49
|
-
|
50
|
-
def codebase
|
51
|
-
@codebase ||= Service::RailsCodebase.new target, origin, @branch, rails_environment
|
52
|
-
end
|
44
|
+
private
|
53
45
|
|
54
|
-
def
|
55
|
-
|
46
|
+
def self.server_name_prefix(options)
|
47
|
+
"#{options[:app_name]}-#{options[:rails_env]}"
|
56
48
|
end
|
57
49
|
|
58
|
-
def
|
59
|
-
@
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
@server ||= Service::CloudServer.new(server_name)
|
64
|
-
end
|
65
|
-
|
66
|
-
def target
|
67
|
-
@target ||= Target.new(:machine_name => server.name)
|
68
|
-
end
|
69
|
-
|
70
|
-
def application_name
|
71
|
-
Application.new(:origin => @origin).name
|
72
|
-
end
|
73
|
-
|
74
|
-
def status
|
75
|
-
"running"
|
76
|
-
end
|
77
|
-
|
78
|
-
def name
|
79
|
-
server.name
|
80
|
-
end
|
81
|
-
|
82
|
-
class Collection
|
83
|
-
include Enumerable
|
84
|
-
|
85
|
-
def initialize(options)
|
86
|
-
@origin = options[:origin]
|
87
|
-
end
|
88
|
-
|
89
|
-
def application_name
|
90
|
-
Application.new(:origin => @origin).name
|
91
|
-
end
|
92
|
-
|
93
|
-
def each(&block)
|
94
|
-
return unless @origin
|
95
|
-
Service::CloudServer.each_with_name_prefix("#{application_name}-") do |server|
|
96
|
-
match = server.name.match(/^#{application_name}-([^-]+)(-[0-9]+)?$/)
|
97
|
-
yield Instance.new(:server => server) if match
|
98
|
-
end
|
99
|
-
end
|
50
|
+
def components
|
51
|
+
@components ||= [
|
52
|
+
Swap.new(@server),
|
53
|
+
RailsApplication.new(Docker::Host.new(@server), @options),
|
54
|
+
]
|
100
55
|
end
|
101
56
|
end
|
102
57
|
end
|