ey-deploy 0.2.4.pre
Sign up to get free protection for your applications and to get access to all the features.
- data/LICENSE +20 -0
- data/README.rdoc +66 -0
- data/Rakefile +63 -0
- data/TODO +4 -0
- data/bin/eysd +10 -0
- data/lib/ey-deploy.rb +16 -0
- data/lib/ey-deploy/cli.rb +58 -0
- data/lib/ey-deploy/compatibility.rb +24 -0
- data/lib/ey-deploy/configuration.rb +111 -0
- data/lib/ey-deploy/deploy.rb +158 -0
- data/lib/ey-deploy/server.rb +84 -0
- data/lib/ey-deploy/strategies/git.rb +43 -0
- data/lib/ey-deploy/task.rb +42 -0
- data/lib/ey-deploy/version.rb +3 -0
- data/lib/vendor/thor/CHANGELOG.rdoc +89 -0
- data/lib/vendor/thor/LICENSE +20 -0
- data/lib/vendor/thor/README.rdoc +297 -0
- data/lib/vendor/thor/Thorfile +69 -0
- data/lib/vendor/thor/bin/rake2thor +86 -0
- data/lib/vendor/thor/bin/thor +6 -0
- data/lib/vendor/thor/lib/thor.rb +244 -0
- data/lib/vendor/thor/lib/thor/actions.rb +275 -0
- data/lib/vendor/thor/lib/thor/actions/create_file.rb +103 -0
- data/lib/vendor/thor/lib/thor/actions/directory.rb +91 -0
- data/lib/vendor/thor/lib/thor/actions/empty_directory.rb +134 -0
- data/lib/vendor/thor/lib/thor/actions/file_manipulation.rb +223 -0
- data/lib/vendor/thor/lib/thor/actions/inject_into_file.rb +104 -0
- data/lib/vendor/thor/lib/thor/base.rb +540 -0
- data/lib/vendor/thor/lib/thor/core_ext/file_binary_read.rb +9 -0
- data/lib/vendor/thor/lib/thor/core_ext/hash_with_indifferent_access.rb +75 -0
- data/lib/vendor/thor/lib/thor/core_ext/ordered_hash.rb +100 -0
- data/lib/vendor/thor/lib/thor/error.rb +30 -0
- data/lib/vendor/thor/lib/thor/group.rb +271 -0
- data/lib/vendor/thor/lib/thor/invocation.rb +180 -0
- data/lib/vendor/thor/lib/thor/parser.rb +4 -0
- data/lib/vendor/thor/lib/thor/parser/argument.rb +67 -0
- data/lib/vendor/thor/lib/thor/parser/arguments.rb +150 -0
- data/lib/vendor/thor/lib/thor/parser/option.rb +128 -0
- data/lib/vendor/thor/lib/thor/parser/options.rb +169 -0
- data/lib/vendor/thor/lib/thor/rake_compat.rb +66 -0
- data/lib/vendor/thor/lib/thor/runner.rb +314 -0
- data/lib/vendor/thor/lib/thor/shell.rb +83 -0
- data/lib/vendor/thor/lib/thor/shell/basic.rb +239 -0
- data/lib/vendor/thor/lib/thor/shell/color.rb +108 -0
- data/lib/vendor/thor/lib/thor/task.rb +102 -0
- data/lib/vendor/thor/lib/thor/util.rb +230 -0
- data/lib/vendor/thor/lib/thor/version.rb +3 -0
- data/lib/vendor/thor/thor.gemspec +120 -0
- data/spec/ey-deploy_spec.rb +7 -0
- data/spec/spec_helper.rb +4 -0
- metadata +114 -0
data/LICENSE
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2010 Engine Yard, Inc
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.rdoc
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
== ey-deploy
|
2
|
+
|
3
|
+
We've been listening to your feedback here on the Engine Yard Cloud and we've heard that the current web deploy is not optimal. People like to see the deploy steps as they happen. not wait until the end to go through the logs to see what went wrong. It is also clear that running the full set of chef recipes every time you deploy is doing a lot of redundant work and taking a lot of time each deploy. So I say down and came up with a new deployment strategy that meets these needs and makes deploying to our cloud a much nicer experience. So today I am releasing a beta of our new git deployment strategy for you to use. This new system is 100% backwards and forwards compatible with the current web deploy. If you have a server already deployed you can start using this new system right on top of it with a few minutes of setup.
|
4
|
+
|
5
|
+
So here is the steps needed to get a new git push based deploy up and running on your cloud system. Let's assume that you have an environment called 'production' with an ip address of 123.123.123.123 and a unix user called 'deploy' with an application attached called 'railsapp'. In the instructions below please replace these items with the correct info for your own setup.
|
6
|
+
|
7
|
+
|
8
|
+
Once you have a server fully up and running, follow these steps:
|
9
|
+
|
10
|
+
1. SSH into each of the servers in your cluster, or just the single server if you have only one and run the following commands:
|
11
|
+
$ sudo gem install ey-deploy --source http://gems.engineyard.com
|
12
|
+
Successfully installed ey-deploy-0.0.7
|
13
|
+
1 gem installed
|
14
|
+
$ sudo ey-deploy-install
|
15
|
+
engineyard git hooks installed
|
16
|
+
|
17
|
+
Now back on your local machine,
|
18
|
+
|
19
|
+
cd railsapp
|
20
|
+
git remote add production deploy@123.123.123.123:/data/railsapp/shared/cached-copy
|
21
|
+
|
22
|
+
# NOTE make sure to replace 'deploy' with the username you created for this env
|
23
|
+
# NOTE also make sure to change the ip address to the address of your app master
|
24
|
+
# NOTE also make sure to replace 'railsapp' in the path with the name of your own application
|
25
|
+
|
26
|
+
If you have only one server then you can go ahead and deploy new code like this:
|
27
|
+
$ git commit -m "made some changes"
|
28
|
+
$ git push production master
|
29
|
+
|
30
|
+
If you have a cluster of servers you need to setup an ssh keypair named 'internal' for them to use to talk to each other.
|
31
|
+
|
32
|
+
$ cd ~/.ssh
|
33
|
+
$ ssh-keygen -t rsa
|
34
|
+
Generating public/private rsa key pair.
|
35
|
+
Enter file in which to save the key (/Users/ez/.ssh/id_rsa): internal
|
36
|
+
Enter passphrase (empty for no passphrase):
|
37
|
+
Enter same passphrase again:
|
38
|
+
Your identification has been saved in /Users/ez/.ssh/internal.
|
39
|
+
Your public key has been saved in /Users/ez/.ssh/foo.pub.
|
40
|
+
The key fingerprint is:
|
41
|
+
79:40:8a:18:84:ff:96:39:c7:3a:3d:f2:e9:20:a1:ea ez@ezra-zygmuntowiczs-macbook-pro.local
|
42
|
+
The key's randomart image is:
|
43
|
+
+--[ RSA 2048]----+
|
44
|
+
| oo . |
|
45
|
+
|. o . o |
|
46
|
+
| .. . . . |
|
47
|
+
| . o |
|
48
|
+
| .. + S . |
|
49
|
+
| . .* o . |
|
50
|
+
|. ...= |
|
51
|
+
|. .+.o. |
|
52
|
+
|oE =+. |
|
53
|
+
+-----------------+
|
54
|
+
|
55
|
+
Now you need to put the ssh keys in place on your servers. Run the following command once for each server in your cluster.
|
56
|
+
|
57
|
+
$ cd ~/.ssh
|
58
|
+
# do this for each server in your cluster
|
59
|
+
$ cat internal.pub | ssh deploy@server "cat >> ~/.ssh/authorized_keys && chmod 0600 ~/.ssh/authorized_keys"
|
60
|
+
$ cat internal | ssh deploy@server "cat > ~/.ssh/internal && chmod 0600 ~/.ssh/internal"
|
61
|
+
|
62
|
+
|
63
|
+
Once you have those keys in place you can start deploying to your cluster via git push. A few things to keep in mind with this new strategy. Your cluster does not run a git server, so you will still keep the canonical git repo on github or on your own git server somewhere. You can push any branch you want but you will always push to master on the far end as that is the branch that will get deployed on the server. But pushing another branch form your local repo to the remote master will work fine.
|
64
|
+
|
65
|
+
|
66
|
+
Thats it! you are now deploying with git directly to your instances. Please give this a try and give me some feedback! I'm hoping to hear from you if you use this new deploy strategy. You can reach me by responding to this post or email me at ez+git@engineyard.com.
|
data/Rakefile
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake/gempackagetask'
|
3
|
+
require 'rubygems/specification'
|
4
|
+
require 'date'
|
5
|
+
require 'spec/rake/spectask'
|
6
|
+
require File.expand_path("lib/ey-deploy/version", File.dirname(__FILE__))
|
7
|
+
|
8
|
+
GEM = "ey-deploy"
|
9
|
+
GEM_VERSION = EY::VERSION
|
10
|
+
AUTHOR = "EY Cloud Team"
|
11
|
+
EMAIL = "cloud@engineyard.com"
|
12
|
+
HOMEPAGE = "http://engineyard.com"
|
13
|
+
SUMMARY = "A gem that deploys ruby applications on EY Cloud instances"
|
14
|
+
|
15
|
+
spec = Gem::Specification.new do |s|
|
16
|
+
s.name = GEM
|
17
|
+
s.version = GEM_VERSION
|
18
|
+
s.platform = Gem::Platform::RUBY
|
19
|
+
s.has_rdoc = true
|
20
|
+
s.extra_rdoc_files = ["README.rdoc", "LICENSE", 'TODO']
|
21
|
+
s.summary = SUMMARY
|
22
|
+
s.description = s.summary
|
23
|
+
s.author = AUTHOR
|
24
|
+
s.email = EMAIL
|
25
|
+
s.homepage = HOMEPAGE
|
26
|
+
s.bindir = "bin"
|
27
|
+
s.executables = %w(eysd)
|
28
|
+
|
29
|
+
bundle = Bundler::Definition.from_gemfile('Gemfile')
|
30
|
+
bundle.dependencies.each do |dep|
|
31
|
+
next unless dep.groups.include?(:runtime)
|
32
|
+
s.add_dependency(dep.name, dep.version_requirements.to_s)
|
33
|
+
end
|
34
|
+
|
35
|
+
s.require_path = 'lib'
|
36
|
+
s.autorequire = GEM
|
37
|
+
s.files = %w(LICENSE README.rdoc Rakefile TODO) + Dir.glob("{lib,spec}/**/*")
|
38
|
+
end
|
39
|
+
|
40
|
+
task :default => :spec
|
41
|
+
|
42
|
+
desc "Run specs"
|
43
|
+
Spec::Rake::SpecTask.new do |t|
|
44
|
+
t.spec_files = FileList['spec/**/*_spec.rb']
|
45
|
+
t.spec_opts = %w(-fs --color)
|
46
|
+
end
|
47
|
+
|
48
|
+
|
49
|
+
Rake::GemPackageTask.new(spec) do |pkg|
|
50
|
+
pkg.gem_spec = spec
|
51
|
+
end
|
52
|
+
|
53
|
+
desc "install the gem locally"
|
54
|
+
task :install => [:package] do
|
55
|
+
sh %{sudo gem install pkg/#{GEM}-#{GEM_VERSION}}
|
56
|
+
end
|
57
|
+
|
58
|
+
desc "create a gemspec file"
|
59
|
+
task :make_spec do
|
60
|
+
File.open("#{GEM}.gemspec", "w") do |file|
|
61
|
+
file.puts spec.to_ruby
|
62
|
+
end
|
63
|
+
end
|
data/TODO
ADDED
data/bin/eysd
ADDED
data/lib/ey-deploy.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
$LOAD_PATH.push(File.expand_path("ey-deploy", File.dirname(__FILE__)))
|
2
|
+
|
3
|
+
require 'version'
|
4
|
+
require 'compatibility'
|
5
|
+
require 'strategies/git'
|
6
|
+
require 'task'
|
7
|
+
require 'server'
|
8
|
+
require 'deploy'
|
9
|
+
require 'cli'
|
10
|
+
require 'configuration'
|
11
|
+
|
12
|
+
module EY
|
13
|
+
def self.node
|
14
|
+
@node ||= JSON.parse(`sudo cat /etc/chef/dna.json`)
|
15
|
+
end
|
16
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
$:.unshift File.expand_path('../vendor/thor/lib', File.dirname(__FILE__))
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module EY
|
6
|
+
class CLI < Thor
|
7
|
+
method_option :migrate, :type => :string,
|
8
|
+
:desc => "Run migrations with this deploy",
|
9
|
+
:aliases => ["-m"]
|
10
|
+
|
11
|
+
method_option :branch, :type => :string,
|
12
|
+
:desc => "Branch to deploy from, defaults to master",
|
13
|
+
:aliases => ["-b"]
|
14
|
+
|
15
|
+
method_option :repo, :type => :string,
|
16
|
+
:desc => "Remote repo to deploy",
|
17
|
+
:aliases => ["-r"]
|
18
|
+
|
19
|
+
method_option :app, :type => :string,
|
20
|
+
:required => true,
|
21
|
+
:desc => "Application to deploy",
|
22
|
+
:aliases => ["-a"]
|
23
|
+
|
24
|
+
method_option :config, :type => :string,
|
25
|
+
:desc => "Additional configuration"
|
26
|
+
|
27
|
+
desc "deploy", "Deploy code from /data/<app>"
|
28
|
+
def deploy(default_task=:deploy)
|
29
|
+
EY::Deploy.run(options.merge("default_task" => default_task))
|
30
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
desc "check", "Check whether the client gem is compatible with the server gem"
|
34
|
+
def check(client_version, server_requirement)
|
35
|
+
compat = EY::Compatibility.new(client_version, server_requirement)
|
36
|
+
return if compat.compatible?
|
37
|
+
|
38
|
+
if compat.server_newer?
|
39
|
+
puts "Server library is newer than supported by the engineyard gem"
|
40
|
+
puts "Please upgrade the engineyard gem"
|
41
|
+
exit(1)
|
42
|
+
end
|
43
|
+
|
44
|
+
system("gem install ey-deploy -v '#{server_requirement}' > /dev/null 2>&1")
|
45
|
+
case $?.exitstatus
|
46
|
+
when 2
|
47
|
+
puts "Incompatible server component detected"
|
48
|
+
puts "Please contact us at http://cloud-support.engineyard.com"
|
49
|
+
exit 2
|
50
|
+
when 0
|
51
|
+
puts "Upgraded server component"
|
52
|
+
exit
|
53
|
+
else
|
54
|
+
exit 3
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module EY
|
2
|
+
class Compatibility
|
3
|
+
attr_reader :server_version, :client_version, :server_required
|
4
|
+
|
5
|
+
def initialize(client_version, server_required)
|
6
|
+
require 'rubygems'
|
7
|
+
@client_version = Gem::Version.new(client_version)
|
8
|
+
@server_required = Gem::Requirement.new(server_required)
|
9
|
+
@server_version = Gem::Version.new(EY::VERSION)
|
10
|
+
end
|
11
|
+
|
12
|
+
def server_required_version
|
13
|
+
server_required.requirements.first.last
|
14
|
+
end
|
15
|
+
|
16
|
+
def compatible?
|
17
|
+
server_required.satisfied_by?(server_version)
|
18
|
+
end
|
19
|
+
|
20
|
+
def server_newer?
|
21
|
+
server_version > server_required_version
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,111 @@
|
|
1
|
+
require 'json'
|
2
|
+
|
3
|
+
module EY
|
4
|
+
class Deploy::Configuration
|
5
|
+
DEFAULT_CONFIG = {
|
6
|
+
"migrate" => "rake db:migrate",
|
7
|
+
"branch" => "master",
|
8
|
+
"copy_exclude" => ".git",
|
9
|
+
"strategy" => "Git",
|
10
|
+
}
|
11
|
+
|
12
|
+
attr_reader :configuration
|
13
|
+
alias :c :configuration
|
14
|
+
|
15
|
+
def initialize(opts={})
|
16
|
+
config = JSON.parse(opts["config"] || "{}")
|
17
|
+
@configuration = DEFAULT_CONFIG.merge(config).merge(opts)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Delegate to the configuration objects
|
21
|
+
def method_missing(meth, *args, &blk)
|
22
|
+
c.key?(meth.to_s) ? c[meth.to_s] : super
|
23
|
+
end
|
24
|
+
def respond_to?(meth)
|
25
|
+
c.key?(meth.to_s) ? true : super
|
26
|
+
end
|
27
|
+
|
28
|
+
def repository_cache
|
29
|
+
configuration['repository_cache'] || File.join(deploy_to, "/shared/cached-copy")
|
30
|
+
end
|
31
|
+
|
32
|
+
def repo
|
33
|
+
configuration['repo'] || EY.node["applications"][app]["repository_name"]
|
34
|
+
end
|
35
|
+
|
36
|
+
def deploy_to
|
37
|
+
configuration['deploy_to'] || "/data/#{app}"
|
38
|
+
end
|
39
|
+
|
40
|
+
def migrate?
|
41
|
+
!!configuration['migrate']
|
42
|
+
end
|
43
|
+
|
44
|
+
def migration_command
|
45
|
+
configuration['migrate'] == "migrate" ? DEFAULT_CONFIG["migrate"] : configuration['migrate']
|
46
|
+
end
|
47
|
+
|
48
|
+
def user
|
49
|
+
EY.node['users'].first['username'] || 'nobody'
|
50
|
+
end
|
51
|
+
alias :group :user
|
52
|
+
|
53
|
+
def role
|
54
|
+
EY.node['instance_role']
|
55
|
+
end
|
56
|
+
|
57
|
+
def copy_exclude
|
58
|
+
@copy_exclude ||= Array(configuration.fetch("copy_exclude", []))
|
59
|
+
end
|
60
|
+
|
61
|
+
def stack
|
62
|
+
EY.node['environment']['stack']
|
63
|
+
end
|
64
|
+
|
65
|
+
def environment
|
66
|
+
EY.node['environment']['framework_env']
|
67
|
+
end
|
68
|
+
|
69
|
+
def latest_release
|
70
|
+
all_releases.last
|
71
|
+
end
|
72
|
+
|
73
|
+
def previous_release(current=latest_release)
|
74
|
+
index = all_releases.index(current)
|
75
|
+
all_releases[index-1]
|
76
|
+
end
|
77
|
+
|
78
|
+
def oldest_release
|
79
|
+
all_releases.first
|
80
|
+
end
|
81
|
+
|
82
|
+
def all_releases
|
83
|
+
Dir.glob("#{release_dir}/*").sort
|
84
|
+
end
|
85
|
+
|
86
|
+
def framework_envs
|
87
|
+
"RAILS_ENV=#{environment} RACK_ENV=#{environment} MERB_ENV=#{environment}"
|
88
|
+
end
|
89
|
+
|
90
|
+
def current_path
|
91
|
+
File.join(deploy_to, "current")
|
92
|
+
end
|
93
|
+
|
94
|
+
def shared_path
|
95
|
+
File.join(deploy_to, "shared")
|
96
|
+
end
|
97
|
+
|
98
|
+
def release_dir
|
99
|
+
File.join(deploy_to, "releases")
|
100
|
+
end
|
101
|
+
|
102
|
+
def release_path
|
103
|
+
@release_path ||= File.join(release_dir, Time.now.utc.strftime("%Y%m%d%H%M%S"))
|
104
|
+
end
|
105
|
+
|
106
|
+
def exclusions
|
107
|
+
copy_exclude.map { |e| %|--exclude="#{e}"| }.join(' ')
|
108
|
+
end
|
109
|
+
|
110
|
+
end
|
111
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
# stolen wholesale from capistrano, thanks Jamis!
|
2
|
+
require 'fileutils'
|
3
|
+
require 'json'
|
4
|
+
|
5
|
+
module EY
|
6
|
+
class DeployBase < Task
|
7
|
+
# default task
|
8
|
+
def deploy
|
9
|
+
update_repository_cache
|
10
|
+
require_custom_tasks
|
11
|
+
push_code
|
12
|
+
|
13
|
+
puts "~> Starting full deploy"
|
14
|
+
|
15
|
+
copy_repository_cache
|
16
|
+
bundle
|
17
|
+
symlink_configs
|
18
|
+
migrate
|
19
|
+
symlink
|
20
|
+
restart
|
21
|
+
cleanup
|
22
|
+
|
23
|
+
puts "~> finalizing deploy"
|
24
|
+
end
|
25
|
+
|
26
|
+
# task
|
27
|
+
def push_code
|
28
|
+
puts "~> Pushing code to all servers"
|
29
|
+
EY::Server.all.each do |server|
|
30
|
+
server.push_code
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
# task
|
35
|
+
def restart
|
36
|
+
puts "~> Restarting app servers"
|
37
|
+
roles :app_master, :app, :solo do
|
38
|
+
restart_command = case c.stack
|
39
|
+
when "nginx_unicorn"
|
40
|
+
"/etc/init.d/unicorn_#{c.app} restart"
|
41
|
+
when "nginx_mongrel"
|
42
|
+
"monit restart all -g #{c.app}"
|
43
|
+
when "nginx_passenger", "apache_passenger"
|
44
|
+
"touch #{c.latest_release}/tmp/restart.txt"
|
45
|
+
end
|
46
|
+
if restart_command
|
47
|
+
puts "~> restarting app: #{c.latest_release}"
|
48
|
+
sudo("cd #{c.current_path} && INLINEDIR=/tmp #{c.framework_envs} #{restart_command}")
|
49
|
+
end
|
50
|
+
callback(:after_restart)
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
# task
|
55
|
+
def bundle
|
56
|
+
roles :app_master, :app, :solo do
|
57
|
+
if File.exist?("#{c.latest_release}/Gemfile")
|
58
|
+
puts "~> Gemfile detected, bundling gems"
|
59
|
+
run %|cd #{c.latest_release} && bundle install|
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
# task
|
65
|
+
def cleanup
|
66
|
+
puts "~> cleaning up old releases"
|
67
|
+
sudo "ls #{c.release_dir} | head -n -3 | xargs -I{} rm -rf #{c.release_dir}/{}"
|
68
|
+
end
|
69
|
+
|
70
|
+
# task
|
71
|
+
def rollback
|
72
|
+
puts "~> rolling back to previous release"
|
73
|
+
symlink(c.previous_release)
|
74
|
+
FileUtils.rm_rf c.latest_release
|
75
|
+
puts "~> restarting with previous release"
|
76
|
+
restart
|
77
|
+
end
|
78
|
+
|
79
|
+
# task
|
80
|
+
def migrate
|
81
|
+
roles :app_master, :solo do
|
82
|
+
if c.migrate?
|
83
|
+
callback(:before_migrate)
|
84
|
+
puts "~> migrating"
|
85
|
+
cmd = "cd #{c.latest_release} && #{c.framework_envs} #{c.migration_command}"
|
86
|
+
puts "~> Migrating: #{cmd}"
|
87
|
+
run(cmd)
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# task
|
93
|
+
def copy_repository_cache
|
94
|
+
puts "~> copying to #{c.release_path}"
|
95
|
+
sudo("mkdir -p #{c.release_path} && rsync -aq #{c.exclusions} #{c.repository_cache}/* #{c.release_path}")
|
96
|
+
|
97
|
+
puts "~> ensuring proper ownership"
|
98
|
+
sudo("chown -R #{c.user}:#{c.group} #{c.deploy_to}")
|
99
|
+
end
|
100
|
+
|
101
|
+
def symlink_configs(release_to_link=c.latest_release)
|
102
|
+
puts "~> Symlinking configs"
|
103
|
+
sudo [ "chmod -R g+w #{release_to_link}",
|
104
|
+
"rm -rf #{release_to_link}/log #{release_to_link}/public/system #{release_to_link}/tmp/pids",
|
105
|
+
"mkdir -p #{release_to_link}/tmp",
|
106
|
+
"ln -nfs #{c.shared_path}/log #{release_to_link}/log",
|
107
|
+
"mkdir -p #{release_to_link}/public",
|
108
|
+
"mkdir -p #{release_to_link}/config",
|
109
|
+
"ln -nfs #{c.shared_path}/system #{release_to_link}/public/system",
|
110
|
+
"ln -nfs #{c.shared_path}/pids #{release_to_link}/tmp/pids",
|
111
|
+
"ln -nfs #{c.shared_path}/config/database.yml #{release_to_link}/config/database.yml",
|
112
|
+
"chown -R #{c.user}:#{c.group} #{release_to_link}"
|
113
|
+
].join(" && ")
|
114
|
+
end
|
115
|
+
|
116
|
+
# task
|
117
|
+
def symlink(release_to_link=c.latest_release)
|
118
|
+
callback(:before_symlink)
|
119
|
+
puts "~> symlinking code"
|
120
|
+
begin
|
121
|
+
sudo "rm -f #{c.current_path} && ln -nfs #{release_to_link} #{c.current_path} && chown -R #{c.user}:#{c.group} #{c.current_path}"
|
122
|
+
rescue => e
|
123
|
+
sudo "rm -f #{c.current_path} && ln -nfs #{c.previous_release(release_to_link)} #{c.current_path} && chown -R #{c.user}:#{c.group} #{c.current_path}"
|
124
|
+
sudo "rm -rf #{release_to_link}"
|
125
|
+
raise e
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# before_symlink
|
130
|
+
# before_restart
|
131
|
+
def callback(what)
|
132
|
+
if File.exist?("#{c.latest_release}/deploy/#{what}.rb")
|
133
|
+
Dir.chdir(c.latest_release) do
|
134
|
+
puts "~> running deploy hook: deploy/#{what}.rb"
|
135
|
+
instance_eval(IO.read("#{c.latest_release}/deploy/#{what}.rb"))
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
class Deploy < DeployBase
|
143
|
+
def self.new(opts={})
|
144
|
+
# include the correct fetch strategy
|
145
|
+
include EY::Strategies.const_get(opts.strategy)::Helpers
|
146
|
+
super
|
147
|
+
end
|
148
|
+
|
149
|
+
def self.run(opts={})
|
150
|
+
conf = EY::Deploy::Configuration.new(opts)
|
151
|
+
EY::Server.config = conf
|
152
|
+
|
153
|
+
dep = new(conf)
|
154
|
+
dep.require_custom_tasks
|
155
|
+
dep.send(opts["default_task"])
|
156
|
+
end
|
157
|
+
end
|
158
|
+
end
|