capistrano-former03 0.0.1
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/.gitignore +18 -0
- data/Gemfile +4 -0
- data/LICENSE.txt +22 -0
- data/README.md +144 -0
- data/Rakefile +8 -0
- data/capistrano-former03.gemspec +27 -0
- data/lib/capistrano/former03/deploy_command.rb +131 -0
- data/lib/capistrano/former03/rsync.rb +119 -0
- data/lib/capistrano/former03/symlink.rb +35 -0
- data/lib/capistrano/former03/version.rb +5 -0
- data/lib/capistrano/former03.rb +10 -0
- data/lib/capistrano/tasks/former03.rake +261 -0
- data/share/build_rsync.sh +27 -0
- data/share/busybox/busybox_x32 +0 -0
- data/share/busybox/busybox_x64 +0 -0
- data/share/rsync/rsync_x32 +0 -0
- data/share/rsync/rsync_x64 +0 -0
- data/spec/helpers.rb +21 -0
- data/spec/spec_helper.rb +24 -0
- data/spec/tasks/local_spec.rb +12 -0
- metadata +137 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 6f93a0a9ae8a6fe227953f82f4337b97ca0729f6
|
4
|
+
data.tar.gz: c65970a378ae6ddfc6b3044900a0de7041dbe995
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 99d652793b3b066e9c241b069af58c26b194fc88100bceaddeb6ffb187a29a4cf6b2a7706e629d6c5c955a64b33c735e6f3814f97da4d747417d18dcdfffdf97
|
7
|
+
data.tar.gz: 51f44aa275d514356a5485bc7e8a84f55f8d95c440def98e1da79b9354cea2bcdbea5b6059d550a77e04d50f9ce351674ecc5dcf06d60a4e974d74f4b9d61c1e
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2014 linyows
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
Capistrano extensions for FORMER 03
|
2
|
+
=====================
|
3
|
+
|
4
|
+
Adds Features for Capistrano that are needed for FORMER 03's deployment
|
5
|
+
|
6
|
+
Implemented features:
|
7
|
+
--------------
|
8
|
+
|
9
|
+
- Local git checkout should be deployed via rsync (to save bandwidth/time)
|
10
|
+
-- saves bandwitdh and time
|
11
|
+
-- be independent of git on remote hosts
|
12
|
+
-- execute pre deployment tasks on controlled environment (e.g. sass compilation)
|
13
|
+
- Support of git submodules
|
14
|
+
- Support of destinations server without public key authentication
|
15
|
+
- Deploy own static compiled versions of busybox and rsync if configured / needed
|
16
|
+
- Relative symlinking (often needed if ssh or webapp is chrooted)
|
17
|
+
- Current directory is no symlink (some hosting provider don't support wwwroot symlinked)
|
18
|
+
|
19
|
+
(Planned) features:
|
20
|
+
--------------
|
21
|
+
|
22
|
+
|
23
|
+
[][gem]
|
24
|
+
|
25
|
+
[capistrano]: https://github.com/capistrano/capistrano
|
26
|
+
[gem]: https://rubygems.org/gems/capistrano-former03
|
27
|
+
|
28
|
+
Requirements
|
29
|
+
------------
|
30
|
+
|
31
|
+
- Ruby >= 2.0
|
32
|
+
- Capistrano == 3.2.1
|
33
|
+
- Rsync >= 2.6
|
34
|
+
|
35
|
+
Installation
|
36
|
+
------------
|
37
|
+
|
38
|
+
Add this line to your application's Gemfile:
|
39
|
+
|
40
|
+
```ruby
|
41
|
+
gem 'capistrano-former03'
|
42
|
+
```
|
43
|
+
|
44
|
+
And then execute:
|
45
|
+
|
46
|
+
```sh
|
47
|
+
$ bundle
|
48
|
+
```
|
49
|
+
|
50
|
+
Or install it yourself as:
|
51
|
+
|
52
|
+
```sh
|
53
|
+
$ gem install capistrano-former03
|
54
|
+
```
|
55
|
+
|
56
|
+
Usage
|
57
|
+
-----
|
58
|
+
|
59
|
+
Capfile:
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
require 'capistrano/former03'
|
63
|
+
```
|
64
|
+
|
65
|
+
deploy as usual
|
66
|
+
|
67
|
+
```sh
|
68
|
+
$ cap deploy
|
69
|
+
```
|
70
|
+
|
71
|
+
Options
|
72
|
+
-------
|
73
|
+
|
74
|
+
Set capistrano variables with `set name, value`.
|
75
|
+
|
76
|
+
Name | Default | Description
|
77
|
+
------------- | -------- | ------------
|
78
|
+
local_stage | tmp/deploy | local stage path
|
79
|
+
remote_stage | shared/deploy | remote stage path
|
80
|
+
remote_bin | shared/deploy_bin | remote bin path
|
81
|
+
rsync_options | --archive --delete | rsync options
|
82
|
+
deploy_busybox_bin | false | deploy a static version of busybox
|
83
|
+
deploy_rsync_bin | nil (Autodetect) | deploy a static version of rsync
|
84
|
+
relative_symlinks | true | create all symlinks with relative
|
85
|
+
current_path_real_dir | false | move actual release to current_path to have a real directory instead of symlink
|
86
|
+
|
87
|
+
Overview
|
88
|
+
--------
|
89
|
+
|
90
|
+
### local machine
|
91
|
+
|
92
|
+
```log
|
93
|
+
~/your_project
|
94
|
+
.
|
95
|
+
|-- app
|
96
|
+
|-- config
|
97
|
+
|-- lib
|
98
|
+
|-- ...
|
99
|
+
|-- ...
|
100
|
+
`-- tmp
|
101
|
+
`-- deploy (rsync src ==>)
|
102
|
+
```
|
103
|
+
|
104
|
+
### deployment hosts
|
105
|
+
|
106
|
+
```log
|
107
|
+
/var/www/your_project
|
108
|
+
.
|
109
|
+
|-- current -> /var/www/your_project/releases/20140219074628
|
110
|
+
|-- releases
|
111
|
+
| |-- 20140219062041
|
112
|
+
| |-- 20140219063022
|
113
|
+
| `-- 20140219074628
|
114
|
+
|-- revisions.log
|
115
|
+
`-- shared
|
116
|
+
|-- vendor
|
117
|
+
|-- deploy (==> rsync dest)
|
118
|
+
|-- deploy_bin (==> static binaries)
|
119
|
+
`-- log
|
120
|
+
```
|
121
|
+
|
122
|
+
Contributing
|
123
|
+
------------
|
124
|
+
|
125
|
+
1. Fork it ( http://github.com/linyows/capistrano-withrsync/fork )
|
126
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
127
|
+
3. Commit your changes (`git commit -am 'Add some feature'`)
|
128
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
129
|
+
5. Create new Pull Request
|
130
|
+
|
131
|
+
|
132
|
+
Author
|
133
|
+
------
|
134
|
+
|
135
|
+
- [linyows][linyows] (Author of capistrano-withrsync)
|
136
|
+
- [simonswine][simonswine]
|
137
|
+
|
138
|
+
[linyows]: https://github.com/linyows
|
139
|
+
[simonswine]: https://github.com/linyows
|
140
|
+
|
141
|
+
License
|
142
|
+
-------
|
143
|
+
|
144
|
+
The MIT License (MIT)
|
data/Rakefile
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'capistrano/former03/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "capistrano-former03"
|
8
|
+
spec.version = Capistrano::Former03::VERSION
|
9
|
+
spec.authors = ["Christian Simon"]
|
10
|
+
spec.email = ["simon@swine.de"]
|
11
|
+
spec.summary = %q{Capistrano with extensions for FORMER 03}
|
12
|
+
spec.description = %q{Capistrano with extensions for FORMER 03}
|
13
|
+
spec.homepage = "https://github.com/former03/capistrano-former03"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files -z`.split("\x0")
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "capistrano", "= 3.2.1"
|
22
|
+
|
23
|
+
spec.add_development_dependency "bundler"
|
24
|
+
spec.add_development_dependency "rake"
|
25
|
+
spec.add_development_dependency "capistrano-spec"
|
26
|
+
spec.add_development_dependency "rspec", ">= 2.5.0"
|
27
|
+
end
|
@@ -0,0 +1,131 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module Former03
|
3
|
+
class DeployCommand
|
4
|
+
|
5
|
+
def initialize(opts={})
|
6
|
+
|
7
|
+
# test for required flags
|
8
|
+
required_flags = [:command, :deploy_flag ,:test_cmd, :required]
|
9
|
+
required_flags.each do |flag|
|
10
|
+
if not opts.has_key?(flag)
|
11
|
+
raise "Required arg '#{flag}' not given"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# copy opts as instance vars
|
16
|
+
opts.each do |k,v|
|
17
|
+
instance_variable_set("@#{k}", v)
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def dest_path
|
22
|
+
File.join(fetch(:remote_bin_path), @command)
|
23
|
+
end
|
24
|
+
|
25
|
+
def dest_src(arch='x64')
|
26
|
+
File.expand_path(File.join(
|
27
|
+
File.expand_path(File.dirname(__FILE__)),
|
28
|
+
"../../../share/#{@command}/#{@command}_#{arch}"
|
29
|
+
))
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_run_path
|
33
|
+
@ssh.test(@command, *@test_cmd)
|
34
|
+
end
|
35
|
+
|
36
|
+
def test_run_absolute
|
37
|
+
@ssh.test(dest_path, *@test_cmd)
|
38
|
+
end
|
39
|
+
|
40
|
+
def upload(src)
|
41
|
+
@ssh.upload! src, dest_path
|
42
|
+
@ssh.execute :chmod, '+x', dest_path
|
43
|
+
if test_run_absolute
|
44
|
+
if not @install_cmd.nil?
|
45
|
+
if @ssh.test(dest_path, *@install_cmd)
|
46
|
+
return true
|
47
|
+
else
|
48
|
+
return false
|
49
|
+
end
|
50
|
+
else
|
51
|
+
return true
|
52
|
+
end
|
53
|
+
else
|
54
|
+
return false
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
def add_env_path
|
59
|
+
#TODO do host local env setting
|
60
|
+
env = SSHKit.config.default_env
|
61
|
+
bin_path = fetch(:remote_bin_path).to_s
|
62
|
+
if env.has_key? (:path)
|
63
|
+
split = env[:path].split(':')
|
64
|
+
if not split.include?(bin_path)
|
65
|
+
split = [bin_path] + split
|
66
|
+
end
|
67
|
+
env[:path] = split.join(':')
|
68
|
+
else
|
69
|
+
env[:path] = "#{bin_path}:$PATH"
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
|
74
|
+
def deploy_succeed
|
75
|
+
add_env_path
|
76
|
+
@ssh.host.properties.set "deploy_#{@command.to_sym}_path".to_sym, dest_path
|
77
|
+
return true
|
78
|
+
end
|
79
|
+
|
80
|
+
def deploy_run
|
81
|
+
# Deploy own binary if it doesn't already exist
|
82
|
+
return deploy_succeed if test_run_absolute
|
83
|
+
|
84
|
+
# Upload x64 binary
|
85
|
+
upload(dest_src('x64'))
|
86
|
+
return deploy_succeed if test_run_absolute
|
87
|
+
|
88
|
+
# Upload x32 binary
|
89
|
+
upload(dest_src('x32'))
|
90
|
+
return deploy_succeed if test_run_absolute
|
91
|
+
|
92
|
+
# Fail if arrive here
|
93
|
+
fail_missing
|
94
|
+
|
95
|
+
end
|
96
|
+
|
97
|
+
def fail_missing
|
98
|
+
fail "No usable '#{@command}' command found"
|
99
|
+
end
|
100
|
+
|
101
|
+
|
102
|
+
def deploy(ssh)
|
103
|
+
|
104
|
+
# receive ssh handle
|
105
|
+
@ssh = ssh
|
106
|
+
@deploy = fetch(@deploy_flag)
|
107
|
+
# deploy states
|
108
|
+
if @deploy == true
|
109
|
+
return deploy_run
|
110
|
+
elsif @deploy.nil?
|
111
|
+
if test_run_path
|
112
|
+
return false
|
113
|
+
else
|
114
|
+
return deploy_run
|
115
|
+
end
|
116
|
+
else
|
117
|
+
if @required
|
118
|
+
if test_run_path
|
119
|
+
return false
|
120
|
+
else
|
121
|
+
fail_missing
|
122
|
+
end
|
123
|
+
else
|
124
|
+
return false
|
125
|
+
end
|
126
|
+
end
|
127
|
+
|
128
|
+
end
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module Former03
|
3
|
+
class Rsync
|
4
|
+
def self.build_path(path,type)
|
5
|
+
return_path = ""
|
6
|
+
|
7
|
+
if not type.nil?
|
8
|
+
user = "#{type.user}@" unless type.user.nil?
|
9
|
+
return_path += "#{user}#{type.hostname}:"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Ensure path ends with slash
|
13
|
+
return_path += path.to_s
|
14
|
+
return_path << '/' unless return_path.end_with?('/')
|
15
|
+
|
16
|
+
return_path
|
17
|
+
end
|
18
|
+
|
19
|
+
def initialize(opts={})
|
20
|
+
|
21
|
+
# test for required flags
|
22
|
+
required_flags = [:src_path, :dest_path]
|
23
|
+
required_flags.each do |flag|
|
24
|
+
if not opts.has_key?(flag)
|
25
|
+
raise "Required arg '#{flag}' not given"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
if not opts[:src_type].nil? and not opts[:dest_type].nil?
|
30
|
+
raise "Only one path can be remote"
|
31
|
+
end
|
32
|
+
|
33
|
+
# copy opts as instance vars
|
34
|
+
opts.each do |k,v|
|
35
|
+
instance_variable_set("@#{k}", v)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
def role
|
40
|
+
@src_type || @dest_type
|
41
|
+
end
|
42
|
+
|
43
|
+
|
44
|
+
def password
|
45
|
+
[role.ssh_options, fetch(:ssh_options)].each do |s|
|
46
|
+
begin
|
47
|
+
return s[:password]
|
48
|
+
rescue
|
49
|
+
next
|
50
|
+
end
|
51
|
+
end
|
52
|
+
return nil
|
53
|
+
end
|
54
|
+
|
55
|
+
|
56
|
+
def remote_options
|
57
|
+
options = []
|
58
|
+
ssh_options = []
|
59
|
+
# No remote site
|
60
|
+
return [] if role.nil?
|
61
|
+
|
62
|
+
# Handle passsword
|
63
|
+
if not password.nil?
|
64
|
+
ssh_options += [
|
65
|
+
:sshpass,
|
66
|
+
'-p',
|
67
|
+
"'#{password}'",
|
68
|
+
:ssh,
|
69
|
+
'-o',
|
70
|
+
'PubkeyAuthentication=no',
|
71
|
+
]
|
72
|
+
end
|
73
|
+
|
74
|
+
if not role.port.nil?
|
75
|
+
ssh_options += ['ssh'] if ssh_options.length == 0
|
76
|
+
ssh_options += ['-p', role.port]
|
77
|
+
end
|
78
|
+
|
79
|
+
# Add options
|
80
|
+
options += ['-e', "\"#{ssh_options.join(' ')}\""] if ssh_options.length > 0
|
81
|
+
|
82
|
+
# Add rsync path if needed
|
83
|
+
rsync_path = role.properties.fetch(:deploy_rsync_path)
|
84
|
+
if not rsync_path.nil?
|
85
|
+
options += ['--rsync-path', rsync_path]
|
86
|
+
end
|
87
|
+
|
88
|
+
return options
|
89
|
+
end
|
90
|
+
|
91
|
+
def src_path
|
92
|
+
return Rsync.build_path(@src_path,@src_type)
|
93
|
+
end
|
94
|
+
|
95
|
+
def dest_path
|
96
|
+
return Rsync.build_path(@dest_path,@dest_type)
|
97
|
+
end
|
98
|
+
|
99
|
+
def command
|
100
|
+
if @rsync_path.nil?
|
101
|
+
options = [:rsync]
|
102
|
+
else
|
103
|
+
options = [@rsync_path]
|
104
|
+
end
|
105
|
+
|
106
|
+
# Add options
|
107
|
+
options += fetch(:rsync_options)
|
108
|
+
|
109
|
+
# Add remote options if needed
|
110
|
+
options += remote_options
|
111
|
+
|
112
|
+
# Add source and destination
|
113
|
+
options += [src_path, dest_path]
|
114
|
+
|
115
|
+
options
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
module Capistrano
|
2
|
+
module Former03
|
3
|
+
module Symlink
|
4
|
+
def self.execute(args)
|
5
|
+
begin
|
6
|
+
if args[0] == :ln and args[1] = '-s'
|
7
|
+
return [
|
8
|
+
:ln,
|
9
|
+
'-s',
|
10
|
+
self.relative_source(args[2], args[3]),
|
11
|
+
args[3]
|
12
|
+
]
|
13
|
+
else
|
14
|
+
return args
|
15
|
+
end
|
16
|
+
rescue IOError
|
17
|
+
return args
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
def self.relative_source(source,destination)
|
22
|
+
# Ensure pathname objects
|
23
|
+
if not source.instance_of?(Pathname)
|
24
|
+
source = Pathname.new source
|
25
|
+
end
|
26
|
+
if not destination.instance_of?(Pathname)
|
27
|
+
destination = Pathname.new destination
|
28
|
+
end
|
29
|
+
|
30
|
+
return source.relative_path_from(destination.dirname)
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
@@ -0,0 +1,10 @@
|
|
1
|
+
require 'capistrano/former03/version'
|
2
|
+
require 'capistrano/former03/deploy_command'
|
3
|
+
require 'capistrano/former03/symlink'
|
4
|
+
require 'capistrano/former03/rsync'
|
5
|
+
load File.expand_path('../tasks/former03.rake', __FILE__)
|
6
|
+
|
7
|
+
module Capistrano
|
8
|
+
module Former03
|
9
|
+
end
|
10
|
+
end
|
@@ -0,0 +1,261 @@
|
|
1
|
+
Rake::Task[:'deploy:check'].enhance [:'former03:override_scm']
|
2
|
+
Rake::Task[:'deploy:updating'].enhance [:'former03:override_scm']
|
3
|
+
Rake::Task[:'deploy:set_current_revision'].enhance [:'former03:override_scm']
|
4
|
+
Rake::Task[:'deploy:symlink:release'].enhance [:'former03:override_symlink']
|
5
|
+
Rake::Task[:'deploy:symlink:linked_dirs'].enhance [:'former03:override_symlink']
|
6
|
+
Rake::Task[:'deploy:symlink:linked_files'].enhance [:'former03:override_symlink']
|
7
|
+
|
8
|
+
namespace :former03 do
|
9
|
+
set :rsync_options, [
|
10
|
+
'--archive',
|
11
|
+
'--delete',
|
12
|
+
]
|
13
|
+
|
14
|
+
set :local_stage, 'tmp/deploy'
|
15
|
+
set :remote_stage, 'shared/deploy'
|
16
|
+
set :remote_bin, 'shared/deploy_bin'
|
17
|
+
set :deploy_rsync_bin, nil
|
18
|
+
set :deploy_busybox_bin, false
|
19
|
+
set :relative_symlinks, true
|
20
|
+
set :current_path_real_dir, false
|
21
|
+
|
22
|
+
set :remote_stage_path, -> {
|
23
|
+
Pathname.new(deploy_to).join(fetch(:remote_stage))
|
24
|
+
}
|
25
|
+
|
26
|
+
set :remote_bin_path, -> {
|
27
|
+
Pathname.new(deploy_to).join(fetch(:remote_bin))
|
28
|
+
}
|
29
|
+
|
30
|
+
set :local_stage_path, -> {
|
31
|
+
Pathname.pwd.join(fetch(:local_stage))
|
32
|
+
}
|
33
|
+
|
34
|
+
desc 'Override scm tasks'
|
35
|
+
task :override_scm do
|
36
|
+
Rake::Task[:"#{scm}:check"].clear
|
37
|
+
Rake::Task.define_task(:"#{scm}:check") do
|
38
|
+
invoke :'former03:local:check'
|
39
|
+
invoke :'former03:remote:check'
|
40
|
+
end
|
41
|
+
|
42
|
+
Rake::Task[:"#{scm}:create_release"].clear
|
43
|
+
Rake::Task.define_task(:"#{scm}:create_release") do
|
44
|
+
invoke :'former03:remote:release'
|
45
|
+
end
|
46
|
+
|
47
|
+
Rake::Task[:"#{scm}:set_current_revision"].clear
|
48
|
+
Rake::Task.define_task(:"#{scm}:set_current_revision") do
|
49
|
+
invoke :'former03:local:set_current_revision'
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
desc 'Override symlink tasks'
|
54
|
+
task :override_symlink do
|
55
|
+
if fetch(:relative_symlinks)
|
56
|
+
#Filter execute with :ln, -s using Capistrano::Former03::Symlink
|
57
|
+
SSHKit::Backend::Netssh.send(:define_method, :execute) do |*args|
|
58
|
+
_execute(*Capistrano::Former03::Symlink.execute(args)).success?
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Move release to have a real dir as current path
|
63
|
+
if fetch(:current_path_real_dir)
|
64
|
+
Rake::Task[:'deploy:symlink:release'].clear
|
65
|
+
Rake::Task.define_task(:'deploy:symlink:release') do
|
66
|
+
invoke :'former03:remote:release_move'
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
namespace :local do
|
72
|
+
desc 'Check that the repository is reachable'
|
73
|
+
task :check do
|
74
|
+
run_locally do
|
75
|
+
git_dir = Pathname.new(capture :git, 'rev-parse', '--git-dir')
|
76
|
+
if not git_dir.absolute?
|
77
|
+
git_dir = Pathname.pwd.join(git_dir)
|
78
|
+
end
|
79
|
+
set :repo_path, git_dir
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
|
84
|
+
desc 'Create the local staging directory'
|
85
|
+
task :mkdir_stage => :check do
|
86
|
+
|
87
|
+
# Get full path of local stage
|
88
|
+
set :local_stage_path, Pathname.pwd.join(fetch(:local_stage))
|
89
|
+
|
90
|
+
# if already exits finish task
|
91
|
+
next if File.directory? fetch(:local_stage)
|
92
|
+
|
93
|
+
# create directory
|
94
|
+
run_locally do
|
95
|
+
execute :mkdir, '-p', fetch(:local_stage)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
|
99
|
+
desc 'Determine current revision'
|
100
|
+
task :set_current_revision do
|
101
|
+
run_locally do
|
102
|
+
# Set current revision
|
103
|
+
revision = capture(:git, 'rev-parse', 'HEAD').chomp
|
104
|
+
branches = capture(:git, 'show-ref','|', :grep, "^#{revision}",'|',:awk, "'{ print $2 }'").split()
|
105
|
+
set :current_revision, revision
|
106
|
+
set :branch, branches.join(', ')
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
desc 'Stage the repository in a local directory'
|
111
|
+
task :stage => :mkdir_stage do
|
112
|
+
|
113
|
+
git_prefix = [:git, '--git-dir', fetch(:repo_path), '--work-tree',fetch(:local_stage_path)]
|
114
|
+
git_submodule = [:git, :submodule]
|
115
|
+
|
116
|
+
run_locally do
|
117
|
+
# Bugfix for git versions < 1.9
|
118
|
+
|
119
|
+
# Check if .gitmodules exist
|
120
|
+
if test :test, '-e', '.gitmodules'
|
121
|
+
execute(*git_submodule, :init)
|
122
|
+
execute(*git_submodule, :sync)
|
123
|
+
execute(*git_submodule, :update)
|
124
|
+
end
|
125
|
+
|
126
|
+
within fetch(:local_stage) do
|
127
|
+
# Ensure correct checkout
|
128
|
+
execute(*git_prefix, :reset, '--hard')
|
129
|
+
|
130
|
+
# Cleanup got
|
131
|
+
execute(*git_prefix, :clean, '-fxd')
|
132
|
+
|
133
|
+
# Check if .gitmodules exist
|
134
|
+
if test :test, '-e', '.gitmodules'
|
135
|
+
# check out all submodules
|
136
|
+
git_submodule = git_prefix + [:submodule]
|
137
|
+
git_submodule_foreach = git_submodule + [:foreach,:git]
|
138
|
+
execute(*git_submodule, :init)
|
139
|
+
execute(*git_submodule, :sync)
|
140
|
+
execute(*git_submodule, :update)
|
141
|
+
|
142
|
+
# cleanup all submodules
|
143
|
+
execute(*git_submodule_foreach, :reset, '--hard')
|
144
|
+
execute(*git_submodule_foreach, :clean, '-fxd')
|
145
|
+
end
|
146
|
+
end
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
namespace :remote do
|
152
|
+
|
153
|
+
desc 'Check the deployment hosts'
|
154
|
+
task :check => [
|
155
|
+
:mkdir_stage,
|
156
|
+
:check_rsync_binary,
|
157
|
+
:check_busybox_binary
|
158
|
+
] do
|
159
|
+
# Add :remote_bin_path to PATH if needed
|
160
|
+
if fetch(:remote_bin_active)
|
161
|
+
set :default_env, {
|
162
|
+
path: "#{fetch(:remote_bin_path)}:$PATH"
|
163
|
+
}
|
164
|
+
end
|
165
|
+
end
|
166
|
+
|
167
|
+
desc 'Create a destination on deployment hosts'
|
168
|
+
task :mkdir_stage do
|
169
|
+
on release_roles :all do
|
170
|
+
path = File.join fetch(:deploy_to), fetch(:remote_stage)
|
171
|
+
execute :mkdir, '-pv', path
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
desc 'Check if bin destnation dir exists'
|
176
|
+
task :check_bin_dir do
|
177
|
+
on release_roles :all do
|
178
|
+
execute :mkdir, '-pv', fetch(:remote_bin_path)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
|
182
|
+
desc 'Check for rsync binary on deployment hosts'
|
183
|
+
task :check_rsync_binary => [:check_bin_dir] do
|
184
|
+
deploy_cmd = Capistrano::Former03::DeployCommand.new(
|
185
|
+
:command => 'rsync',
|
186
|
+
:deploy_flag => :deploy_rsync_bin,
|
187
|
+
:deploy_path => :deploy_rsync_path,
|
188
|
+
:install_cmd => nil,
|
189
|
+
:install_cmd => nil,
|
190
|
+
:test_cmd => ['--version', '>', '/dev/null'],
|
191
|
+
:required => true,
|
192
|
+
)
|
193
|
+
on release_roles :all do
|
194
|
+
deploy_cmd.deploy(self)
|
195
|
+
end
|
196
|
+
end
|
197
|
+
|
198
|
+
desc 'Check for busybox binary on deployment hosts'
|
199
|
+
task :check_busybox_binary => [:check_bin_dir] do
|
200
|
+
deploy_cmd = Capistrano::Former03::DeployCommand.new(
|
201
|
+
:command => 'busybox',
|
202
|
+
:deploy_flag => :deploy_busybox_bin,
|
203
|
+
:install_cmd => ['--install', '-s', fetch(:remote_bin_path)],
|
204
|
+
:test_cmd => ['--help', '>', '/dev/null'],
|
205
|
+
:required => false,
|
206
|
+
)
|
207
|
+
on release_roles :all do
|
208
|
+
deploy_cmd.deploy(self)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
|
212
|
+
desc 'Sync to deployment hosts from local'
|
213
|
+
task :sync => [:check, 'former03:local:stage'] do
|
214
|
+
roles(:all).each do |role|
|
215
|
+
rsync = Capistrano::Former03::Rsync.new(
|
216
|
+
:src_path => fetch(:local_stage_path),
|
217
|
+
:dest_path => fetch(:remote_stage_path),
|
218
|
+
:dest_type => role,
|
219
|
+
)
|
220
|
+
run_locally do
|
221
|
+
execute(*rsync.command)
|
222
|
+
end
|
223
|
+
end
|
224
|
+
end
|
225
|
+
|
226
|
+
desc 'Copy the code to the releases directory'
|
227
|
+
task :release => :sync do
|
228
|
+
on release_roles :all do
|
229
|
+
rsync = Capistrano::Former03::Rsync.new(
|
230
|
+
:rsync_path => fetch(:deploy_rsync_path),
|
231
|
+
:src_path => fetch(:remote_stage_path),
|
232
|
+
:dest_path => release_path,
|
233
|
+
)
|
234
|
+
execute(*rsync.command)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
238
|
+
desc 'Move release to current instead of symlinking'
|
239
|
+
task :release_move do
|
240
|
+
on release_roles :all do
|
241
|
+
cp = current_path.join('current')
|
242
|
+
current_path = cp
|
243
|
+
current_version_path = current_path.to_s + ".version"
|
244
|
+
|
245
|
+
current_path_directory = test :test, '-d', current_path
|
246
|
+
current_version_exists = test :test, '-f', current_version_path
|
247
|
+
|
248
|
+
# check if current is a dir
|
249
|
+
if current_path_directory and current_version_exists
|
250
|
+
execute :mv, current_path, releases_path.join("`cat #{current_version_path}`")
|
251
|
+
else
|
252
|
+
execute :rm, '-rf', current_path
|
253
|
+
end
|
254
|
+
|
255
|
+
execute :mv, release_path, current_path
|
256
|
+
execute :echo, '-n', File.basename(release_path), '>', current_version_path
|
257
|
+
|
258
|
+
end
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
# This script builds a static version of rsync for amd64 and i386
|
4
|
+
# You need docker to run this script
|
5
|
+
|
6
|
+
VERSION=3.1.0
|
7
|
+
ARCHIVE=rsync-${VERSION}.tar.gz
|
8
|
+
|
9
|
+
wget -nc http://rsync.samba.org/ftp/rsync/src/rsync-${VERSION}.tar.gz
|
10
|
+
rm -rf rsync_src/
|
11
|
+
mkdir rsync_src/
|
12
|
+
tar xvfz ${ARCHIVE} -C rsync_src/ --strip-components 1
|
13
|
+
|
14
|
+
docker run -t -i -v $(pwd)/rsync_src:/src debian:squeeze \
|
15
|
+
/bin/bash -c "apt-get update && apt-get install -y build-essential && cd /src && ./configure CFLAGS=\"${CFLAGS} -static\" && make"
|
16
|
+
|
17
|
+
mkdir -p rsync_static
|
18
|
+
mv rsync_src/rsync rsync_static/rsync_x64
|
19
|
+
|
20
|
+
rm -rf rsync_src/
|
21
|
+
mkdir rsync_src/
|
22
|
+
tar xvfz ${ARCHIVE} -C rsync_src/ --strip-components 1
|
23
|
+
docker run -t -i -v $(pwd)/rsync_src:/src sugi/debian-i386 \
|
24
|
+
/bin/bash -c "apt-get update && apt-get install -y build-essential && cd /src && ./configure CFLAGS=\"${CFLAGS} -static\" && make"
|
25
|
+
|
26
|
+
mkdir -p rsync_static
|
27
|
+
mv rsync_src/rsync rsync_static/rsync_x32
|
Binary file
|
Binary file
|
Binary file
|
Binary file
|
data/spec/helpers.rb
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'pp'
|
2
|
+
|
3
|
+
def get_last_desc(md,key)
|
4
|
+
if md.has_key?(key)
|
5
|
+
return md[key]
|
6
|
+
else
|
7
|
+
return md
|
8
|
+
end
|
9
|
+
end
|
10
|
+
|
11
|
+
|
12
|
+
module Helpers
|
13
|
+
def set_task
|
14
|
+
puts described_class
|
15
|
+
#puts "TEST: #{example.metadata}"
|
16
|
+
end
|
17
|
+
def get_task
|
18
|
+
puts described_class
|
19
|
+
#puts "TEST: #{example.metadata}"
|
20
|
+
end
|
21
|
+
end
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require 'bundler'
|
2
|
+
begin
|
3
|
+
Bundler.setup(:default, :development)
|
4
|
+
rescue Bundler::BundlerError => e
|
5
|
+
$stderr.puts e.message
|
6
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
7
|
+
exit e.status_code
|
8
|
+
end
|
9
|
+
require_relative 'helpers'
|
10
|
+
|
11
|
+
RSpec.configure do |c|
|
12
|
+
c.include Helpers
|
13
|
+
end
|
14
|
+
|
15
|
+
|
16
|
+
shared_context "Capistrano::Former03" do
|
17
|
+
require 'capistrano/all'
|
18
|
+
require 'capistrano/deploy'
|
19
|
+
require 'capistrano/former03'
|
20
|
+
before do
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__),'../spec_helper'))
|
2
|
+
|
3
|
+
describe Rake::Task['former03:local:check'] do
|
4
|
+
it "Should test if there's a git repo" do
|
5
|
+
subject.invoke
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
describe Rake::Task['former03:local:mkdir_stage'] do
|
10
|
+
end
|
11
|
+
describe Rake::Task['former03:local:stage'] do
|
12
|
+
end
|
metadata
ADDED
@@ -0,0 +1,137 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: capistrano-former03
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Christian Simon
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
date: 2014-05-28 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.2.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 3.2.1
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: bundler
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - '>='
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rake
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - '>='
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: capistrano-spec
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - '>='
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '0'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: rspec
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - '>='
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 2.5.0
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - '>='
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 2.5.0
|
83
|
+
description: Capistrano with extensions for FORMER 03
|
84
|
+
email:
|
85
|
+
- simon@swine.de
|
86
|
+
executables: []
|
87
|
+
extensions: []
|
88
|
+
extra_rdoc_files: []
|
89
|
+
files:
|
90
|
+
- .gitignore
|
91
|
+
- Gemfile
|
92
|
+
- LICENSE.txt
|
93
|
+
- README.md
|
94
|
+
- Rakefile
|
95
|
+
- capistrano-former03.gemspec
|
96
|
+
- lib/capistrano/former03.rb
|
97
|
+
- lib/capistrano/former03/deploy_command.rb
|
98
|
+
- lib/capistrano/former03/rsync.rb
|
99
|
+
- lib/capistrano/former03/symlink.rb
|
100
|
+
- lib/capistrano/former03/version.rb
|
101
|
+
- lib/capistrano/tasks/former03.rake
|
102
|
+
- share/build_rsync.sh
|
103
|
+
- share/busybox/busybox_x32
|
104
|
+
- share/busybox/busybox_x64
|
105
|
+
- share/rsync/rsync_x32
|
106
|
+
- share/rsync/rsync_x64
|
107
|
+
- spec/helpers.rb
|
108
|
+
- spec/spec_helper.rb
|
109
|
+
- spec/tasks/local_spec.rb
|
110
|
+
homepage: https://github.com/former03/capistrano-former03
|
111
|
+
licenses:
|
112
|
+
- MIT
|
113
|
+
metadata: {}
|
114
|
+
post_install_message:
|
115
|
+
rdoc_options: []
|
116
|
+
require_paths:
|
117
|
+
- lib
|
118
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
119
|
+
requirements:
|
120
|
+
- - '>='
|
121
|
+
- !ruby/object:Gem::Version
|
122
|
+
version: '0'
|
123
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
124
|
+
requirements:
|
125
|
+
- - '>='
|
126
|
+
- !ruby/object:Gem::Version
|
127
|
+
version: '0'
|
128
|
+
requirements: []
|
129
|
+
rubyforge_project:
|
130
|
+
rubygems_version: 2.2.2
|
131
|
+
signing_key:
|
132
|
+
specification_version: 4
|
133
|
+
summary: Capistrano with extensions for FORMER 03
|
134
|
+
test_files:
|
135
|
+
- spec/helpers.rb
|
136
|
+
- spec/spec_helper.rb
|
137
|
+
- spec/tasks/local_spec.rb
|