vlad 1.1.0 → 1.2.0
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.
- 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
|