capistrano_two_phase_deployment 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/README.md +66 -0
- data/lib/capistrano/intermediate_host.rb +30 -0
- data/lib/capistrano/tasks/deploy.cap +6 -0
- data/lib/capistrano/tasks/intermediate_host.cap +85 -0
- metadata +63 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: b9c9945152efe930fa68bfd3a9bfd609e15a3045
|
4
|
+
data.tar.gz: 55b96b28d9cde94d9dd7bb72583cf19473175580
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 547039642f57031e4ed9c0ff809f8447dbc76b29f4f78f9cda168743275cda9b800bd3978625c705cc69a63eedab84268a08bfb13cd9e72797ab2e87933a28e7
|
7
|
+
data.tar.gz: 0c620e3e14fbc4c0f4103dbde1fc36116646a1c0cef7bf3239f1145d277419f31ef96964085f812fc687b392a708d41f4534886a5c7a9a098f5cb0a36bfb66d0
|
data/README.md
ADDED
@@ -0,0 +1,66 @@
|
|
1
|
+
# Two-Phase Deployment for Capistrano 3.1
|
2
|
+
|
3
|
+
This gem provides two-phase deployment capabilities to capistrano 3.
|
4
|
+
|
5
|
+
The deployment process is split into two phases: the first generates a
|
6
|
+
tar.gz file of the content to be deployed via ```cap deploy:prepare_release```
|
7
|
+
and uploads it to an intermediary server. This intermediary server should
|
8
|
+
ideally be located in the network infrastructure of your application servers.
|
9
|
+
|
10
|
+
In the second phase (```cap deploy```), the frontend servers pull the current
|
11
|
+
release from the intermediary server and install it locally.
|
12
|
+
|
13
|
+
This allows the servers to not require an installed SCM (e.g. git),
|
14
|
+
and saves network bandwith, because the new release is no longer transmitted
|
15
|
+
to all servers from an external source.
|
16
|
+
|
17
|
+
## Installation
|
18
|
+
Add the following to your deploy.rb file:
|
19
|
+
```
|
20
|
+
set :scm, :intermediate_host
|
21
|
+
set :intermediate_host, "host.example.com"
|
22
|
+
```
|
23
|
+
|
24
|
+
## Capistrano Directory structure on the intermediary host
|
25
|
+
These recipes will use the same capistrano directory structure on the
|
26
|
+
intermediary host as on the application servers.
|
27
|
+
|
28
|
+
The tar Archives are stored as {deploy_to}/releases/{timestamp}.tar.gz with
|
29
|
+
a {deploy_to}/current_tgz symlink pointing to the release tarfile that should
|
30
|
+
be pulled in the second phase of the deployment process. This also allows your
|
31
|
+
intermediary host to be a regular application server.
|
32
|
+
|
33
|
+
## Release directory changes from the capistrano default
|
34
|
+
Unlike the default capistrano release path name, the release path will now
|
35
|
+
consist of two timestamps:
|
36
|
+
{deploy_to}/releases/{deployment_timestamp_of_phase2}_#{timestamp_of_release_preparation}/
|
37
|
+
|
38
|
+
Using this directory name format, you can deploy the same intermediary archive
|
39
|
+
multiple times without conflicting with an existing deployment of the same
|
40
|
+
version. This can come in handy in case you generate additional files during
|
41
|
+
your deployment that are not part of the tar archive (e.g. rendering configuration
|
42
|
+
file templates, locally compiled assets during deployment etc.).
|
43
|
+
|
44
|
+
## Configuration Options
|
45
|
+
```
|
46
|
+
# Host which acts as intermediary for the deployment files
|
47
|
+
# NOTE: only the primary host is currently evaluated
|
48
|
+
role :intermediate_host, "host.example.com"
|
49
|
+
|
50
|
+
# Which format git archive should output as. See the git archive manual page.
|
51
|
+
# Defaults to tar.gz
|
52
|
+
set :archive_format, "tar.gz"
|
53
|
+
|
54
|
+
# Where to output the generated git archive locally before uploading.
|
55
|
+
# Will use Tempfile.new by default to create non-static filename.
|
56
|
+
# The tempfile will be deleted after capistrano terminates.
|
57
|
+
set :archive_output, "myfile"
|
58
|
+
|
59
|
+
# Which branch git archive should generate the tar file from.
|
60
|
+
set :branch, "production"
|
61
|
+
```
|
62
|
+
|
63
|
+
## Caveats/TODOs
|
64
|
+
* Only supports git at the moment
|
65
|
+
* Will only evaluate the primary intermediary host
|
66
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
require 'capistrano'
|
2
|
+
require 'capistrano/scm'
|
3
|
+
require 'tempfile'
|
4
|
+
|
5
|
+
class Capistrano::IntermediateHost < Capistrano::SCM
|
6
|
+
module GitStrategy
|
7
|
+
def test
|
8
|
+
test! "[ -f #{repo_path}/HEAD ]"
|
9
|
+
end
|
10
|
+
|
11
|
+
def check
|
12
|
+
end
|
13
|
+
|
14
|
+
def generate_archive
|
15
|
+
now = Time.now
|
16
|
+
format = fetch( :archive_format, "tar.gz" )
|
17
|
+
prefix = release_timestamp
|
18
|
+
output_file = fetch( :archive_output, Tempfile.new( "archive" ).path )
|
19
|
+
branch = fetch( :branch )
|
20
|
+
run_locally do
|
21
|
+
execute :git, "archive --format=#{format} --prefix=#{prefix}/ --output=#{output_file} #{branch}"
|
22
|
+
end
|
23
|
+
output_file
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
import File.join( File.dirname( __FILE__ ), 'tasks', 'intermediate_host.cap' )
|
30
|
+
import File.join( File.dirname( __FILE__ ), 'tasks', 'deploy.cap' )
|
@@ -0,0 +1,85 @@
|
|
1
|
+
namespace :intermediate_host do
|
2
|
+
def strategy
|
3
|
+
@strategy ||= Capistrano::IntermediateHost.new(self, Capistrano::IntermediateHost::GitStrategy )
|
4
|
+
end
|
5
|
+
|
6
|
+
def upload_path
|
7
|
+
@upload_path ||= "#{releases_path}/#{release_timestamp}.tar.gz"
|
8
|
+
end
|
9
|
+
|
10
|
+
def current_tgz
|
11
|
+
@current_tgz ||= deploy_path.join( "current.tar.gz" )
|
12
|
+
end
|
13
|
+
|
14
|
+
desc 'check stuff'
|
15
|
+
task :check do
|
16
|
+
strategy.check
|
17
|
+
end
|
18
|
+
|
19
|
+
desc 'Update the repo mirror to reflect the origin state'
|
20
|
+
task :update do
|
21
|
+
output_file = strategy.generate_archive
|
22
|
+
end
|
23
|
+
|
24
|
+
desc 'Upload a release to the intermediary server'
|
25
|
+
task :upload_release do
|
26
|
+
output_file = strategy.generate_archive
|
27
|
+
|
28
|
+
on primary( :intermediate_host ) do
|
29
|
+
upload! output_file, upload_path
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
desc 'Copy repo to releases host'
|
34
|
+
task :prepare_release => :upload_release do
|
35
|
+
on primary( :intermediate_host ) do
|
36
|
+
execute :rm, "-f", current_tgz
|
37
|
+
execute :ln, "-sf", upload_path, current_tgz
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def mk_tempfile_name
|
42
|
+
tempfile_template = "#{fetch( :application )}_XXXXXX"
|
43
|
+
|
44
|
+
mktemp_version_info = capture( :mktemp, "-V" )
|
45
|
+
if mktemp_version_info =~ /mktemp version 1\./
|
46
|
+
# Old CentOS/OpenBSD mktemp style
|
47
|
+
capture( :mktemp, "-p #{fetch(:deploy_to)}", tempfile_template )
|
48
|
+
else
|
49
|
+
# Otherwise, be more sane.
|
50
|
+
capture( :mktemp, "--suffix=.tar.gz", "--tmpdir=#{fetch(:deploy_to)}", tempfile_template )
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
desc 'Extract the archive timestamp from current.tar.gz on intermediary host'
|
55
|
+
task :set_release_path_based_on_archive_timestamp do
|
56
|
+
on primary( :intermediate_host ) do
|
57
|
+
archive_timestamp = capture( :tar, "tfzv", current_tgz, " | head -n 1 | awk '{print $6}'" )
|
58
|
+
|
59
|
+
deploy_timestamp = "#{release_timestamp}_#{archive_timestamp}"
|
60
|
+
|
61
|
+
set( :release_path, releases_path.join( deploy_timestamp ) )
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
desc 'Pull release from releases host'
|
66
|
+
task :update => :set_release_path_based_on_archive_timestamp do
|
67
|
+
on release_roles :all do
|
68
|
+
download_path = mk_tempfile_name
|
69
|
+
|
70
|
+
execute :scp, "#{primary( :intermediate_host )}:#{current_tgz}",
|
71
|
+
download_path
|
72
|
+
|
73
|
+
execute :mkdir, "-p", release_path
|
74
|
+
execute :tar, "xfz", download_path, "-C", release_path, "--strip-components=1"
|
75
|
+
execute :rm, "-f", download_path
|
76
|
+
end
|
77
|
+
end
|
78
|
+
|
79
|
+
desc 'Create release from pulled repo'
|
80
|
+
task :create_release => :update do
|
81
|
+
on release_roles :all do
|
82
|
+
# something
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
metadata
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano_two_phase_deployment
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Sven Riedel
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-04-05 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: capistrano
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 3.1.0
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.1.0
|
27
|
+
description: Deploy with tar files via an intermediary host
|
28
|
+
email: sr@gimp.org
|
29
|
+
executables: []
|
30
|
+
extensions: []
|
31
|
+
extra_rdoc_files:
|
32
|
+
- README.md
|
33
|
+
files:
|
34
|
+
- README.md
|
35
|
+
- lib/capistrano/intermediate_host.rb
|
36
|
+
- lib/capistrano/tasks/deploy.cap
|
37
|
+
- lib/capistrano/tasks/intermediate_host.cap
|
38
|
+
homepage: http://github.com/sriedel/capistrano_two_phase_deployment
|
39
|
+
licenses: []
|
40
|
+
metadata: {}
|
41
|
+
post_install_message:
|
42
|
+
rdoc_options:
|
43
|
+
- "--charset=UTF-8"
|
44
|
+
require_paths:
|
45
|
+
- lib
|
46
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
47
|
+
requirements:
|
48
|
+
- - ">="
|
49
|
+
- !ruby/object:Gem::Version
|
50
|
+
version: 2.0.0
|
51
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
52
|
+
requirements:
|
53
|
+
- - ">="
|
54
|
+
- !ruby/object:Gem::Version
|
55
|
+
version: '0'
|
56
|
+
requirements: []
|
57
|
+
rubyforge_project:
|
58
|
+
rubygems_version: 2.2.2
|
59
|
+
signing_key:
|
60
|
+
specification_version: 4
|
61
|
+
summary: Allows Capistrano 3 to deploy tar archives via an intermediary host; servers
|
62
|
+
no longer need to have an SCM client installed
|
63
|
+
test_files: []
|