marionetta 0.4.8 → 0.4.8.1
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +2 -7
- data/Rakefile +0 -1
- data/lib/marionetta.rb +1 -1
- data/lib/marionetta/directory_sync.rb +8 -3
- data/lib/marionetta/manipulators/debloyer.rb +3 -1
- data/lib/marionetta/manipulators/deployer.rb +84 -16
- data/lib/marionetta/manipulators/puppet.rb +3 -1
- data/lib/marionetta/rake_helper.rb +0 -1
- data/spec/app/after2 +1 -0
- data/spec/deployer_spec.rb +15 -2
- data/spec/spec_helper.rb +3 -1
- metadata +6 -4
data/README.md
CHANGED
@@ -166,17 +166,12 @@ staging.manipulate_each_server(:deployer, :rollback)
|
|
166
166
|
|
167
167
|
## Upcoming
|
168
168
|
|
169
|
-
-
|
170
|
-
- Add clean up for deployments (v0.4.x)
|
171
|
-
- Add puppet safe-upgrade ability (v0.4.x)
|
169
|
+
- Add permissions with Manipulators::Deployer (v0.4.x)
|
172
170
|
- Remove rollback feature... we don't need rollbacks IMO. (v0.5.x)
|
173
171
|
- Remove Marionetta::Manipulators::Debloyer (v0.5.x)
|
174
172
|
- Use rye for commands (https://github.com/delano/rye) (v0.5.x)
|
175
173
|
- Use a single SSH connection per task (v0.5.x)
|
176
|
-
-
|
177
|
-
- Add ability to define permissions with Manipulators::Deployer
|
178
|
-
- Change :before_script and :after_script to :before_scripts and :after_scripts
|
179
|
-
that take an array
|
174
|
+
- Ensure concurrency is tested and therefore guaranteed (v0.5.x)
|
180
175
|
|
181
176
|
## Author
|
182
177
|
|
data/Rakefile
CHANGED
data/lib/marionetta.rb
CHANGED
@@ -42,10 +42,15 @@ module Marionetta
|
|
42
42
|
end
|
43
43
|
|
44
44
|
def rsync_exclude_flags(exclude_files)
|
45
|
-
|
46
|
-
|
45
|
+
excludes_path = '/tmp/exclude-rsync'
|
46
|
+
excludes_file = File.open(excludes_path, 'w')
|
47
47
|
|
48
|
-
|
48
|
+
exclude_files.each do |f|
|
49
|
+
excludes_file << "#{f}\n"
|
50
|
+
end
|
51
|
+
|
52
|
+
excludes_file.close
|
53
|
+
return ['--exclude-from', excludes_path]
|
49
54
|
end
|
50
55
|
|
51
56
|
def sync_dir(from, to, exclude_files = [])
|
@@ -19,6 +19,8 @@ module Marionetta
|
|
19
19
|
|
20
20
|
def initialize(server)
|
21
21
|
@server = server
|
22
|
+
server[:logger].warn('You should try Marionetta::Manipulators::Deployer')
|
23
|
+
server[:logger].warn('Debloyer (thats Deb) is now deprecated and will be removed in v0.5.x')
|
22
24
|
end
|
23
25
|
|
24
26
|
def can?()
|
@@ -90,4 +92,4 @@ module Marionetta
|
|
90
92
|
end
|
91
93
|
end
|
92
94
|
end
|
93
|
-
end
|
95
|
+
end
|
@@ -54,16 +54,22 @@ module Marionetta
|
|
54
54
|
|
55
55
|
### Deploying
|
56
56
|
|
57
|
-
#
|
58
|
-
#
|
57
|
+
# Setup deploy environment on remote server.
|
58
|
+
#
|
59
|
+
def setup()
|
60
|
+
create_directories
|
61
|
+
end
|
62
|
+
|
63
|
+
# Run a deploy to your remote server. The process
|
64
|
+
# involves:
|
59
65
|
#
|
60
66
|
# - `:from` directory rsync'd to remote cache directory
|
61
67
|
# with `:exclude` files being ignored
|
62
68
|
# - cache directory copied on remote machine to
|
63
69
|
# releases directory
|
64
|
-
# - `:before_script` run
|
70
|
+
# - `:before_script` and `:before_scripts` run
|
65
71
|
# - release directory symlinked to a current directory
|
66
|
-
# - `:after_script` run
|
72
|
+
# - `:after_script` and `:before_scripts` run
|
67
73
|
#
|
68
74
|
# The directory structure under `server[:deployer][:to]`
|
69
75
|
# looks something like this:
|
@@ -80,26 +86,33 @@ module Marionetta
|
|
80
86
|
DirectorySync.sync(server, from_dir, cache_dir, server[:deployer])
|
81
87
|
copy_cache_dir_to_release(release)
|
82
88
|
|
89
|
+
symlink_shared_directories(release)
|
90
|
+
|
83
91
|
send_scripts()
|
84
92
|
run_script(:before, release)
|
85
93
|
symlink_release_dir(release)
|
86
94
|
run_script(:after, release)
|
87
95
|
end
|
88
96
|
|
89
|
-
#
|
90
|
-
#
|
91
|
-
# be listed.
|
97
|
+
# Get an array of all releases including those which
|
98
|
+
# have been rolled back (skipped).
|
92
99
|
#
|
93
|
-
def
|
94
|
-
|
100
|
+
def releases_including_skipped()
|
101
|
+
files = []
|
95
102
|
|
96
103
|
cmd.ssh("ls -m #{releases_dir}") do |stdout|
|
97
|
-
stdout.read.split(/[,\s]+/)
|
98
|
-
releases << release unless release.index('skip-') == 0
|
99
|
-
end
|
104
|
+
files.concat(stdout.read.split(/[,\s]+/))
|
100
105
|
end
|
101
106
|
|
102
|
-
return
|
107
|
+
return files
|
108
|
+
end
|
109
|
+
|
110
|
+
# Get an array of all releases call `.releases()`. Any
|
111
|
+
# release that is subsequently rolled back will not
|
112
|
+
# be listed.
|
113
|
+
#
|
114
|
+
def releases()
|
115
|
+
releases_including_skipped.delete_if {|r| r =~ /^skip-/}
|
103
116
|
end
|
104
117
|
|
105
118
|
# If you push out and need to rollback to the previous
|
@@ -119,6 +132,16 @@ module Marionetta
|
|
119
132
|
end
|
120
133
|
end
|
121
134
|
|
135
|
+
# Delete release directories on remote machine.
|
136
|
+
#
|
137
|
+
def clean()
|
138
|
+
rels = releases()
|
139
|
+
rels.pop()
|
140
|
+
rm = ['rm', '-r'].concat(rels.map {|r| release_dir(r)})
|
141
|
+
rm << release_dir('skip-*')
|
142
|
+
cmd.ssh(rm)
|
143
|
+
end
|
144
|
+
|
122
145
|
private
|
123
146
|
|
124
147
|
def from_dir()
|
@@ -141,6 +164,10 @@ module Marionetta
|
|
141
164
|
"#{to_dir}/cache"
|
142
165
|
end
|
143
166
|
|
167
|
+
def shared_dir()
|
168
|
+
"#{to_dir}/shared"
|
169
|
+
end
|
170
|
+
|
144
171
|
def releases_dir()
|
145
172
|
"#{to_dir}/releases"
|
146
173
|
end
|
@@ -153,6 +180,24 @@ module Marionetta
|
|
153
180
|
"#{to_dir}/current"
|
154
181
|
end
|
155
182
|
|
183
|
+
def install_dir_cmd(dir)
|
184
|
+
owner = 'www-data'
|
185
|
+
group = 'www-data'
|
186
|
+
chmod = '775'
|
187
|
+
|
188
|
+
return "install -d #{dir} -o #{owner} -g #{group} -m #{chmod}"
|
189
|
+
end
|
190
|
+
|
191
|
+
def create_directories()
|
192
|
+
install = [install_dir_cmd(releases_dir), install_dir_cmd(cache_dir)]
|
193
|
+
|
194
|
+
if server[:deployer].has_key?(:shared_directories)
|
195
|
+
install << install_dir_cmd(shared_dir)
|
196
|
+
end
|
197
|
+
|
198
|
+
cmd.ssh(install)
|
199
|
+
end
|
200
|
+
|
156
201
|
def create_release_name()
|
157
202
|
name = timestamp
|
158
203
|
|
@@ -173,14 +218,37 @@ module Marionetta
|
|
173
218
|
cmd.ssh("mkdir -p #{releases_dir} && cp -r #{cache_dir} #{release_dir}")
|
174
219
|
end
|
175
220
|
|
221
|
+
def symlink_shared_directories(release)
|
222
|
+
return unless server[:deployer].has_key?(:shared_directories)
|
223
|
+
|
224
|
+
release_dir = release_dir(release)
|
225
|
+
cmds = []
|
226
|
+
|
227
|
+
server[:deployer][:shared_directories].each do |d|
|
228
|
+
to = "#{release_dir}/#{d}"
|
229
|
+
from = "#{shared_dir}/#{d}"
|
230
|
+
|
231
|
+
cmds << "rm -r #{to}"
|
232
|
+
cmds << "mkdir -p #{from}"
|
233
|
+
cmds << "ln -s #{from} #{to}"
|
234
|
+
end
|
235
|
+
|
236
|
+
cmd.ssh(cmds.join(' && '))
|
237
|
+
end
|
238
|
+
|
176
239
|
def send_scripts()
|
177
240
|
files = []
|
178
241
|
|
179
242
|
[:before, :after].each do |script|
|
180
|
-
|
243
|
+
singular_script_key = "#{script}_script".to_sym
|
244
|
+
plural_script_key = "#{script}_scripts".to_sym
|
245
|
+
|
246
|
+
if server[:deployer].has_key?(singular_script_key)
|
247
|
+
files << server[:deployer][singular_script_key]
|
248
|
+
end
|
181
249
|
|
182
|
-
if server[:deployer].has_key?(
|
183
|
-
files
|
250
|
+
if server[:deployer].has_key?(plural_script_key)
|
251
|
+
files.concat(server[:deployer][plural_script_key])
|
184
252
|
end
|
185
253
|
end
|
186
254
|
|
@@ -54,7 +54,9 @@ module Marionetta
|
|
54
54
|
# to install puppet on debian or ubuntu servers.
|
55
55
|
#
|
56
56
|
def install()
|
57
|
-
|
57
|
+
p = server[:puppet]
|
58
|
+
|
59
|
+
unless p.has_key?(:use_distro_repo) and p[:use_distro_repo] == true
|
58
60
|
install_deb_repo
|
59
61
|
end
|
60
62
|
|
data/spec/app/after2
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
echo 'Cool'
|
data/spec/deployer_spec.rb
CHANGED
@@ -11,17 +11,25 @@ def cmd()
|
|
11
11
|
end
|
12
12
|
|
13
13
|
describe Marionetta::Manipulators::Deployer do
|
14
|
-
it 'should
|
14
|
+
it 'should setup' do
|
15
15
|
cmd.ssh('rm -rf ~/app')
|
16
|
+
deployer.setup
|
17
|
+
cmd.ssh("[ -d ~/app/releases ]").should == true
|
18
|
+
cmd.ssh("[ -d ~/app/shared ]").should == true
|
19
|
+
cmd.ssh("[ -d ~/app/cache ]").should == true
|
20
|
+
end
|
21
|
+
|
22
|
+
it 'should deploy' do
|
16
23
|
deployer.deploy
|
17
24
|
deployer.deploy
|
18
25
|
cmd.ssh("[ -L ~/app/current ]").should == true
|
19
|
-
cmd.ssh("[ -d ~/app/releases ]").should == true
|
20
26
|
cmd.ssh("[ -f ~/app/current/app.rb ]").should == true
|
21
27
|
cmd.ssh("[ -f ~/app/current/app-copy.rb ]").should == true
|
22
28
|
cmd.ssh("[ -f ~/app/current/exclude.txt ]").should_not == true
|
23
29
|
cmd.ssh("[ -f ~/app/current/exclude/another.txt ]").should_not == true
|
24
30
|
cmd.ssh("[ -f ~/app/current/after ]").should_not == true
|
31
|
+
cmd.ssh("[ -f ~/app/current/after2 ]").should_not == true
|
32
|
+
cmd.ssh("[ -L ~/app/current/logs ]").should == true
|
25
33
|
end
|
26
34
|
|
27
35
|
it 'should list releases' do
|
@@ -31,4 +39,9 @@ describe Marionetta::Manipulators::Deployer do
|
|
31
39
|
it 'should rollback' do
|
32
40
|
deployer.rollback
|
33
41
|
end
|
42
|
+
|
43
|
+
it 'should clean up' do
|
44
|
+
deployer.clean
|
45
|
+
deployer.releases_including_skipped.length.should == 1
|
46
|
+
end
|
34
47
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -22,8 +22,10 @@ def server()
|
|
22
22
|
|
23
23
|
s[:deployer][:from] = app_dir
|
24
24
|
s[:deployer][:to] = '~/app'
|
25
|
-
s[:deployer][:exclude] = ['exclud*', 'before', 'after']
|
25
|
+
s[:deployer][:exclude] = ['exclud*', 'before', 'after*']
|
26
26
|
s[:deployer][:after_script] = "#{app_dir}/after"
|
27
|
+
s[:deployer][:after_scripts] = ["#{app_dir}/after2"]
|
28
|
+
s[:deployer][:shared_directories] = ['logs']
|
27
29
|
|
28
30
|
s[:debloyer][:from] = app_dir
|
29
31
|
s[:debloyer][:to] = '~/app-deb'
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: marionetta
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.4.8
|
4
|
+
version: 0.4.8.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-02-
|
12
|
+
date: 2013-02-21 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: open4
|
@@ -150,6 +150,7 @@ files:
|
|
150
150
|
- lib/marionetta/rake_helper.rb
|
151
151
|
- marionetta.gemspec
|
152
152
|
- spec/app/after
|
153
|
+
- spec/app/after2
|
153
154
|
- spec/app/app.rb
|
154
155
|
- spec/app/exclude.txt
|
155
156
|
- spec/app/exclude/another.txt
|
@@ -179,7 +180,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
179
180
|
version: '0'
|
180
181
|
segments:
|
181
182
|
- 0
|
182
|
-
hash:
|
183
|
+
hash: 2416169289769076479
|
183
184
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
184
185
|
none: false
|
185
186
|
requirements:
|
@@ -188,7 +189,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
189
|
version: '0'
|
189
190
|
segments:
|
190
191
|
- 0
|
191
|
-
hash:
|
192
|
+
hash: 2416169289769076479
|
192
193
|
requirements: []
|
193
194
|
rubyforge_project:
|
194
195
|
rubygems_version: 1.8.24
|
@@ -197,6 +198,7 @@ specification_version: 3
|
|
197
198
|
summary: Provision using puppet and deploy your servers over SSH.
|
198
199
|
test_files:
|
199
200
|
- spec/app/after
|
201
|
+
- spec/app/after2
|
200
202
|
- spec/app/app.rb
|
201
203
|
- spec/app/exclude.txt
|
202
204
|
- spec/app/exclude/another.txt
|