godfat-app-deploy 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
data/CHANGES ADDED
@@ -0,0 +1,3 @@
1
+
2
+ 2008-12-10
3
+ bundle as gem
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
@@ -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
@@ -0,0 +1,4 @@
1
+ = app-deploy todo list
2
+
3
+ * escape \" and \' in options?
4
+ * extract rack-cluster
@@ -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
@@ -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
@@ -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,13 @@
1
+
2
+ namespace :app do
3
+ namespace :mongrel do
4
+
5
+ [:start, :stop, :restart].each{ |name|
6
+ desc "#{name} the mongrel cluster"
7
+ task name do
8
+ sh "mongrel_rails cluster::#{name}"
9
+ end
10
+ }
11
+
12
+ end # of mongrel
13
+ 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,9 @@
1
+
2
+ namespace :app do
3
+ namespace :server do
4
+
5
+ desc 'please define your server:restart task'
6
+ task :restart
7
+
8
+ end # of server
9
+ end # of app
@@ -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
@@ -0,0 +1,4 @@
1
+
2
+ module AppDeploy
3
+ VERSION = '0.5.0'
4
+ end
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
+