vlad 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/History.txt +19 -0
- data/Manifest.txt +6 -0
- data/doco/variables.txt +1 -0
- data/lib/rake_remote_task.rb +32 -5
- data/lib/vlad.rb +1 -1
- data/lib/vlad/core.rb +15 -8
- data/lib/vlad/git.rb +43 -0
- data/lib/vlad/lighttpd.rb +85 -0
- data/lib/vlad/mercurial.rb +34 -0
- data/lib/vlad/mongrel.rb +0 -4
- data/lib/vlad/perforce.rb +70 -0
- data/test/test_rake_remote_task.rb +5 -5
- data/test/test_vlad.rb +1 -1
- data/test/test_vlad_git.rb +39 -0
- data/test/test_vlad_mercurial.rb +26 -0
- data/vladdemo.sh +64 -0
- metadata +86 -71
data/History.txt
CHANGED
@@ -1,3 +1,22 @@
|
|
1
|
+
== 1.1.1 / 2008-01-14
|
2
|
+
|
3
|
+
* 5 major enhancements:
|
4
|
+
* Support for Rake 0.8. Should still work for Rake 0.7.
|
5
|
+
* Added git support (contributed by Garry Dolley).
|
6
|
+
* Reviewed for accuracy by Evan Phoenix.
|
7
|
+
* Added lighttpd.rb
|
8
|
+
* Added automatic client setup for perforce.
|
9
|
+
* Added mercurial SCM support patch. Closes ticket 13475.
|
10
|
+
* 6 minor enhancements:
|
11
|
+
* Added #put method that wraps up Tempfile/rsync pattern.
|
12
|
+
* Added automatic p4 client setup for perforce.
|
13
|
+
* Added vladdemo.sh
|
14
|
+
* Moved everything over to put.
|
15
|
+
* Moved generic app setup to core from mongrel.
|
16
|
+
* Parameterized 'head' into 'revision' variable (with head as default).
|
17
|
+
* 1 bug fix
|
18
|
+
* Fixed cleanup to actually properly clean up.
|
19
|
+
|
1
20
|
== 1.1.0 / 2007-09-12
|
2
21
|
|
3
22
|
* 3 major enhancements:
|
data/Manifest.txt
CHANGED
@@ -12,11 +12,17 @@ lib/rake_remote_task.rb
|
|
12
12
|
lib/vlad.rb
|
13
13
|
lib/vlad/apache.rb
|
14
14
|
lib/vlad/core.rb
|
15
|
+
lib/vlad/git.rb
|
16
|
+
lib/vlad/lighttpd.rb
|
17
|
+
lib/vlad/mercurial.rb
|
15
18
|
lib/vlad/mongrel.rb
|
16
19
|
lib/vlad/perforce.rb
|
17
20
|
lib/vlad/subversion.rb
|
18
21
|
test/test_rake_remote_task.rb
|
19
22
|
test/test_vlad.rb
|
23
|
+
test/test_vlad_git.rb
|
24
|
+
test/test_vlad_mercurial.rb
|
20
25
|
test/test_vlad_perforce.rb
|
21
26
|
test/test_vlad_subversion.rb
|
22
27
|
test/vlad_test_case.rb
|
28
|
+
vladdemo.sh
|
data/doco/variables.txt
CHANGED
@@ -31,6 +31,7 @@ releases:: An array of all existing releases, oldest first.
|
|
31
31
|
Defaults to latest release directory name.
|
32
32
|
releases_path:: Full path to the 'releases' directory on the remote host.
|
33
33
|
Defaults to "#{deploy_to}/releases".
|
34
|
+
revision:: Revision to use for release. Defaults to 'head'.
|
34
35
|
rsync_cmd:: Path to rsync command. Defaults to "rsync".
|
35
36
|
rsync_flags:: Flags for rsync. Defaults to ['-azP', '--delete'].
|
36
37
|
scm_path:: Path on the remote host that will be used as 'working
|
data/lib/rake_remote_task.rb
CHANGED
@@ -38,6 +38,19 @@ def host host_name, *roles
|
|
38
38
|
Rake::RemoteTask.host host_name, *roles
|
39
39
|
end
|
40
40
|
|
41
|
+
##
|
42
|
+
# Copy a (usually generated) file to +remote_path+. Contents of block
|
43
|
+
# are copied to +remote_path+ and you may specify an optional
|
44
|
+
# base_name for the tempfile (aids in debugging).
|
45
|
+
|
46
|
+
def put remote_path, base_name = 'vlad.unknown'
|
47
|
+
Tempfile.open base_name do |fp|
|
48
|
+
fp.puts yield
|
49
|
+
fp.flush
|
50
|
+
rsync fp.path, remote_path
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
41
54
|
##
|
42
55
|
# Declare a Vlad task that will execute on all hosts by default. To
|
43
56
|
# limit that task to specific roles, use:
|
@@ -83,6 +96,16 @@ def target_host
|
|
83
96
|
Thread.current[:task].target_host
|
84
97
|
end
|
85
98
|
|
99
|
+
if Gem::Version.new(RAKEVERSION) < Gem::Version.new('0.8') then
|
100
|
+
class Rake::Task
|
101
|
+
alias vlad_original_execute execute
|
102
|
+
|
103
|
+
def execute(args = nil)
|
104
|
+
vlad_original_execute
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
86
109
|
##
|
87
110
|
# Rake::RemoteTask is a subclass of Rake::Task that adds
|
88
111
|
# remote_actions that execute in parallel on multiple hosts via ssh.
|
@@ -135,12 +158,14 @@ class Rake::RemoteTask < Rake::Task
|
|
135
158
|
# actions will be performed in parallel on each host configured for this
|
136
159
|
# RemoteTask.
|
137
160
|
|
138
|
-
def execute
|
161
|
+
def execute(args = nil)
|
139
162
|
raise(Vlad::ConfigurationError,
|
140
163
|
"No target hosts specified for task: #{self.name}") if
|
141
164
|
target_hosts.empty?
|
142
|
-
|
143
|
-
|
165
|
+
|
166
|
+
super args
|
167
|
+
|
168
|
+
@remote_actions.each { |act| act.execute(target_hosts, args) }
|
144
169
|
end
|
145
170
|
|
146
171
|
##
|
@@ -184,6 +209,7 @@ class Rake::RemoteTask < Rake::Task
|
|
184
209
|
until streams.empty? do
|
185
210
|
# don't busy loop
|
186
211
|
selected, = select streams, nil, nil, 0.1
|
212
|
+
|
187
213
|
next if selected.nil? or selected.empty?
|
188
214
|
|
189
215
|
selected.each do |stream|
|
@@ -394,6 +420,7 @@ class Rake::RemoteTask < Rake::Task
|
|
394
420
|
:migrate_target, :latest,
|
395
421
|
:rails_env, "production",
|
396
422
|
:rake_cmd, "rake",
|
423
|
+
:revision, "head",
|
397
424
|
:rsync_cmd, "rsync",
|
398
425
|
:rsync_flags, ['-azP', '--delete'],
|
399
426
|
:ssh_cmd, "ssh",
|
@@ -521,13 +548,13 @@ class Rake::RemoteTask < Rake::Task
|
|
521
548
|
# Execute this action on +hosts+ in parallel. Returns when block
|
522
549
|
# has completed for each host.
|
523
550
|
|
524
|
-
def execute hosts
|
551
|
+
def execute hosts, args = nil
|
525
552
|
hosts.each do |host|
|
526
553
|
t = task.clone
|
527
554
|
t.target_host = host
|
528
555
|
thread = Thread.new(t) do |task|
|
529
556
|
Thread.current[:task] = task
|
530
|
-
block.call
|
557
|
+
block.call args
|
531
558
|
end
|
532
559
|
@workers << thread
|
533
560
|
end
|
data/lib/vlad.rb
CHANGED
data/lib/vlad/core.rb
CHANGED
@@ -36,6 +36,14 @@ namespace :vlad do
|
|
36
36
|
Rake::Task['vlad:setup_app'].invoke
|
37
37
|
end
|
38
38
|
|
39
|
+
desc "Prepares application servers for deployment.".cleanup
|
40
|
+
|
41
|
+
remote_task :setup_app, :roles => :app do
|
42
|
+
dirs = [deploy_to, releases_path, scm_path, shared_path]
|
43
|
+
dirs += %w(system log pids).map { |d| File.join(shared_path, d) }
|
44
|
+
run "umask 02 && mkdir -p #{dirs.join(' ')}"
|
45
|
+
end
|
46
|
+
|
39
47
|
desc "Updates your application server to the latest revision. Syncs
|
40
48
|
a copy of the repository, exports it as the latest release, fixes
|
41
49
|
up your symlinks, symlinks the latest revision to current and logs
|
@@ -44,9 +52,8 @@ namespace :vlad do
|
|
44
52
|
remote_task :update, :roles => :app do
|
45
53
|
symlink = false
|
46
54
|
begin
|
47
|
-
# TODO: head/version should be parameterized
|
48
55
|
run [ "cd #{scm_path}",
|
49
|
-
"#{source.checkout
|
56
|
+
"#{source.checkout revision, '.'}",
|
50
57
|
"#{source.export ".", release_path}",
|
51
58
|
"chmod -R g+w #{latest_release}",
|
52
59
|
"rm -rf #{latest_release}/log #{latest_release}/public/system #{latest_release}/tmp/pids",
|
@@ -59,7 +66,7 @@ namespace :vlad do
|
|
59
66
|
symlink = true
|
60
67
|
run "rm -f #{current_path} && ln -s #{latest_release} #{current_path}"
|
61
68
|
|
62
|
-
run "echo #{now} $USER #{
|
69
|
+
run "echo #{now} $USER #{revision} #{File.basename release_path} >> #{deploy_to}/revisions.log"
|
63
70
|
rescue => e
|
64
71
|
run "rm -f #{current_path} && ln -s #{previous_release} #{current_path}" if
|
65
72
|
symlink
|
@@ -151,13 +158,13 @@ namespace :vlad do
|
|
151
158
|
All other deployed revisions are removed from the servers.".cleanup
|
152
159
|
|
153
160
|
remote_task :cleanup do
|
154
|
-
|
155
|
-
|
156
|
-
puts "no old releases to clean up"
|
161
|
+
max = keep_releases
|
162
|
+
if releases.length <= max then
|
163
|
+
puts "no old releases to clean up #{releases.length} <= #{max}"
|
157
164
|
else
|
158
|
-
puts "keeping #{
|
165
|
+
puts "keeping #{max} of #{releases.length} deployed releases"
|
159
166
|
|
160
|
-
directories = (releases - releases.last(
|
167
|
+
directories = (releases - releases.last(max)).map { |release|
|
161
168
|
File.join(releases_path, release)
|
162
169
|
}.join(" ")
|
163
170
|
|
data/lib/vlad/git.rb
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
class Vlad::Git
|
2
|
+
|
3
|
+
set :source, Vlad::Git.new
|
4
|
+
set :git_cmd, "git"
|
5
|
+
|
6
|
+
##
|
7
|
+
# Returns the command that will check out +revision+ from the
|
8
|
+
# repository into directory +destination+. +revision+ can be any
|
9
|
+
# SHA1 or equivalent (e.g. branch, tag, etc...)
|
10
|
+
|
11
|
+
def checkout(revision, destination)
|
12
|
+
destination = 'repo' if destination == '.'
|
13
|
+
revision = 'HEAD' if revision =~ /head/i
|
14
|
+
|
15
|
+
[ "rm -rf #{destination}",
|
16
|
+
"#{git_cmd} clone #{repository} #{destination}",
|
17
|
+
"cd #{destination}",
|
18
|
+
"#{git_cmd} checkout -f -b deployed-#{revision} #{revision}"
|
19
|
+
].join(" && ")
|
20
|
+
end
|
21
|
+
|
22
|
+
##
|
23
|
+
# Returns the command that will export +revision+ from the repository into
|
24
|
+
# the directory +destination+.
|
25
|
+
|
26
|
+
def export(revision, destination)
|
27
|
+
revision = 'HEAD' if revision == "."
|
28
|
+
|
29
|
+
[ "mkdir -p #{destination}",
|
30
|
+
"#{git_cmd} archive #{revision} | (cd #{destination} && tar xf -)"
|
31
|
+
].join(" && ")
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Returns a command that maps human-friendly revision identifier +revision+
|
36
|
+
# into a git SHA1.
|
37
|
+
|
38
|
+
def revision(revision)
|
39
|
+
revision = 'HEAD' if revision =~ /head/i
|
40
|
+
|
41
|
+
"`#{git_cmd} rev-parse #{revision}`"
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'vlad'
|
2
|
+
|
3
|
+
namespace :vlad do
|
4
|
+
|
5
|
+
set :lighttpd_port, 65536
|
6
|
+
set :web_command, "lighttpd"
|
7
|
+
set :lighttpd_user, "nobody"
|
8
|
+
set :lighttpd_group, "nobody"
|
9
|
+
set(:lighttpd_init) { "#{shared_path}/lighttpd.sh" }
|
10
|
+
set(:lighttpd_conf) { "#{shared_path}/lighttpd.conf" }
|
11
|
+
|
12
|
+
desc "Prepares application servers for deployment. Lighttpd
|
13
|
+
configuration is set via the lighttpd_* variables.".cleanup
|
14
|
+
|
15
|
+
remote_task :setup_lighttpd, :roles => :app do
|
16
|
+
require 'tempfile'
|
17
|
+
|
18
|
+
put lighttpd_conf, 'vlad.lighttpd_config' do
|
19
|
+
conf = <<-"EOF"
|
20
|
+
server.modules = ( "mod_rewrite",
|
21
|
+
"mod_access",
|
22
|
+
"mod_fastcgi",
|
23
|
+
"mod_compress",
|
24
|
+
"mod_accesslog" )
|
25
|
+
|
26
|
+
server.document-root = "#{current_path}/public"
|
27
|
+
server.errorlog = "#{shared_path}/log/lighttpd.error.log"
|
28
|
+
accesslog.filename = "#{shared_path}/log/lighttpd.access.log"
|
29
|
+
server.pid-file = "#{shared_path}/pids/lighttpd.pid"
|
30
|
+
server.port = #{lighttpd_port}
|
31
|
+
server.username = "#{lighttpd_user}"
|
32
|
+
server.groupname = "#{lighttpd_group}"
|
33
|
+
server.error-handler-404 = "/dispatch.fcgi"
|
34
|
+
server.indexfiles = ( "index.html", "index.rb" )
|
35
|
+
url.access-deny = ( "~", ".inc" )
|
36
|
+
compress.cache-dir = "#{shared_path}/tmp/cache/compress"
|
37
|
+
compress.filetype = ("text/html","text/plain","text/javascript","text/css")
|
38
|
+
server.tag = "lighttpd | TextDriven"
|
39
|
+
|
40
|
+
fastcgi.server = (
|
41
|
+
".fcgi" => (
|
42
|
+
"localhost" => (
|
43
|
+
"min-procs" => 1,
|
44
|
+
"max-procs" => 1,
|
45
|
+
"socket" => "#{shared_path}/pids/rubyholic.socket",
|
46
|
+
"bin-path" => "#{current_path}/public/dispatch.fcgi",
|
47
|
+
"bin-environment" => ( "RAILS_ENV" => "production" ) ) ) )
|
48
|
+
EOF
|
49
|
+
end
|
50
|
+
|
51
|
+
run "mkdir -p \"#{shared_path}/tmp/cache/compress\""
|
52
|
+
end
|
53
|
+
|
54
|
+
desc "(Re)Start the web servers"
|
55
|
+
|
56
|
+
remote_task :start_web, :roles => :web do
|
57
|
+
cmd = %w(lighttpd ruby).map {|app| "(killall #{app} || true)"}.join(" && ")
|
58
|
+
cmd += " && #{web_command} -f #{lighttpd_conf} </dev/null >/dev/null 2>&1"
|
59
|
+
run cmd
|
60
|
+
end
|
61
|
+
|
62
|
+
desc "Stop the web servers"
|
63
|
+
remote_task :stop_web, :roles => :web do
|
64
|
+
cmd = %w(lighttpd ruby).map {|app| "(killall #{app} || true)"}.join(" && ")
|
65
|
+
|
66
|
+
run cmd
|
67
|
+
end
|
68
|
+
|
69
|
+
##
|
70
|
+
# Everything HTTP.
|
71
|
+
|
72
|
+
desc "(Re)Start the web and app servers"
|
73
|
+
|
74
|
+
remote_task :start do
|
75
|
+
Rake::Task['vlad:start_app'].invoke
|
76
|
+
Rake::Task['vlad:start_web'].invoke
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Stop the web and app servers"
|
80
|
+
|
81
|
+
remote_task :stop do
|
82
|
+
Rake::Task['vlad:stop_app'].invoke
|
83
|
+
Rake::Task['vlad:stop_web'].invoke
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
class Vlad::Mercurial
|
2
|
+
|
3
|
+
set :source, Vlad::Mercurial.new
|
4
|
+
|
5
|
+
##
|
6
|
+
# Returns the command that will check out +revision+ from the repository
|
7
|
+
# into directory +destination+
|
8
|
+
|
9
|
+
def checkout(revision, destination)
|
10
|
+
revision = 'tip' if revision =~ /^head$/i
|
11
|
+
"hg pull -r #{revision} -R #{destination} #{repository}"
|
12
|
+
end
|
13
|
+
|
14
|
+
##
|
15
|
+
# Returns the command that will export +revision+ from the repository into
|
16
|
+
# the directory +destination+.
|
17
|
+
|
18
|
+
def export(revision_or_source, destination)
|
19
|
+
revision_or_source = 'tip' if revision_or_source =~ /^head$/i
|
20
|
+
if revision_or_source =~ /^(\d+|tip)$/i then
|
21
|
+
"hg archive -r #{revision_or_source} -R #{repository} #{destination}"
|
22
|
+
else
|
23
|
+
"hg archive -R #{revision_or_source} #{destination}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
##
|
28
|
+
# Returns a command that maps human-friendly revision identifier +revision+
|
29
|
+
# into a subversion revision specification.
|
30
|
+
|
31
|
+
def revision(revision)
|
32
|
+
"`hg identify -R #{repository} | cut -f1 -d\\ `"
|
33
|
+
end
|
34
|
+
end
|
data/lib/vlad/mongrel.rb
CHANGED
@@ -22,10 +22,6 @@ namespace :vlad do
|
|
22
22
|
configuration is set via the mongrel_* variables.".cleanup
|
23
23
|
|
24
24
|
remote_task :setup_app, :roles => :app do
|
25
|
-
dirs = [deploy_to, releases_path, scm_path, shared_path]
|
26
|
-
dirs += %w(system log pids).map { |d| File.join(shared_path, d) }
|
27
|
-
run "umask 02 && mkdir -p #{dirs.join(' ')}"
|
28
|
-
|
29
25
|
cmd = [
|
30
26
|
"#{mongrel_command} cluster::configure",
|
31
27
|
"-N #{mongrel_servers}",
|
data/lib/vlad/perforce.rb
CHANGED
@@ -45,3 +45,73 @@ class Vlad::Perforce
|
|
45
45
|
end
|
46
46
|
end
|
47
47
|
end
|
48
|
+
|
49
|
+
namespace :vlad do
|
50
|
+
remote_task :setup_app, :roles => :app do
|
51
|
+
p4data = p4port = p4user = p4passwd = nil
|
52
|
+
|
53
|
+
if ENV['P4CONFIG'] then
|
54
|
+
p4config_name = ENV['P4CONFIG']
|
55
|
+
p4config = nil
|
56
|
+
orig_dir = Dir.pwd.split File::SEPARATOR
|
57
|
+
|
58
|
+
until orig_dir.length == 1 do
|
59
|
+
p4config = orig_dir + [p4config_name]
|
60
|
+
p4config = File.join p4config
|
61
|
+
break if File.exist? p4config
|
62
|
+
orig_dir.pop
|
63
|
+
end
|
64
|
+
|
65
|
+
raise "couldn't find .p4config" unless File.exist? p4config
|
66
|
+
|
67
|
+
p4data = File.readlines(p4config).map { |line| line.strip.split '=', 2 }
|
68
|
+
p4data = Hash[*p4data.flatten]
|
69
|
+
else
|
70
|
+
p4data = ENV
|
71
|
+
end
|
72
|
+
|
73
|
+
p4port = p4data['P4PORT']
|
74
|
+
p4user = p4data['P4USER']
|
75
|
+
p4passwd = p4data['P4PASSWD']
|
76
|
+
|
77
|
+
raise "couldn't get P4PORT" if p4port.nil?
|
78
|
+
raise "couldn't get P4USER" if p4user.nil?
|
79
|
+
raise "couldn't get P4PASSWD" if p4passwd.nil?
|
80
|
+
|
81
|
+
p4client = [p4user, target_host, application].join '-'
|
82
|
+
|
83
|
+
require 'tmpdir'
|
84
|
+
require 'tempfile'
|
85
|
+
|
86
|
+
put File.join(scm_path, '.p4config'), 'vlad.p4config' do
|
87
|
+
[ "P4PORT=#{p4port}",
|
88
|
+
"P4USER=#{p4user}",
|
89
|
+
"P4PASSWD=#{p4passwd}",
|
90
|
+
"P4CLIENT=#{p4client}" ].join("\n")
|
91
|
+
end
|
92
|
+
|
93
|
+
p4client_path = File.join deploy_to, 'p4client.tmp'
|
94
|
+
|
95
|
+
put p4client_path, 'vlad.p4client' do
|
96
|
+
conf = <<-"CLIENT"
|
97
|
+
Client: #{p4client}
|
98
|
+
|
99
|
+
Owner: #{p4user}
|
100
|
+
|
101
|
+
Root: #{scm_path}
|
102
|
+
|
103
|
+
View:
|
104
|
+
#{repository}/... //#{p4client}/...
|
105
|
+
CLIENT
|
106
|
+
end
|
107
|
+
|
108
|
+
cmds = [
|
109
|
+
"cd #{scm_path}",
|
110
|
+
"p4 client -i < #{p4client_path}",
|
111
|
+
"rm #{p4client_path}",
|
112
|
+
]
|
113
|
+
|
114
|
+
run cmds.join(' && ')
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
@@ -24,7 +24,7 @@ class TestRakeRemoteTask < VladTestCase
|
|
24
24
|
set :some_variable, 1
|
25
25
|
x = 5
|
26
26
|
task = @vlad.remote_task(:some_task) { x += some_variable }
|
27
|
-
task.execute
|
27
|
+
task.execute nil
|
28
28
|
assert_equal 1, task.some_variable
|
29
29
|
assert_equal 2, task.remote_actions.first.workers.size
|
30
30
|
assert_equal 7, x
|
@@ -33,20 +33,20 @@ class TestRakeRemoteTask < VladTestCase
|
|
33
33
|
def test_execute_exposes_target_host
|
34
34
|
host "app.example.com", :app
|
35
35
|
task = remote_task(:target_task) { set(:test_target_host, target_host) }
|
36
|
-
task.execute
|
36
|
+
task.execute nil
|
37
37
|
assert_equal "app.example.com", Rake::RemoteTask.fetch(:test_target_host)
|
38
38
|
end
|
39
39
|
|
40
40
|
def test_execute_with_no_hosts
|
41
41
|
@vlad.host "app.example.com", :app
|
42
42
|
t = @vlad.remote_task(:flunk, :roles => :db) { flunk "should not have run" }
|
43
|
-
e = assert_raise(Vlad::ConfigurationError) { t.execute }
|
43
|
+
e = assert_raise(Vlad::ConfigurationError) { t.execute nil }
|
44
44
|
assert_equal "No target hosts specified for task: flunk", e.message
|
45
45
|
end
|
46
46
|
|
47
47
|
def test_execute_with_no_roles
|
48
48
|
t = @vlad.remote_task(:flunk, :roles => :junk) { flunk "should not have run" }
|
49
|
-
e = assert_raise(Vlad::ConfigurationError) { t.execute }
|
49
|
+
e = assert_raise(Vlad::ConfigurationError) { t.execute nil }
|
50
50
|
assert_equal "No target hosts specified for task: flunk", e.message
|
51
51
|
end
|
52
52
|
|
@@ -55,7 +55,7 @@ class TestRakeRemoteTask < VladTestCase
|
|
55
55
|
set :some_variable, 1
|
56
56
|
x = 5
|
57
57
|
task = @vlad.remote_task(:some_task, :roles => :db) { x += some_variable }
|
58
|
-
task.execute
|
58
|
+
task.execute nil
|
59
59
|
assert_equal 1, task.some_variable
|
60
60
|
assert_equal 6, x
|
61
61
|
end
|
data/test/test_vlad.rb
CHANGED
@@ -126,7 +126,7 @@ class TestVlad < VladTestCase
|
|
126
126
|
@vlad.host 'www.example.com', :app
|
127
127
|
@vlad.remote_task(:some_task) do $some_task_result = some_variable end
|
128
128
|
|
129
|
-
Rake::Task['some_task'].execute
|
129
|
+
Rake::Task['some_task'].execute nil
|
130
130
|
assert_equal @vlad.fetch(:some_variable), $some_task_result
|
131
131
|
end
|
132
132
|
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'test/vlad_test_case'
|
2
|
+
require 'vlad'
|
3
|
+
require 'vlad/git'
|
4
|
+
|
5
|
+
class TestVladGit < VladTestCase
|
6
|
+
def setup
|
7
|
+
super
|
8
|
+
@scm = Vlad::Git.new
|
9
|
+
set :repository, "git@myhost:/home/john/project1"
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_checkout
|
13
|
+
# Checkout to the current directory (which is what the :update task passes)
|
14
|
+
cmd = @scm.checkout 'master', '.'
|
15
|
+
assert_equal 'rm -rf repo && git clone git@myhost:/home/john/project1 repo && cd repo && git checkout -f -b deployed-master master', cmd
|
16
|
+
|
17
|
+
# Mimic :update task
|
18
|
+
# 'head' should become HEAD
|
19
|
+
cmd = @scm.checkout 'head', '.'
|
20
|
+
assert_equal 'rm -rf repo && git clone git@myhost:/home/john/project1 repo && cd repo && git checkout -f -b deployed-HEAD HEAD', cmd
|
21
|
+
|
22
|
+
# Checkout to a relative path
|
23
|
+
cmd = @scm.checkout 'master', 'some/relative/path'
|
24
|
+
assert_equal 'rm -rf some/relative/path && git clone git@myhost:/home/john/project1 some/relative/path && cd some/relative/path && git checkout -f -b deployed-master master', cmd
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_export
|
28
|
+
cmd = @scm.export 'master', 'the/release/path'
|
29
|
+
assert_equal 'mkdir -p the/release/path && git archive master | (cd the/release/path && tar xf -)', cmd
|
30
|
+
end
|
31
|
+
|
32
|
+
def test_revision
|
33
|
+
['head', 'HEAD'].each do |head|
|
34
|
+
cmd = @scm.revision(head)
|
35
|
+
expected = "`git rev-parse HEAD`"
|
36
|
+
assert_equal expected, cmd
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
require 'test/vlad_test_case'
|
2
|
+
require 'vlad'
|
3
|
+
require 'vlad/mercurial'
|
4
|
+
|
5
|
+
class TestVladMercurial < Test::Unit::TestCase
|
6
|
+
def setup
|
7
|
+
@scm = Vlad::Mercurial.new
|
8
|
+
set :repository, "http://repo/project"
|
9
|
+
end
|
10
|
+
|
11
|
+
def test_checkout
|
12
|
+
cmd = @scm.checkout 'head', '/the/place'
|
13
|
+
assert_equal 'hg pull -r tip -R /the/place http://repo/project', cmd
|
14
|
+
end
|
15
|
+
|
16
|
+
def test_export
|
17
|
+
cmd = @scm.export 'head', '/the/place'
|
18
|
+
assert_equal 'hg archive -r tip -R http://repo/project /the/place', cmd
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_revision
|
22
|
+
cmd = @scm.revision('tip')
|
23
|
+
expected = "`hg identify -R http://repo/project | cut -f1 -d\\ `"
|
24
|
+
assert_equal expected, cmd
|
25
|
+
end
|
26
|
+
end
|
data/vladdemo.sh
ADDED
@@ -0,0 +1,64 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
killall mongrel svnserve 2> /dev/null
|
4
|
+
|
5
|
+
rm -rf ~/demo
|
6
|
+
mkdir ~/demo
|
7
|
+
cd ~/demo
|
8
|
+
|
9
|
+
pause() {
|
10
|
+
echo -n "waiting... hit return... "
|
11
|
+
read
|
12
|
+
echo
|
13
|
+
}
|
14
|
+
|
15
|
+
echo "Starting demo from scratch"
|
16
|
+
echo " This step creates a subversion repository and imports a new rails app"
|
17
|
+
echo " It modifies the Rakefile to load Vlad and creates config/deploy.rb"
|
18
|
+
echo
|
19
|
+
pause
|
20
|
+
|
21
|
+
svnadmin create svnrepo
|
22
|
+
echo "anon-access = write" >> svnrepo/conf/svnserve.conf
|
23
|
+
|
24
|
+
svnserve -d --foreground -r svnrepo --listen-host localhost &
|
25
|
+
|
26
|
+
rails mydemoapp
|
27
|
+
|
28
|
+
cd mydemoapp
|
29
|
+
|
30
|
+
echo "require 'rubygems'
|
31
|
+
require 'vlad'
|
32
|
+
Vlad.load" >> Rakefile
|
33
|
+
|
34
|
+
echo "set :repository, 'svn://localhost/blah'
|
35
|
+
set :domain, 'localhost'
|
36
|
+
set :deploy_to, '/Users/ryan/demo/website'
|
37
|
+
set :web_command, 'sudo apachectl'" > config/deploy.rb
|
38
|
+
|
39
|
+
svn import -m Added . svn://localhost/blah
|
40
|
+
|
41
|
+
echo
|
42
|
+
echo "Here are the tasks available:"
|
43
|
+
echo
|
44
|
+
|
45
|
+
rake -T vlad
|
46
|
+
|
47
|
+
echo
|
48
|
+
echo "The next step deploys and fires up the application"
|
49
|
+
echo
|
50
|
+
pause
|
51
|
+
|
52
|
+
rake -t vlad:setup vlad:update vlad:start
|
53
|
+
|
54
|
+
open http://localhost:8000/
|
55
|
+
|
56
|
+
echo
|
57
|
+
echo "done! check it out"
|
58
|
+
echo
|
59
|
+
pause
|
60
|
+
|
61
|
+
rake vlad:stop
|
62
|
+
|
63
|
+
kill %1
|
64
|
+
|
metadata
CHANGED
@@ -1,35 +1,62 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
|
-
rubygems_version: 0.9.4
|
3
|
-
specification_version: 1
|
4
2
|
name: vlad
|
5
3
|
version: !ruby/object:Gem::Version
|
6
|
-
version: 1.
|
7
|
-
date: 2007-09-12 00:00:00 -07:00
|
8
|
-
summary: Vlad the Deployer is pragmatic application deployment automation, without mercy. Much like Capistrano, but with 1/10th the complexity. Vlad integrates seamlessly with Rake, and uses familiar and standard tools like ssh and rsync.
|
9
|
-
require_paths:
|
10
|
-
- lib
|
11
|
-
email: ryand-ruby@zenspider.com
|
12
|
-
homepage: http://rubyhitsquad.com/
|
13
|
-
rubyforge_project: hitsquad
|
14
|
-
description: "Vlad the Deployer is pragmatic application deployment automation, without mercy. Much like Capistrano, but with 1/10th the complexity. Vlad integrates seamlessly with Rake, and uses familiar and standard tools like ssh and rsync. Impale your application on the heartless spike of the Deployer. == FEATURES/PROBLEMS: * Full deployment automation stack. * Turnkey deployment for mongrel+apache+svn. * Supports single server deployment with just 3 variables defined. * Built on rake. Easy. Engine is small. * Very few dependencies. All simple. * Uses ssh with your ssh settings already in place. * Uses rsync for efficient transfers. * Run remote commands on one or more servers. * Mix and match local and remote tasks. * Compatible with all of your tab completion shell script rake-tastic goodness. * Ships with tests that actually pass in 0.028 seconds! * Does NOT support Windows right now (we think). Coming soon in 1.2."
|
15
|
-
autorequire:
|
16
|
-
default_executable:
|
17
|
-
bindir: bin
|
18
|
-
has_rdoc: true
|
19
|
-
required_ruby_version: !ruby/object:Gem::Version::Requirement
|
20
|
-
requirements:
|
21
|
-
- - ">"
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.0.0
|
24
|
-
version:
|
4
|
+
version: 1.2.0
|
25
5
|
platform: ruby
|
26
|
-
signing_key:
|
27
|
-
cert_chain:
|
28
|
-
post_install_message:
|
29
6
|
authors:
|
30
7
|
- Ryan Davis
|
31
8
|
- Eric Hodel
|
32
9
|
- Wilson Bilkovich
|
10
|
+
autorequire:
|
11
|
+
bindir: bin
|
12
|
+
cert_chain: []
|
13
|
+
|
14
|
+
date: 2008-01-14 00:00:00 -08:00
|
15
|
+
default_executable:
|
16
|
+
dependencies:
|
17
|
+
- !ruby/object:Gem::Dependency
|
18
|
+
name: rake
|
19
|
+
version_requirement:
|
20
|
+
version_requirements: !ruby/object:Gem::Requirement
|
21
|
+
requirements:
|
22
|
+
- - ">="
|
23
|
+
- !ruby/object:Gem::Version
|
24
|
+
version: "0"
|
25
|
+
version:
|
26
|
+
- !ruby/object:Gem::Dependency
|
27
|
+
name: open4
|
28
|
+
version_requirement:
|
29
|
+
version_requirements: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - ">="
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: "0"
|
34
|
+
version:
|
35
|
+
- !ruby/object:Gem::Dependency
|
36
|
+
name: hoe
|
37
|
+
version_requirement:
|
38
|
+
version_requirements: !ruby/object:Gem::Requirement
|
39
|
+
requirements:
|
40
|
+
- - ">="
|
41
|
+
- !ruby/object:Gem::Version
|
42
|
+
version: 1.4.0
|
43
|
+
version:
|
44
|
+
description: "Vlad the Deployer is pragmatic application deployment automation, without mercy. Much like Capistrano, but with 1/10th the complexity. Vlad integrates seamlessly with Rake, and uses familiar and standard tools like ssh and rsync. Impale your application on the heartless spike of the Deployer. == FEATURES/PROBLEMS: * Full deployment automation stack. * Turnkey deployment for mongrel+apache+svn. * Supports single server deployment with just 3 variables defined. * Built on rake. Easy. Engine is small. * Very few dependencies. All simple. * Uses ssh with your ssh settings already in place. * Uses rsync for efficient transfers. * Run remote commands on one or more servers. * Mix and match local and remote tasks. * Compatible with all of your tab completion shell script rake-tastic goodness. * Ships with tests that actually pass in 0.028 seconds! * Does NOT support Windows right now (we think). Coming soon in 1.2."
|
45
|
+
email: ryand-ruby@zenspider.com
|
46
|
+
executables: []
|
47
|
+
|
48
|
+
extensions: []
|
49
|
+
|
50
|
+
extra_rdoc_files:
|
51
|
+
- History.txt
|
52
|
+
- Manifest.txt
|
53
|
+
- README.txt
|
54
|
+
- considerations.txt
|
55
|
+
- doco/faq.txt
|
56
|
+
- doco/getting_started.txt
|
57
|
+
- doco/migration.txt
|
58
|
+
- doco/perforce.txt
|
59
|
+
- doco/variables.txt
|
33
60
|
files:
|
34
61
|
- History.txt
|
35
62
|
- Manifest.txt
|
@@ -45,63 +72,51 @@ files:
|
|
45
72
|
- lib/vlad.rb
|
46
73
|
- lib/vlad/apache.rb
|
47
74
|
- lib/vlad/core.rb
|
75
|
+
- lib/vlad/git.rb
|
76
|
+
- lib/vlad/lighttpd.rb
|
77
|
+
- lib/vlad/mercurial.rb
|
48
78
|
- lib/vlad/mongrel.rb
|
49
79
|
- lib/vlad/perforce.rb
|
50
80
|
- lib/vlad/subversion.rb
|
51
81
|
- test/test_rake_remote_task.rb
|
52
82
|
- test/test_vlad.rb
|
83
|
+
- test/test_vlad_git.rb
|
84
|
+
- test/test_vlad_mercurial.rb
|
53
85
|
- test/test_vlad_perforce.rb
|
54
86
|
- test/test_vlad_subversion.rb
|
55
87
|
- test/vlad_test_case.rb
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
- test/test_vlad_subversion.rb
|
88
|
+
- vladdemo.sh
|
89
|
+
has_rdoc: true
|
90
|
+
homepage: http://rubyhitsquad.com/
|
91
|
+
post_install_message:
|
61
92
|
rdoc_options:
|
62
93
|
- --main
|
63
94
|
- README.txt
|
64
|
-
|
65
|
-
-
|
66
|
-
|
67
|
-
|
68
|
-
-
|
69
|
-
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
95
|
+
require_paths:
|
96
|
+
- lib
|
97
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ">="
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: "0"
|
102
|
+
version:
|
103
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
104
|
+
requirements:
|
105
|
+
- - ">="
|
106
|
+
- !ruby/object:Gem::Version
|
107
|
+
version: "0"
|
108
|
+
version:
|
78
109
|
requirements: []
|
79
110
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
-
|
91
|
-
|
92
|
-
version_requirement:
|
93
|
-
version_requirements: !ruby/object:Gem::Version::Requirement
|
94
|
-
requirements:
|
95
|
-
- - ">"
|
96
|
-
- !ruby/object:Gem::Version
|
97
|
-
version: 0.0.0
|
98
|
-
version:
|
99
|
-
- !ruby/object:Gem::Dependency
|
100
|
-
name: hoe
|
101
|
-
version_requirement:
|
102
|
-
version_requirements: !ruby/object:Gem::Version::Requirement
|
103
|
-
requirements:
|
104
|
-
- - ">="
|
105
|
-
- !ruby/object:Gem::Version
|
106
|
-
version: 1.3.0
|
107
|
-
version:
|
111
|
+
rubyforge_project: hitsquad
|
112
|
+
rubygems_version: 1.0.1
|
113
|
+
signing_key:
|
114
|
+
specification_version: 2
|
115
|
+
summary: Vlad the Deployer is pragmatic application deployment automation, without mercy. Much like Capistrano, but with 1/10th the complexity. Vlad integrates seamlessly with Rake, and uses familiar and standard tools like ssh and rsync.
|
116
|
+
test_files:
|
117
|
+
- test/test_rake_remote_task.rb
|
118
|
+
- test/test_vlad.rb
|
119
|
+
- test/test_vlad_git.rb
|
120
|
+
- test/test_vlad_mercurial.rb
|
121
|
+
- test/test_vlad_perforce.rb
|
122
|
+
- test/test_vlad_subversion.rb
|