godfat-app-deploy 0.5.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/CHANGES +3 -0
- data/README +38 -0
- data/Rakefile +58 -0
- data/TODO +4 -0
- data/app-deploy.gemspec +35 -0
- data/example.rake +79 -0
- data/lib/app-deploy.rb +186 -0
- data/lib/app-deploy/deploy.rake +18 -0
- data/lib/app-deploy/gem.rake +25 -0
- data/lib/app-deploy/git.rake +76 -0
- data/lib/app-deploy/install.rake +17 -0
- data/lib/app-deploy/merb.rake +20 -0
- data/lib/app-deploy/mongrel.rake +13 -0
- data/lib/app-deploy/nginx.rake +25 -0
- data/lib/app-deploy/rack.rake +34 -0
- data/lib/app-deploy/rack_cluster.rb +73 -0
- data/lib/app-deploy/rack_daemon.rb +62 -0
- data/lib/app-deploy/server.rake +9 -0
- data/lib/app-deploy/thin.rake +13 -0
- data/lib/app-deploy/version.rb +4 -0
- metadata +100 -0
data/CHANGES
ADDED
data/README
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
tasks:
|
2
|
+
|
3
|
+
$ rake -T app
|
4
|
+
(in /home/photos)
|
5
|
+
rake app:deploy # deploy to master state
|
6
|
+
rake app:deploy:after # after deploy hook for you to override
|
7
|
+
rake app:deploy:before # before deploy hook for you to override
|
8
|
+
rake app:gem:install # install gems
|
9
|
+
rake app:gem:reinstall # reinstall gems
|
10
|
+
rake app:gem:uninstall # uninstall gems
|
11
|
+
rake app:git[cmd] # generic git cmd walk through all dependency
|
12
|
+
rake app:git:clone # clone repoitory from github
|
13
|
+
rake app:git:gc # git gc
|
14
|
+
rake app:git:pull # pull anything from origin
|
15
|
+
rake app:git:reset # make anything reflect master state
|
16
|
+
rake app:install # install this application
|
17
|
+
rake app:install:after # after install hook for you to override
|
18
|
+
rake app:install:before # before install hook for you to override
|
19
|
+
rake app:merb:restart # restart the merb server
|
20
|
+
rake app:merb:start[config] # start the merb server, default config: config/merb.yml
|
21
|
+
rake app:merb:stop # stop the merb server
|
22
|
+
rake app:mongrel:restart # restart the mongrel cluster
|
23
|
+
rake app:mongrel:start # start the mongrel cluster
|
24
|
+
rake app:mongrel:stop # stop the mongrel cluster
|
25
|
+
rake app:nginx:restart # reload config
|
26
|
+
rake app:nginx:start[config,nginx] # start nginx, default config is config/nginx.conf, nginx is /usr/sbin/nginx
|
27
|
+
rake app:nginx:stop[timeout] # stop nginx
|
28
|
+
rake app:rack:restart[config] # restart the rack cluster
|
29
|
+
rake app:rack:start[config] # start the rack cluster
|
30
|
+
rake app:rack:stop[config] # stop the rack cluster
|
31
|
+
rake app:server:restart # please define your server:restart task
|
32
|
+
rake app:thin:restart[config] # restart the thin cluster
|
33
|
+
rake app:thin:start[config] # start the thin cluster
|
34
|
+
rake app:thin:stop[config] # stop the thin cluster
|
35
|
+
|
36
|
+
|
37
|
+
|
38
|
+
example: see example.rake
|
data/Rakefile
ADDED
@@ -0,0 +1,58 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
begin
|
4
|
+
require 'bones'
|
5
|
+
Bones.setup
|
6
|
+
rescue LoadError
|
7
|
+
load 'tasks/setup.rb' # this line should already be there
|
8
|
+
end
|
9
|
+
|
10
|
+
PROJ.name = 'app-deploy'
|
11
|
+
# supress warnings, there's too many warnings in dm-core
|
12
|
+
# PROJ.ruby_opts.delete '-w'
|
13
|
+
|
14
|
+
# PROJ.gem.dependencies << ['dm-core', '>=0.9.3']
|
15
|
+
# PROJ.gem.development_dependencies << ['minitest', '>=1.3.0']
|
16
|
+
# PROJ.gem.executables = ["bin/#{PROJ.name}"]
|
17
|
+
|
18
|
+
task :default do
|
19
|
+
Rake.application.options.show_task_pattern = /./
|
20
|
+
Rake.application.display_tasks_and_comments
|
21
|
+
end
|
22
|
+
|
23
|
+
namespace :gem do
|
24
|
+
desc "create #{PROJ.name}.gemspec"
|
25
|
+
task 'gemspec' do
|
26
|
+
puts "rake gem:debug > #{PROJ.name}.gemspec"
|
27
|
+
File.open("#{PROJ.name}.gemspec", 'w'){|spec| spec << `rake gem:debug`.sub(/.*/, '')}
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
PROJ.authors = 'Lin Jen-Shin (a.k.a. godfat 真常)'
|
32
|
+
PROJ.email = 'godfat (XD) godfat.org'
|
33
|
+
PROJ.url = "http://github.com/godfat/#{PROJ.name}"
|
34
|
+
PROJ.description = PROJ.summary = paragraphs_of('README', 'description').join("\n\n")
|
35
|
+
PROJ.changes = paragraphs_of('CHANGES', 0..1).join("\n\n")
|
36
|
+
PROJ.rubyforge.name = 'ludy'
|
37
|
+
PROJ.version = File.read("lib/#{PROJ.name}/version.rb").gsub(/.*VERSION = '(.*)'.*/m, '\1')
|
38
|
+
|
39
|
+
PROJ.manifest_file = 'Manifest'
|
40
|
+
PROJ.exclude += ['^Manifest$', '^tmp', 'tmp$', '^pkg',
|
41
|
+
'^\.gitignore$', '^ann-', '\.sqlite3$', '\.db$']
|
42
|
+
|
43
|
+
PROJ.rdoc.remote_dir = PROJ.name
|
44
|
+
|
45
|
+
PROJ.readme_file = 'README'
|
46
|
+
PROJ.rdoc.main = 'README'
|
47
|
+
PROJ.rdoc.exclude += ['Rakefile', '^tasks', '^test']
|
48
|
+
PROJ.rdoc.include << '\w+'
|
49
|
+
PROJ.rdoc.opts << '--diagram' if !WIN32 and `which dot` =~ %r/\/dot/
|
50
|
+
PROJ.rdoc.opts += ['--charset=utf-8', '--inline-source',
|
51
|
+
'--line-numbers', '--promiscuous']
|
52
|
+
|
53
|
+
PROJ.spec.opts << '--color'
|
54
|
+
|
55
|
+
PROJ.ann.file = "ann-#{PROJ.name}-#{PROJ.version}"
|
56
|
+
PROJ.ann.paragraphs.concat %w[LINKS SYNOPSIS REQUIREMENTS INSTALL LICENSE]
|
57
|
+
|
58
|
+
CLEAN.include Dir['**/*.rbc']
|
data/TODO
ADDED
data/app-deploy.gemspec
ADDED
@@ -0,0 +1,35 @@
|
|
1
|
+
|
2
|
+
# -*- encoding: utf-8 -*-
|
3
|
+
|
4
|
+
Gem::Specification.new do |s|
|
5
|
+
s.name = %q{app-deploy}
|
6
|
+
s.version = "0.5.0"
|
7
|
+
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
9
|
+
s.authors = ["Lin Jen-Shin (a.k.a. godfat \347\234\237\345\270\270)"]
|
10
|
+
s.date = %q{2009-01-13}
|
11
|
+
s.description = %q{}
|
12
|
+
s.email = %q{godfat (XD) godfat.org}
|
13
|
+
s.extra_rdoc_files = ["CHANGES", "README", "TODO", "app-deploy.gemspec", "example.rake", "lib/app-deploy/deploy.rake", "lib/app-deploy/gem.rake", "lib/app-deploy/git.rake", "lib/app-deploy/install.rake", "lib/app-deploy/merb.rake", "lib/app-deploy/mongrel.rake", "lib/app-deploy/nginx.rake", "lib/app-deploy/rack.rake", "lib/app-deploy/server.rake", "lib/app-deploy/thin.rake"]
|
14
|
+
s.files = ["CHANGES", "README", "Rakefile", "TODO", "app-deploy.gemspec", "example.rake", "lib/app-deploy.rb", "lib/app-deploy/deploy.rake", "lib/app-deploy/gem.rake", "lib/app-deploy/git.rake", "lib/app-deploy/install.rake", "lib/app-deploy/merb.rake", "lib/app-deploy/mongrel.rake", "lib/app-deploy/nginx.rake", "lib/app-deploy/rack.rake", "lib/app-deploy/rack_cluster.rb", "lib/app-deploy/rack_daemon.rb", "lib/app-deploy/server.rake", "lib/app-deploy/thin.rake", "lib/app-deploy/version.rb"]
|
15
|
+
s.has_rdoc = true
|
16
|
+
s.homepage = %q{http://github.com/godfat/app-deploy}
|
17
|
+
s.rdoc_options = ["--diagram", "--charset=utf-8", "--inline-source", "--line-numbers", "--promiscuous", "--main", "README"]
|
18
|
+
s.require_paths = ["lib"]
|
19
|
+
s.rubyforge_project = %q{ludy}
|
20
|
+
s.rubygems_version = %q{1.3.1}
|
21
|
+
s.summary = %q{}
|
22
|
+
|
23
|
+
if s.respond_to? :specification_version then
|
24
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
25
|
+
s.specification_version = 2
|
26
|
+
|
27
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
28
|
+
s.add_development_dependency(%q<bones>, [">= 2.2.0"])
|
29
|
+
else
|
30
|
+
s.add_dependency(%q<bones>, [">= 2.2.0"])
|
31
|
+
end
|
32
|
+
else
|
33
|
+
s.add_dependency(%q<bones>, [">= 2.2.0"])
|
34
|
+
end
|
35
|
+
end
|
data/example.rake
ADDED
@@ -0,0 +1,79 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
|
4
|
+
begin
|
5
|
+
require 'app-deploy'
|
6
|
+
|
7
|
+
rescue LoadError
|
8
|
+
|
9
|
+
puts "app-deploy not found, automaticly downloading and installing..."
|
10
|
+
|
11
|
+
`git clone git://github.com/godfat/app-deploy.git tmp/app-deploy`
|
12
|
+
Dir.chdir 'tmp/app-deploy'
|
13
|
+
|
14
|
+
sh 'rake clobber'
|
15
|
+
sh 'rake gem:package'
|
16
|
+
sh 'gem install --local pkg/app-deploy-*.gem --no-ri --no-rdoc'
|
17
|
+
|
18
|
+
puts "Please re-invoke: rake #{ARGV.join(' ')}"
|
19
|
+
exit(1)
|
20
|
+
|
21
|
+
end
|
22
|
+
|
23
|
+
task :default do
|
24
|
+
Rake.application.options.show_task_pattern = /./
|
25
|
+
Rake.application.display_tasks_and_comments
|
26
|
+
end
|
27
|
+
|
28
|
+
# install gem from rubyforge
|
29
|
+
AppDeploy.dependency_gem :gem => 'bones'
|
30
|
+
|
31
|
+
# install gem from github
|
32
|
+
AppDeploy.dependency_gem :gem => 'pagfiy', :source => 'http://gems.github.com'
|
33
|
+
|
34
|
+
# clone and build and install gem from github with bones
|
35
|
+
AppDeploy.dependency_gem :github_user => 'godfat',
|
36
|
+
:github_project => 'friendly_format',
|
37
|
+
:task_gem => 'bones',
|
38
|
+
:git_path => 'tmp/friendly_format'
|
39
|
+
|
40
|
+
# same as above but with hoe
|
41
|
+
AppDeploy.dependency_gem :github_user => 'godfat',
|
42
|
+
:github_project => 'mogilefs-client',
|
43
|
+
:task_gem => 'hoe',
|
44
|
+
:git_path => 'tmp/mogilefs-client'
|
45
|
+
|
46
|
+
# same as above but with custom install script
|
47
|
+
AppDeploy.dependency_gem :github_user => 'godfat',
|
48
|
+
:github_project => 'app-deploy',
|
49
|
+
:git_path => 'tmp/app-deploy' do
|
50
|
+
sh 'rake clobber'
|
51
|
+
sh 'rake gem:package'
|
52
|
+
sh 'gem install --local pkg/app-deploy-*.gem --no-ri --no-rdoc'
|
53
|
+
end
|
54
|
+
|
55
|
+
# no gem to install, just clone it
|
56
|
+
AppDeploy.dependency :github_user => 'godfat',
|
57
|
+
:github_project => 'in_place_editing',
|
58
|
+
:git_path => 'tmp/vendor/plugins/in_place_editing'
|
59
|
+
|
60
|
+
namespace :app do
|
61
|
+
namespace :install do
|
62
|
+
# before install hook
|
63
|
+
task :before do
|
64
|
+
# explicit install gem, ignore gem that was already installed
|
65
|
+
AppDeploy.install_gem(:gem => 'hoe')
|
66
|
+
end
|
67
|
+
|
68
|
+
# after install hook
|
69
|
+
task :after do
|
70
|
+
# explicit uninstall gem, ignore gem that was not installed
|
71
|
+
AppDeploy.uninstall_gem(:gem => 'zzz')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
namespace :server do
|
76
|
+
# use thin as server
|
77
|
+
task :restart => 'thin:restart'
|
78
|
+
end
|
79
|
+
end
|
data/lib/app-deploy.rb
ADDED
@@ -0,0 +1,186 @@
|
|
1
|
+
|
2
|
+
%w[deploy gem git install merb mongrel nginx server thin rack].each{ |task|
|
3
|
+
load "app-deploy/#{task}.rake"
|
4
|
+
}
|
5
|
+
|
6
|
+
module AppDeploy
|
7
|
+
module_function
|
8
|
+
def github; @github ||= []; end
|
9
|
+
def dependency opts = {}
|
10
|
+
opts = opts.dup
|
11
|
+
opts[:git_path] ||= opts[:github_project]
|
12
|
+
github << opts.freeze
|
13
|
+
end
|
14
|
+
|
15
|
+
def gem; @gem ||= []; end
|
16
|
+
def dependency_gem opts = {}, &block
|
17
|
+
opts = opts.dup
|
18
|
+
|
19
|
+
if opts[:github_project]
|
20
|
+
opts[:git_path] ||= opts[:github_project]
|
21
|
+
opts[:task_gem] = block if block_given?
|
22
|
+
github << opts.freeze
|
23
|
+
end
|
24
|
+
|
25
|
+
gem << opts.freeze
|
26
|
+
end
|
27
|
+
|
28
|
+
def each *with
|
29
|
+
with = [:github, :gem] if with.empty?
|
30
|
+
cwd = Dir.pwd
|
31
|
+
|
32
|
+
# github's gem would be in @github and @gem,
|
33
|
+
# so call uniq to ensure it wouldn't get called twice.
|
34
|
+
with.map{ |kind| AppDeploy.send(kind) }.flatten.uniq.each{ |opts|
|
35
|
+
puts
|
36
|
+
|
37
|
+
begin
|
38
|
+
if opts[:github_project]
|
39
|
+
if File.directory?(opts[:git_path])
|
40
|
+
Dir.chdir(opts[:git_path])
|
41
|
+
else
|
42
|
+
puts "Skip #{opts[:github_project]}, because it was not found"
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
yield(opts)
|
47
|
+
|
48
|
+
rescue RuntimeError => e
|
49
|
+
puts e
|
50
|
+
|
51
|
+
ensure
|
52
|
+
Dir.chdir(cwd)
|
53
|
+
|
54
|
+
end
|
55
|
+
}
|
56
|
+
end
|
57
|
+
|
58
|
+
def extract_config config
|
59
|
+
require 'yaml'
|
60
|
+
YAML.load(File.read(config)).inject([]){ |result, opt_value|
|
61
|
+
opt, value = opt_value
|
62
|
+
if block_given?
|
63
|
+
result << yield(opt, value)
|
64
|
+
else
|
65
|
+
result << "--#{opt} #{value}"
|
66
|
+
end
|
67
|
+
result
|
68
|
+
}.compact.join(' ')
|
69
|
+
end
|
70
|
+
|
71
|
+
# about git
|
72
|
+
def clone opts
|
73
|
+
user, proj, path = opts[:github_user], opts[:github_project], opts[:git_path]
|
74
|
+
|
75
|
+
if File.exist?(path)
|
76
|
+
puts "Skip #{proj} because #{path} exists"
|
77
|
+
else
|
78
|
+
sh "git clone git://github.com/#{user}/#{proj}.git #{path}"
|
79
|
+
sh "git --git-dir #{path}/.git gc"
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
# about gem
|
84
|
+
def installed_gem? gem_name
|
85
|
+
`gem list '^#{gem_name}$'` =~ /^#{gem_name}/
|
86
|
+
end
|
87
|
+
|
88
|
+
def install_gem opts
|
89
|
+
gem_name = opts[:gem] || opts[:github_project]
|
90
|
+
|
91
|
+
if AppDeploy.installed_gem?(gem_name)
|
92
|
+
puts "Skip #{gem_name} because it was installed. Uninstall first if you want to reinstall"
|
93
|
+
|
94
|
+
else
|
95
|
+
if opts[:gem]
|
96
|
+
AppDeploy.install_gem_remote(opts[:gem], opts[:source])
|
97
|
+
else
|
98
|
+
AppDeploy.install_gem_local(opts[:github_project], opts[:task_gem])
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
def uninstall_gem opts
|
105
|
+
gem_name = opts[:gem] || opts[:github_project]
|
106
|
+
if AppDeploy.installed_gem?(gem_name)
|
107
|
+
sh "gem uninstall #{gem_name}"
|
108
|
+
else
|
109
|
+
puts "Skip #{gem_name} because it was not installed"
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def install_gem_remote gem_name, source = nil
|
114
|
+
sh "gem install #{gem_name} --no-ri --no-rdoc#{source ? ' --source' + source : ''}"
|
115
|
+
end
|
116
|
+
|
117
|
+
def install_gem_local proj, task
|
118
|
+
case task
|
119
|
+
when 'bones'
|
120
|
+
sh 'rake clobber'
|
121
|
+
sh 'rake gem:package'
|
122
|
+
sh "gem install --local pkg/#{proj}-*.gem --no-ri --no-rdoc"
|
123
|
+
|
124
|
+
when 'hoe'
|
125
|
+
sh 'rake gem'
|
126
|
+
sh "gem install --local pkg/#{proj}-*.gem --no-ri --no-rdoc"
|
127
|
+
|
128
|
+
when Proc
|
129
|
+
task.call
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# about sending signal
|
134
|
+
def read_pid pid_path
|
135
|
+
if File.exist?(pid_path)
|
136
|
+
File.read(pid_path).strip.to_i
|
137
|
+
|
138
|
+
else
|
139
|
+
puts "WARN: No pid file found in #{pid_path}"
|
140
|
+
nil
|
141
|
+
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
def hup pid_path, name = nil
|
146
|
+
if pid = AppDeploy.read_pid(pid_path)
|
147
|
+
puts "Sending HUP to #{name}(#{pid})..."
|
148
|
+
Process.kill('HUP', pid)
|
149
|
+
end
|
150
|
+
rescue Errno::ESRCH
|
151
|
+
puts "WARN: No such pid: #{pid}, removing #{pid_path}..."
|
152
|
+
File.delete(pid_path)
|
153
|
+
end
|
154
|
+
|
155
|
+
def term pid_path, name = nil, limit = 5
|
156
|
+
if pid = AppDeploy.read_pid(pid_path)
|
157
|
+
puts "Sending TERM to #{name}(#{pid})..."
|
158
|
+
|
159
|
+
else
|
160
|
+
return
|
161
|
+
|
162
|
+
end
|
163
|
+
|
164
|
+
require 'timeout'
|
165
|
+
begin
|
166
|
+
timeout(limit){
|
167
|
+
while true
|
168
|
+
Process.kill('TERM', pid)
|
169
|
+
sleep(0.1)
|
170
|
+
end
|
171
|
+
}
|
172
|
+
rescue Errno::ESRCH
|
173
|
+
if File.exist?(pid_path)
|
174
|
+
puts "WARN: No such pid: #{pid}, removing #{pid_path}..."
|
175
|
+
File.delete(pid_path)
|
176
|
+
else
|
177
|
+
puts "Killed #{name}(#{pid})"
|
178
|
+
end
|
179
|
+
|
180
|
+
rescue Timeout::Error
|
181
|
+
puts "Timeout(#{limit}) killing #{name}(#{pid})"
|
182
|
+
|
183
|
+
end
|
184
|
+
end
|
185
|
+
|
186
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
|
2
|
+
namespace :app do
|
3
|
+
|
4
|
+
desc 'deploy to master state'
|
5
|
+
task :deploy => 'deploy:default'
|
6
|
+
|
7
|
+
namespace :deploy do
|
8
|
+
desc 'before deploy hook for you to override'
|
9
|
+
task :before
|
10
|
+
|
11
|
+
desc 'after deploy hook for you to override'
|
12
|
+
task :after
|
13
|
+
|
14
|
+
task :default => [:before, 'git:reset',
|
15
|
+
'server:restart', :after]
|
16
|
+
|
17
|
+
end # of deploy
|
18
|
+
end # of app
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
namespace :app do
|
3
|
+
namespace :gem do
|
4
|
+
|
5
|
+
desc 'install gems'
|
6
|
+
task :install do
|
7
|
+
AppDeploy.each(:gem){ |dep|
|
8
|
+
puts "Installing #{dep[:gem] || dep[:github_project]}..."
|
9
|
+
AppDeploy.install_gem(dep)
|
10
|
+
}
|
11
|
+
end
|
12
|
+
|
13
|
+
desc 'uninstall gems'
|
14
|
+
task :uninstall do
|
15
|
+
AppDeploy.each(:gem){ |dep|
|
16
|
+
puts "Uninstalling #{dep[:gem] || dep[:github_project]}..."
|
17
|
+
AppDeploy.uninstall_gem(dep)
|
18
|
+
}
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'reinstall gems'
|
22
|
+
task :reinstall => [:uninstall, :install]
|
23
|
+
|
24
|
+
end # of gem
|
25
|
+
end # of app
|
@@ -0,0 +1,76 @@
|
|
1
|
+
|
2
|
+
namespace :app do
|
3
|
+
|
4
|
+
desc 'generic git cmd walk through all dependency'
|
5
|
+
task :git, :cmd do |t, args|
|
6
|
+
cmd = args[:cmd] || 'status'
|
7
|
+
|
8
|
+
puts "Invoking git #{cmd}..."
|
9
|
+
begin
|
10
|
+
sh "git #{cmd}"
|
11
|
+
rescue RuntimeError => e
|
12
|
+
puts e
|
13
|
+
end
|
14
|
+
|
15
|
+
AppDeploy.each(:github){ |opts|
|
16
|
+
puts "Invoking git #{cmd} on #{opts[:github_project]}..."
|
17
|
+
begin
|
18
|
+
sh "git #{cmd}"
|
19
|
+
rescue RuntimeError => e
|
20
|
+
puts e
|
21
|
+
end
|
22
|
+
}
|
23
|
+
|
24
|
+
end
|
25
|
+
|
26
|
+
namespace :git do
|
27
|
+
|
28
|
+
desc 'make anything reflect master state'
|
29
|
+
task :reset do
|
30
|
+
puts 'Resetting...'
|
31
|
+
sh 'git stash' # oops, save your work first.
|
32
|
+
sh 'git reset --hard'
|
33
|
+
|
34
|
+
AppDeploy.each(:github){ |opts|
|
35
|
+
puts "Resetting #{opts[:github_project]}..."
|
36
|
+
sh 'git stash' # oops, save your work first.
|
37
|
+
sh 'git reset --hard'
|
38
|
+
}
|
39
|
+
end
|
40
|
+
|
41
|
+
desc 'clone repoitory from github'
|
42
|
+
task :clone do
|
43
|
+
AppDeploy.github.each{ |dep|
|
44
|
+
puts "Cloning #{dep[:github_project]}..."
|
45
|
+
AppDeploy.clone(dep)
|
46
|
+
}
|
47
|
+
end
|
48
|
+
|
49
|
+
desc 'pull anything from origin'
|
50
|
+
task :pull do
|
51
|
+
puts 'Pulling...'
|
52
|
+
begin
|
53
|
+
sh 'git pull' if `git remote` =~ /^origin$/
|
54
|
+
rescue RuntimeError => e
|
55
|
+
puts e
|
56
|
+
end
|
57
|
+
|
58
|
+
AppDeploy.each(:github){ |opts|
|
59
|
+
puts "Pulling #{opts[:github_project]}..."
|
60
|
+
sh 'git pull'
|
61
|
+
}
|
62
|
+
end
|
63
|
+
|
64
|
+
desc 'git gc'
|
65
|
+
task :gc do
|
66
|
+
puts 'Garbage collecting...'
|
67
|
+
sh 'git gc'
|
68
|
+
|
69
|
+
AppDeploy.each(:github){ |opts|
|
70
|
+
puts "Garbage collecting #{opts[:github_project]}..."
|
71
|
+
sh 'git gc'
|
72
|
+
}
|
73
|
+
end
|
74
|
+
|
75
|
+
end # of git
|
76
|
+
end # of app
|
@@ -0,0 +1,17 @@
|
|
1
|
+
|
2
|
+
namespace :app do
|
3
|
+
|
4
|
+
desc 'install this application'
|
5
|
+
task :install => 'install:default'
|
6
|
+
|
7
|
+
namespace :install do
|
8
|
+
desc 'before install hook for you to override'
|
9
|
+
task :before
|
10
|
+
|
11
|
+
desc 'after install hook for you to override'
|
12
|
+
task :after
|
13
|
+
|
14
|
+
task :default => [:before, 'git:clone', 'gem:install', :after]
|
15
|
+
|
16
|
+
end # of install
|
17
|
+
end # of app
|
@@ -0,0 +1,20 @@
|
|
1
|
+
|
2
|
+
namespace :app do
|
3
|
+
namespace :merb do
|
4
|
+
|
5
|
+
desc 'start the merb server, default config: config/merb.yml'
|
6
|
+
task :start, :config do |t, args|
|
7
|
+
sh "merb #{AppDeploy.extract_config(args[:config] || 'config/merb.yml')}"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'stop the merb server'
|
11
|
+
task :stop do
|
12
|
+
sh 'merb -K all'
|
13
|
+
sleep(0.5)
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'restart the merb server'
|
17
|
+
task :restart => [:stop, :start]
|
18
|
+
|
19
|
+
end # of merb
|
20
|
+
end # of app
|
@@ -0,0 +1,25 @@
|
|
1
|
+
|
2
|
+
namespace :app do
|
3
|
+
namespace :nginx do
|
4
|
+
|
5
|
+
desc 'start nginx, default config is config/nginx.conf, nginx is /usr/sbin/nginx'
|
6
|
+
task :start, :config, :nginx do |t, args|
|
7
|
+
if !File.exist?('tmp/pids/nginx.pid')
|
8
|
+
sh "#{args[:nginx] || '/usr/sbin/nginx'} -c #{args[:config] || 'config/nginx.conf'}"
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
desc 'reload config'
|
13
|
+
task :restart do
|
14
|
+
# sh 'kill -HUP `cat tmp/pids/nginx.pid`'
|
15
|
+
AppDeploy.hup('tmp/pids/nginx.pid', 'nginx')
|
16
|
+
end
|
17
|
+
|
18
|
+
desc 'stop nginx'
|
19
|
+
task :stop, :timeout do |t, args|
|
20
|
+
# sh "kill -TERM `cat tmp/pids/nginx.pid`"
|
21
|
+
AppDeploy.term('tmp/pids/nginx.pid', 'nginx', args[:timeout] || 5)
|
22
|
+
end
|
23
|
+
|
24
|
+
end # of nginx
|
25
|
+
end # of app
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
require 'app-deploy/rack_cluster'
|
3
|
+
|
4
|
+
namespace :app do
|
5
|
+
namespace :rack do
|
6
|
+
|
7
|
+
desc "start the rack cluster"
|
8
|
+
task :start, :config do |t, args|
|
9
|
+
config = args[:config] || 'config/rack_cluster.yml'
|
10
|
+
RackCluster.each(config){ |config, ruby_opts, rack_opts|
|
11
|
+
RackCluster.start(config, ruby_opts, rack_opts)
|
12
|
+
}
|
13
|
+
end
|
14
|
+
|
15
|
+
desc "stop the rack cluster"
|
16
|
+
task :stop, :config do |t, args|
|
17
|
+
config = args[:config] || 'config/rack_cluster.yml'
|
18
|
+
RackCluster.each(config){ |config, ruby_opts, rack_opts|
|
19
|
+
AppDeploy.term(config[:pid], config[:server])
|
20
|
+
}
|
21
|
+
end
|
22
|
+
|
23
|
+
desc "restart the rack cluster"
|
24
|
+
task :restart, :config do |t, args|
|
25
|
+
config = args[:config] || 'config/rack_cluster.yml'
|
26
|
+
RackCluster.each(config){ |config, ruby_opts, rack_opts|
|
27
|
+
AppDeploy.term(config[:pid], config[:server])
|
28
|
+
RackCluster.start(config, ruby_opts, rack_opts)
|
29
|
+
puts
|
30
|
+
}
|
31
|
+
end
|
32
|
+
|
33
|
+
end # of rack
|
34
|
+
end # of app
|
@@ -0,0 +1,73 @@
|
|
1
|
+
|
2
|
+
module RackCluster
|
3
|
+
module_function
|
4
|
+
def each path
|
5
|
+
config_orig = {}
|
6
|
+
rack_opts = AppDeploy.extract_config(path){ |opt, value|
|
7
|
+
case opt
|
8
|
+
when 'environment'; "--env #{value}"
|
9
|
+
|
10
|
+
when *%w[server host]
|
11
|
+
config_orig[opt.to_sym] = value
|
12
|
+
"--#{opt} #{value}"
|
13
|
+
|
14
|
+
when *%w[user group chdir servers require rackup daemonize port pid log]
|
15
|
+
config_orig[opt.to_sym] = value
|
16
|
+
nil # rack doesn't have this option
|
17
|
+
|
18
|
+
else
|
19
|
+
"--#{opt} #{value}"
|
20
|
+
|
21
|
+
end
|
22
|
+
}
|
23
|
+
|
24
|
+
config_orig[:servers].times{ |n|
|
25
|
+
config = config_orig.dup
|
26
|
+
ruby_opts = ''
|
27
|
+
rack_opts = ''
|
28
|
+
|
29
|
+
config[:port] += n if config[:port]
|
30
|
+
config[:pid] = RackCluster.pid_path(config[:pid], config[:port])
|
31
|
+
|
32
|
+
if config[:daemonize]
|
33
|
+
config[:log] = RackCluster.log_path(config[:log], config[:port])
|
34
|
+
|
35
|
+
args = [:pid, :log, :user, :group, :chdir].map{ |kind|
|
36
|
+
config.send(:[], kind)
|
37
|
+
}.join("', '")
|
38
|
+
|
39
|
+
init_script = "RackDaemon.daemonize('#{args}')"
|
40
|
+
rack_daemon = File.dirname(__FILE__) + '/rack_daemon.rb'
|
41
|
+
ruby_opts += " -r #{rack_daemon} -e \"#{init_script}\""
|
42
|
+
end
|
43
|
+
|
44
|
+
rack_opts += " --port #{config[:port]}" if config[:port]
|
45
|
+
rack_opts += " --pid #{config[:pid]}" if config[:pid]
|
46
|
+
|
47
|
+
yield(config, ruby_opts, rack_opts)
|
48
|
+
}
|
49
|
+
|
50
|
+
end
|
51
|
+
|
52
|
+
def start config, ruby_opts, rack_opts
|
53
|
+
puts "Starting #{config[:server]} on #{config[:host]}:#{config[:port]}..."
|
54
|
+
sh "rackup#{ruby_opts}#{rack_opts} #{config[:rackup]}"
|
55
|
+
end
|
56
|
+
|
57
|
+
def pid_path path, port
|
58
|
+
RackCluster.include_server_number(path, port)
|
59
|
+
end
|
60
|
+
|
61
|
+
def log_path path, port
|
62
|
+
File.expand_path(RackCluster.include_server_number(path, port))
|
63
|
+
end
|
64
|
+
|
65
|
+
# extracted from thin
|
66
|
+
# Add the server port or number in the filename
|
67
|
+
# so each instance get its own file
|
68
|
+
def include_server_number path, number
|
69
|
+
ext = File.extname(path)
|
70
|
+
path.gsub(/#{ext}$/, ".#{number}#{ext}")
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
|
2
|
+
require 'rubygems'
|
3
|
+
require 'daemons'
|
4
|
+
|
5
|
+
require 'etc'
|
6
|
+
require 'fileutils'
|
7
|
+
|
8
|
+
module RackDaemon
|
9
|
+
module_function
|
10
|
+
def daemonize pid_path, log_path, user, group, chdir
|
11
|
+
Dir.chdir(chdir) if chdir
|
12
|
+
|
13
|
+
user ||= Etc.getpwuid(Process.uid).name
|
14
|
+
group ||= Etc.getpwuid(Process.gid).name
|
15
|
+
|
16
|
+
RackDaemon.change_privilege(user, group)
|
17
|
+
|
18
|
+
cwd = Dir.pwd
|
19
|
+
Daemonize.daemonize(log_path, 'rack-cluster')
|
20
|
+
Dir.chdir(cwd)
|
21
|
+
|
22
|
+
RackDaemon.write_pid(pid_path)
|
23
|
+
|
24
|
+
at_exit{
|
25
|
+
puts "Stopping #{pid_path}..."
|
26
|
+
RackDaemon.remove_pid(pid_path)
|
27
|
+
}
|
28
|
+
end
|
29
|
+
|
30
|
+
# extracted from thin
|
31
|
+
# Change privileges of the process
|
32
|
+
# to the specified user and group.
|
33
|
+
def change_privilege user, group
|
34
|
+
|
35
|
+
uid, gid = Process.euid, Process.egid
|
36
|
+
target_uid = Etc.getpwnam(user).uid
|
37
|
+
target_gid = Etc.getgrnam(group).gid
|
38
|
+
|
39
|
+
if uid != target_uid || gid != target_gid
|
40
|
+
puts "Changing process privilege to #{user}:#{group}"
|
41
|
+
|
42
|
+
# Change process ownership
|
43
|
+
Process.initgroups(user, target_gid)
|
44
|
+
Process::GID.change_privilege(target_gid)
|
45
|
+
Process::UID.change_privilege(target_uid)
|
46
|
+
end
|
47
|
+
|
48
|
+
rescue Errno::EPERM => e
|
49
|
+
puts "Couldn't change user and group to #{user}:#{group}: #{e}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def write_pid path
|
53
|
+
FileUtils.mkdir_p(File.dirname(path))
|
54
|
+
File.open(path, 'w'){ |f| f.write(Process.pid) }
|
55
|
+
File.chmod(0644, path)
|
56
|
+
end
|
57
|
+
|
58
|
+
def remove_pid path
|
59
|
+
File.delete(path) if File.exist?(path)
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
|
2
|
+
namespace :app do
|
3
|
+
namespace :thin do
|
4
|
+
|
5
|
+
[:start, :stop, :restart].each{ |name|
|
6
|
+
desc "#{name} the thin cluster"
|
7
|
+
task name, :config do |t, args|
|
8
|
+
sh "thin -C #{args[:config] || 'config/thin.yml'} #{name}"
|
9
|
+
end
|
10
|
+
}
|
11
|
+
|
12
|
+
end # of thin
|
13
|
+
end # of app
|
metadata
ADDED
@@ -0,0 +1,100 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: godfat-app-deploy
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.5.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- "Lin Jen-Shin (a.k.a. godfat \xE7\x9C\x9F\xE5\xB8\xB8)"
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain: []
|
11
|
+
|
12
|
+
date: 2009-01-13 00:00:00 -08:00
|
13
|
+
default_executable:
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: bones
|
17
|
+
version_requirement:
|
18
|
+
version_requirements: !ruby/object:Gem::Requirement
|
19
|
+
requirements:
|
20
|
+
- - ">="
|
21
|
+
- !ruby/object:Gem::Version
|
22
|
+
version: 2.2.0
|
23
|
+
version:
|
24
|
+
description: ""
|
25
|
+
email: godfat (XD) godfat.org
|
26
|
+
executables: []
|
27
|
+
|
28
|
+
extensions: []
|
29
|
+
|
30
|
+
extra_rdoc_files:
|
31
|
+
- CHANGES
|
32
|
+
- README
|
33
|
+
- TODO
|
34
|
+
- app-deploy.gemspec
|
35
|
+
- example.rake
|
36
|
+
- lib/app-deploy/deploy.rake
|
37
|
+
- lib/app-deploy/gem.rake
|
38
|
+
- lib/app-deploy/git.rake
|
39
|
+
- lib/app-deploy/install.rake
|
40
|
+
- lib/app-deploy/merb.rake
|
41
|
+
- lib/app-deploy/mongrel.rake
|
42
|
+
- lib/app-deploy/nginx.rake
|
43
|
+
- lib/app-deploy/rack.rake
|
44
|
+
- lib/app-deploy/server.rake
|
45
|
+
- lib/app-deploy/thin.rake
|
46
|
+
files:
|
47
|
+
- CHANGES
|
48
|
+
- README
|
49
|
+
- Rakefile
|
50
|
+
- TODO
|
51
|
+
- app-deploy.gemspec
|
52
|
+
- example.rake
|
53
|
+
- lib/app-deploy.rb
|
54
|
+
- lib/app-deploy/deploy.rake
|
55
|
+
- lib/app-deploy/gem.rake
|
56
|
+
- lib/app-deploy/git.rake
|
57
|
+
- lib/app-deploy/install.rake
|
58
|
+
- lib/app-deploy/merb.rake
|
59
|
+
- lib/app-deploy/mongrel.rake
|
60
|
+
- lib/app-deploy/nginx.rake
|
61
|
+
- lib/app-deploy/rack.rake
|
62
|
+
- lib/app-deploy/rack_cluster.rb
|
63
|
+
- lib/app-deploy/rack_daemon.rb
|
64
|
+
- lib/app-deploy/server.rake
|
65
|
+
- lib/app-deploy/thin.rake
|
66
|
+
- lib/app-deploy/version.rb
|
67
|
+
has_rdoc: true
|
68
|
+
homepage: http://github.com/godfat/app-deploy
|
69
|
+
post_install_message:
|
70
|
+
rdoc_options:
|
71
|
+
- --diagram
|
72
|
+
- --charset=utf-8
|
73
|
+
- --inline-source
|
74
|
+
- --line-numbers
|
75
|
+
- --promiscuous
|
76
|
+
- --main
|
77
|
+
- README
|
78
|
+
require_paths:
|
79
|
+
- lib
|
80
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - ">="
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: "0"
|
85
|
+
version:
|
86
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
|
+
requirements:
|
88
|
+
- - ">="
|
89
|
+
- !ruby/object:Gem::Version
|
90
|
+
version: "0"
|
91
|
+
version:
|
92
|
+
requirements: []
|
93
|
+
|
94
|
+
rubyforge_project: ludy
|
95
|
+
rubygems_version: 1.2.0
|
96
|
+
signing_key:
|
97
|
+
specification_version: 2
|
98
|
+
summary: ""
|
99
|
+
test_files: []
|
100
|
+
|