rails_pwnerer 0.5.16 → 0.5.17

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/CHANGELOG CHANGED
@@ -1,3 +1,5 @@
1
+ v0.5.17. Ability to call custom scripts during an app's lifecycle.
2
+
1
3
  v0.5.16. Letter-based database passwords (ruby's mysql doesn't like numbers).
2
4
 
3
5
  v0.5.15. Home-baked process info (in case Sys::Proctable doesn't work).
data/Manifest CHANGED
@@ -8,6 +8,7 @@ lib/pwnage/app/database.rb
8
8
  lib/pwnage/app/gems.rb
9
9
  lib/pwnage/app/main.rb
10
10
  lib/pwnage/app/nginx_config.rb
11
+ lib/pwnage/app/scripts.rb
11
12
  lib/pwnage/app/svn.rb
12
13
  lib/pwnage/base/atomics.rb
13
14
  lib/pwnage/base/dirs.rb
@@ -36,6 +37,8 @@ lib/pwnage/scaffolds/mysql_config.rb
36
37
  lib/pwnage/scaffolds/packages.rb
37
38
  lib/pwnage/scaffolds/rubygems.rb
38
39
  lib/pwnage/scaffolds/sshd.rb
40
+ lib/pwnage/util/kill_process_set.rb
41
+ lib/pwnage/util/main.rb
39
42
  lib/rails_pwnerer.rb
40
43
  LICENSE
41
44
  Manifest
@@ -59,67 +59,28 @@ class RailsPwnage::App::ClusterConfig
59
59
  def remove_mongrels(app_name, instance_name)
60
60
  # bomb the configuration from the launch directory
61
61
  launch_config = File.join RailsPwnage::Config.path_to(:mongrel_configs), "#{app_name}.#{instance_name}.yml"
62
- File.delete launch_config if File.exists? launch_config
62
+ File.delete launch_config if File.exists? launch_config
63
63
  end
64
64
 
65
- def kill_stray_mongrels(app_name, instance_name)
66
- app_config = RailsPwnage::Config[app_name, instance_name]
67
- # silently die if the app was completely busted
68
- return unless app_config and File.exists? app_config[:app_path]
69
-
70
- # a list of patterns that show up in mongrels' cmdline
71
- patterns = ['mongrel', app_config[:app_path] + ' ', 'tmp/pids/mongrel', 'log/mongrel']
72
-
73
- Dir.chdir app_config[:app_path] do
74
- # Phase 1: look through PID files and issue kill orders
75
- pinfo = process_info()
76
- Dir.glob('tmp/pids/*.pid').each do |fname|
77
- begin
78
- pid = File.open(fname, 'r') { |f| f.read.strip! }
79
- # avoid killing innocent victims
80
- if pinfo[pid].nil? or patterns.all? { |pattern| pinfo[pid][:cmdline].index pattern }
81
- print "Killing #{pid}: #{pinfo[pid][:cmdline]}\n"
82
- Process.kill 'TERM', pid.to_i
83
- end
84
- rescue
85
- # just in case the file gets wiped before we see it
86
- end
87
- begin
88
- print "Deleting #{fname}\n"
89
- File.delete fname if File.exists? fname
90
- rescue
91
- # prevents crashing if the file is wiped after we call exists?
92
- end
93
- end
94
-
95
- # Phase 2: look through the process table and kill anything that looks good
96
- pinfo = process_info()
97
- pinfo.each do |pid, info|
98
- next unless patterns.all? { |pattern| info[:cmdline].index pattern }
99
- print "Killing #{pid}: #{pinfo[pid][:cmdline]}\n"
100
- Process.kill 'TERM', pid.to_i
101
- end
102
- end
103
- end
104
-
105
- def stop_mongrels(app_name, instance_name)
65
+ def stop(app_name, instance_name)
106
66
  app_config = RailsPwnage::Config[app_name, instance_name]
107
67
  # silently die if the app was completely busted
108
68
  return unless app_config and File.exists? app_config[:app_path]
69
+
70
+ cmdline_patterns = ['mongrel', app_config[:app_path] + ' ', 'tmp/pids/mongrel', 'log/mongrel']
109
71
 
110
72
  Dir.chdir app_config[:app_path] do
111
- Kernel.system 'mongrel_rails cluster::stop'
73
+ RailsPwnage::Util.kill_process_set('mongrel_rails cluster::stop',
74
+ 'tmp/pids/*.pid', cmdline_patterns, :verbose => false, :sleep_delay => 0.5)
112
75
  end
113
- sleep 0.5
114
- kill_stray_mongrels app_name, instance_name
115
76
  end
116
77
 
117
- def start_mongrels(app_name, instance_name)
78
+ def start(app_name, instance_name)
118
79
  app_config = RailsPwnage::Config[app_name, instance_name]
119
80
  # silently die if the app was completely busted
120
81
  return unless app_config and File.exists? app_config[:app_path]
121
82
 
122
- kill_stray_mongrels app_name, instance_name
83
+ stop app_name, instance_name
123
84
 
124
85
  # alloc a port if somehow that slipped through the cracks
125
86
  if app_config[:port0] == 0
@@ -140,20 +101,17 @@ class RailsPwnage::App::ClusterConfig
140
101
  # no need to configure nginx here, it'll be done by the executor
141
102
  end
142
103
 
143
- def update(app_name, instance_name, &update_proc)
144
- stop_mongrels app_name, instance_name
104
+ def pre_update(app_name, instance_name, &update_proc)
145
105
  manage_ports app_name, instance_name, :free
146
- yield
147
- ensure
106
+ end
107
+ def post_update(app_name, instance_name)
148
108
  manage_ports app_name, instance_name, :alloc
149
109
  configure_mongrels app_name, instance_name
150
110
  fix_permissions app_name, instance_name
151
- start_mongrels app_name, instance_name
152
- RailsPwnage::App::NginxConfig.new.update app_name, instance_name
153
111
  end
154
112
 
155
113
  def remove(app_name, instance_name)
156
- stop_mongrels app_name, instance_name
114
+ stop app_name, instance_name
157
115
  remove_mongrels app_name, instance_name
158
116
  manage_ports app_name, instance_name, :free
159
117
  end
@@ -172,9 +130,9 @@ class RailsPwnage::App::ClusterConfig
172
130
  RailsPwnage::Config.all_applications.each do |ai|
173
131
  case action
174
132
  when :start
175
- RailsPwnage::App::ClusterConfig.new.start_mongrels ai[0], ai[1]
133
+ RailsPwnage::App::ClusterConfig.new.start ai[0], ai[1]
176
134
  when :stop
177
- RailsPwnage::App::ClusterConfig.new.stop_mongrels ai[0], ai[1]
135
+ RailsPwnage::App::ClusterConfig.new.stop ai[0], ai[1]
178
136
  end
179
137
  end
180
138
  end
@@ -18,7 +18,7 @@ module RailsPwnage::App
18
18
  Config.new.alloc app, instance
19
19
  rails_root = Svn.new.checkout svn_path, app, instance
20
20
  if rails_root
21
- [Config, Svn, Gems, Database, ClusterConfig, NginxConfig].each do |mod|
21
+ [Config, Svn, Gems, Database, ClusterConfig, NginxConfig, Scripts].each do |mod|
22
22
  mod.new.setup app, instance
23
23
  end
24
24
  else
@@ -32,9 +32,9 @@ module RailsPwnage::App
32
32
  # updates an application (restart servers if necessary)
33
33
  def self.update(app_name, instance_name)
34
34
  instance_magic(app_name, instance_name) do |app, instance|
35
- ClusterConfig.new.update app, instance do
36
- [Svn, Config, Gems, Database].each do |mod|
37
- mod.new.update app, instance
35
+ update_app app, instance do
36
+ [Svn, Config, Gems, Database, Scripts].each do |mod|
37
+ mod.new.update app, instance
38
38
  end
39
39
  end
40
40
  NginxConfig.new.update app, instance
@@ -50,6 +50,20 @@ module RailsPwnage::App
50
50
  end
51
51
  end
52
52
 
53
+ def self.update_app(app_name, instance_name, &block)
54
+ Scripts.new.pre_stop app_name, instance_name
55
+ ClusterConfig.new.stop app_name, instance_name
56
+ ClusterConfig.new.pre_update app_name, instance_name
57
+ Scripts.new.post_stop app_name, instance_name
58
+ yield
59
+ ensure
60
+ ClusterConfig.new.post_update app_name, instance_name
61
+ NginxConfig.new.update app_name, instance_name
62
+ Scripts.new.pre_start app_name, instance_name
63
+ ClusterConfig.new.start app_name, instance_name
64
+ Scripts.new.post_start app_name, instance_name
65
+ end
66
+
53
67
  # performs application management (checkpoint / rollback / console)
54
68
  def self.manage(app_name, instance_name, action = :checkpoint)
55
69
  instance_magic(app_name, instance_name) do |app, instance|
@@ -58,11 +72,11 @@ module RailsPwnage::App
58
72
  when :checkpoint
59
73
  ClusterConfig.new.manage app, instance, action
60
74
  Svn.new.manage app, instance, action
61
- ClusterConfig.new.update app, instance do
75
+ self.update_app app, instance do
62
76
  Database.new.manage app, instance, action
63
77
  end
64
78
  when :rollback
65
- ClusterConfig.new.update app, instance do
79
+ self.update_app app, instance do
66
80
  [Svn, Database, ClusterConfig].each do |mod|
67
81
  mod.new.manage app, instance, action
68
82
  end
@@ -80,11 +94,15 @@ module RailsPwnage::App
80
94
  case action
81
95
  when :start
82
96
  Database.new.control_all :start
97
+ Scripts.new.control_all :pre_start
83
98
  ClusterConfig.new.control_all :start
84
99
  NginxConfig.new.control_all :start
100
+ Scripts.new.control_all :post_start
85
101
  when :stop
102
+ Scripts.new.control_all :pre_stop
86
103
  NginxConfig.new.control_all :stop
87
104
  ClusterConfig.new.control_all :stop
105
+ Scripts.new.control_all :post_stop
88
106
  Database.new.control_all :stop
89
107
  end
90
108
  end
@@ -0,0 +1,72 @@
1
+ # runs custom scripts on app events
2
+
3
+ class RailsPwnage::App::Scripts
4
+ include RailsPwnage::Base
5
+
6
+ def run_script(app_name, instance_name, script_name)
7
+ app_config = RailsPwnage::Config[app_name, instance_name]
8
+ pwnerer_user = app_config[:pwnerer_user]
9
+ pwnerer_uid = uid_for_username(pwnerer_user)
10
+ pwnerer_gid = gid_for_username(pwnerer_user)
11
+
12
+ return unless app_path = app_config[:app_path]
13
+
14
+ Dir.chdir app_path do
15
+ script_file = Dir.glob(File.join('script/rails_pwnerer', script_name + '*')).first
16
+ return if script_file.nil?
17
+ # make sure the script is executable
18
+ mode = File.stat(script_file).mode
19
+ File.chmod((mode | 0100) & 0777, script_file)
20
+ File.chown(pwnerer_uid, pwnerer_gid, script_file)
21
+
22
+ # run the script under the app's user
23
+ pid = Process.fork do
24
+ Process.uid = pwnerer_uid
25
+ Process.gid = pwnerer_gid
26
+ Process.egid = pwnerer_gid
27
+ Process.euid = pwnerer_uid
28
+ Dir.chdir app_path do
29
+ script_prefix = (script_file[0] == ?/) ? '' : './'
30
+ Kernel.system %Q|#{script_prefix}#{script_file} "#{app_name}" "#{instance_name}"|
31
+ end
32
+ end
33
+ Process.wait pid
34
+ end
35
+ end
36
+
37
+ def setup(app_name, instance_name)
38
+ run_script app_name, instance_name, 'setup'
39
+ end
40
+
41
+ def update(app_name, instance_name)
42
+ run_script app_name, instance_name, 'update'
43
+ end
44
+
45
+ def remove(app_name, instance_name)
46
+ run_script app_name, instance_name, 'remove'
47
+ end
48
+
49
+ def pre_start(app_name, instance_name)
50
+ run_script app_name, instance_name, 'pre_start'
51
+ end
52
+ def post_start(app_name, instance_name)
53
+ run_script app_name, instance_name, 'post_start'
54
+ end
55
+ def pre_stop(app_name, instance_name)
56
+ run_script app_name, instance_name, 'pre_stop'
57
+ end
58
+ def post_stop(app_name, instance_name)
59
+ run_script app_name, instance_name, 'post_stop'
60
+ end
61
+
62
+ def control_all(action)
63
+ RailsPwnage::Config.all_applications.each do |ai|
64
+ run_script ai[0], ai[1], (case action
65
+ when :pre_start then 'pre_start'
66
+ when :post_start then 'post_start'
67
+ when :pre_stop then 'pre_stop'
68
+ when :post_stop then 'post_stop'
69
+ end)
70
+ end
71
+ end
72
+ end
@@ -0,0 +1,52 @@
1
+ module RailsPwnage::Util
2
+ # Complex procedure for killing a process or a bunch of process replicas
3
+ # kill_command is the script that's supposed to kill the process / processes (tried first)
4
+ # pid_patters are globs identifying PID files (a file can match any of the patterns)
5
+ # process_patterns are strings that should show on a command line (a process must match all)
6
+ # options:
7
+ # :verbose - display what gets killed
8
+ # :script_delay - the amount of seconds to sleep after launching the kill script
9
+ # :force_script - the kill script is executed even if there are no PID files
10
+ def self.kill_process_set(kill_script, pid_patterns, process_patterns, options = {})
11
+ # Phase 1: kill order (only if there's a PID file)
12
+ pid_patterns = [pid_patterns] unless pid_patterns.kind_of? Enumerable
13
+ unless options[:force_script]
14
+ pid_files = pid_patterns.map { |pattern| Dir.glob(pattern) }.flatten
15
+ unless pid_files.empty?
16
+ Kernel.system kill_script unless kill_script.nil?
17
+ sleep options[:script_delay] || 0.5
18
+ end
19
+ end
20
+
21
+ # Phase 2: look through PID files and issue kill orders
22
+ pinfo = process_info()
23
+ pid_files = pid_patterns.map { |pattern| Dir.glob(pattern) }.flatten
24
+ pid_files.each do |fname|
25
+ begin
26
+ pid = File.open(fname, 'r') { |f| f.read.strip! }
27
+ process_cmdline = pinfo[pid][:cmdline]
28
+ # avoid killing innocent victims
29
+ if pinfo[pid].nil? or process_patterns.all? { |pattern| process_cmdline.index pattern }
30
+ print "Killing #{pid}: #{process_cmdline}\n"
31
+ Process.kill 'TERM', pid.to_i
32
+ end
33
+ rescue
34
+ # just in case the file gets wiped before we see it
35
+ end
36
+ begin
37
+ print "Deleting #{fname}\n"
38
+ File.delete fname if File.exists? fname
39
+ rescue
40
+ # prevents crashing if the file is wiped after we call exists?
41
+ end
42
+ end
43
+
44
+ # Phase 3: look through the process table and kill anything that looks good
45
+ pinfo = process_info()
46
+ pinfo.each do |pid, info|
47
+ next unless process_patterns.all? { |pattern| info[:cmdline].index pattern }
48
+ print "Killing #{pid}: #{pinfo[pid][:cmdline]}\n"
49
+ Process.kill 'TERM', pid.to_i
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,5 @@
1
+ module RailsPwnage::Util
2
+ class << self
3
+ include RailsPwnage::Base
4
+ end
5
+ end
data/lib/rails_pwnerer.rb CHANGED
@@ -21,6 +21,9 @@ require 'pwnage/base/process.rb'
21
21
  require 'pwnage/base/rails.rb'
22
22
  require 'pwnage/base/startup.rb'
23
23
 
24
+ require 'pwnage/util/main.rb'
25
+ require 'pwnage/util/kill_process_set.rb'
26
+
24
27
  require 'pwnage/config/app.rb'
25
28
  require 'pwnage/config/main.rb'
26
29
  require 'pwnage/config/paths.rb'
@@ -44,6 +47,7 @@ require 'pwnage/app/cluster_config.rb'
44
47
  require 'pwnage/app/database.rb'
45
48
  require 'pwnage/app/gems.rb'
46
49
  require 'pwnage/app/nginx_config.rb'
50
+ require 'pwnage/app/scripts.rb'
47
51
  require 'pwnage/app/svn.rb'
48
52
 
49
53
  require 'pwnage/ctl_executor.rb'
@@ -1,18 +1,18 @@
1
1
 
2
- # Gem::Specification for Rails_pwnerer-0.5.16
2
+ # Gem::Specification for Rails_pwnerer-0.5.17
3
3
  # Originally generated by Echoe
4
4
 
5
5
  --- !ruby/object:Gem::Specification
6
6
  name: rails_pwnerer
7
7
  version: !ruby/object:Gem::Version
8
- version: 0.5.16
8
+ version: 0.5.17
9
9
  platform: ruby
10
10
  authors:
11
11
  - Victor Costan
12
12
  autorequire:
13
13
  bindir: bin
14
14
 
15
- date: 2008-08-25 00:00:00 -04:00
15
+ date: 2008-08-27 00:00:00 -04:00
16
16
  default_executable:
17
17
  dependencies:
18
18
  - !ruby/object:Gem::Dependency
@@ -44,6 +44,7 @@ extra_rdoc_files:
44
44
  - lib/pwnage/app/gems.rb
45
45
  - lib/pwnage/app/main.rb
46
46
  - lib/pwnage/app/nginx_config.rb
47
+ - lib/pwnage/app/scripts.rb
47
48
  - lib/pwnage/app/svn.rb
48
49
  - lib/pwnage/base/atomics.rb
49
50
  - lib/pwnage/base/dirs.rb
@@ -72,6 +73,8 @@ extra_rdoc_files:
72
73
  - lib/pwnage/scaffolds/packages.rb
73
74
  - lib/pwnage/scaffolds/rubygems.rb
74
75
  - lib/pwnage/scaffolds/sshd.rb
76
+ - lib/pwnage/util/kill_process_set.rb
77
+ - lib/pwnage/util/main.rb
75
78
  - lib/rails_pwnerer.rb
76
79
  - LICENSE
77
80
  - README
@@ -86,6 +89,7 @@ files:
86
89
  - lib/pwnage/app/gems.rb
87
90
  - lib/pwnage/app/main.rb
88
91
  - lib/pwnage/app/nginx_config.rb
92
+ - lib/pwnage/app/scripts.rb
89
93
  - lib/pwnage/app/svn.rb
90
94
  - lib/pwnage/base/atomics.rb
91
95
  - lib/pwnage/base/dirs.rb
@@ -114,6 +118,8 @@ files:
114
118
  - lib/pwnage/scaffolds/packages.rb
115
119
  - lib/pwnage/scaffolds/rubygems.rb
116
120
  - lib/pwnage/scaffolds/sshd.rb
121
+ - lib/pwnage/util/kill_process_set.rb
122
+ - lib/pwnage/util/main.rb
117
123
  - lib/rails_pwnerer.rb
118
124
  - LICENSE
119
125
  - Manifest
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_pwnerer
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.16
4
+ version: 0.5.17
5
5
  platform: ruby
6
6
  authors:
7
7
  - Victor Costan
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2008-08-25 00:00:00 -04:00
12
+ date: 2008-08-27 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -41,6 +41,7 @@ extra_rdoc_files:
41
41
  - lib/pwnage/app/gems.rb
42
42
  - lib/pwnage/app/main.rb
43
43
  - lib/pwnage/app/nginx_config.rb
44
+ - lib/pwnage/app/scripts.rb
44
45
  - lib/pwnage/app/svn.rb
45
46
  - lib/pwnage/base/atomics.rb
46
47
  - lib/pwnage/base/dirs.rb
@@ -69,6 +70,8 @@ extra_rdoc_files:
69
70
  - lib/pwnage/scaffolds/packages.rb
70
71
  - lib/pwnage/scaffolds/rubygems.rb
71
72
  - lib/pwnage/scaffolds/sshd.rb
73
+ - lib/pwnage/util/kill_process_set.rb
74
+ - lib/pwnage/util/main.rb
72
75
  - lib/rails_pwnerer.rb
73
76
  - LICENSE
74
77
  - README
@@ -83,6 +86,7 @@ files:
83
86
  - lib/pwnage/app/gems.rb
84
87
  - lib/pwnage/app/main.rb
85
88
  - lib/pwnage/app/nginx_config.rb
89
+ - lib/pwnage/app/scripts.rb
86
90
  - lib/pwnage/app/svn.rb
87
91
  - lib/pwnage/base/atomics.rb
88
92
  - lib/pwnage/base/dirs.rb
@@ -111,6 +115,8 @@ files:
111
115
  - lib/pwnage/scaffolds/packages.rb
112
116
  - lib/pwnage/scaffolds/rubygems.rb
113
117
  - lib/pwnage/scaffolds/sshd.rb
118
+ - lib/pwnage/util/kill_process_set.rb
119
+ - lib/pwnage/util/main.rb
114
120
  - lib/rails_pwnerer.rb
115
121
  - LICENSE
116
122
  - Manifest