process_control 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,23 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'autotest/restart'
4
+
5
+ # Autotest.add_hook :initialize do |at|
6
+ # at.extra_files << "../some/external/dependency.rb"
7
+ #
8
+ # at.libs << ":../some/external"
9
+ #
10
+ # at.add_exception 'vendor'
11
+ #
12
+ # at.add_mapping(/dependency.rb/) do |f, _|
13
+ # at.files_matching(/test_.*rb$/)
14
+ # end
15
+ #
16
+ # %w(TestA TestB).each do |klass|
17
+ # at.extra_class_map[klass] = "test/test_misc.rb"
18
+ # end
19
+ # end
20
+
21
+ # Autotest.add_hook :run_command do |at|
22
+ # system "rake build"
23
+ # end
File without changes
@@ -0,0 +1,6 @@
1
+ === 1.0.0 / 2011-07-13
2
+
3
+ * 1 major enhancement
4
+
5
+ * Birthday!
6
+
@@ -0,0 +1,8 @@
1
+ .autotest
2
+ History.txt
3
+ Manifest.txt
4
+ README.txt
5
+ Rakefile
6
+ bin/process_control
7
+ lib/process_control.rb
8
+ test/test_process_control.rb
@@ -0,0 +1,93 @@
1
+ = process_control
2
+
3
+ * http://cyberconnect.biz/opensource
4
+
5
+ == DESCRIPTION:
6
+
7
+ Process Control is a wrapper to allow easy control for any external daemon type process. The
8
+ Process Control app is minimal, such that there should never be any errors and the process can
9
+ run in a daemon state yielding a consistant means for controlling a child process. The child
10
+ process being controlled is done so via signals, QUIT, CONT, HUP, USR1 and TERM (see SIGNALS
11
+ section).
12
+
13
+ == FEATURES
14
+
15
+ * Monitor interval: Sleep time between each cycle.
16
+ * Monitor exec: Child command to execute. Command should be a standalone daemon
17
+ that doesn't not exit.
18
+ * Monitor exec_live_cfg, optional config file to be passed to the exec attribute if you have more
19
+ than one config file. If your application being controlled only requires one config file put
20
+ the config parameter in the exec string itself.
21
+ * Monitor exec_maintenance_cfg config file to use when your application is in maintenance mode
22
+ * Monitor kill_signal: Signal to use when stopping the child process, defalting to TERM.
23
+ * Monitor kill_children: If the child process defined by exec launches additional processes,
24
+ kill all children of the exec process.
25
+ * Monitor usr1: User defined Proc to execute. This is usefull for external system monitoring.
26
+ For example, the Proc could create a tmp file, and when USR1 is sent to the process_control pid
27
+ that tmp file would be created. Now the external monotor has an easy means to ensure that the
28
+ process_control process is functioning properly.
29
+ * Monitors the process launched defined by exec, and if not found running, starts it.
30
+
31
+ == SIGNALS
32
+
33
+ Signals need to be sent to the process_control process and not the child spawned. Process Control in turn will perform actions based on the signal provided.
34
+
35
+ * QUIT: Kill the child process, and puts the monitoring of the child process in a halt state. If exec_live_cfg and exec_maintenance_cfg are set, swap the config file from live to maintenance and start the process. Multiple config files are handy when you have down time to a web site and you need to display a certain page to the user while you upgrade your application.
36
+ * CONT: Start the child process, and enables the monitor to restart the child process if found not running. If exec_live_cfg and exec_maintenance_cfg are set the config file is set to live before the application is started.
37
+ * HUP: Restart the child process
38
+ * TERM: Stop both the child process and process_control itself
39
+ * USR1: Execute the Proc code block defined in the config
40
+
41
+ == SYNOPSIS:
42
+
43
+ /usr/bin/process_control --config <full path to config file>
44
+
45
+ Example config file for a web agent running as a daemon, outside of the web framework itself. If
46
+ the code below was saved in a file named /tmp/start_cert.rb you would launch cert.rb via process_control by:
47
+
48
+ process_control --config /tmp/start_cert.rb
49
+
50
+ ProcessControl.run { |monitor|
51
+ monitor.interval = 10
52
+ monitor.exec = "ruby /cyber_platform/vendor/plugins/phased_layer_tunnel/agents/cert.rb"
53
+ monitor.kill_children = true
54
+ monitor.kill_signal='TERM'
55
+ monitor.usr1 = Proc.new {
56
+ status_f = "/share/status/cyber_platform_cert.rb"
57
+ begin
58
+ FileUtils.rm_f status_f if File.exists?(status_f)
59
+ rescue => e
60
+ end
61
+ begin
62
+ fd = File.open(status_f, 'w+')
63
+ fd.close
64
+ rescue => e
65
+ end
66
+ }
67
+ monitor.monitor # required last line, or child process will not be launched
68
+ }
69
+
70
+ Example for nginx hosting a rails application given live and maintenance configurations. When QUIT is sent to process_control the maintenance config file will be utilized so that users will still be able to access the site, but given an explanation there's maintenance. And when CONT is sent, toggle the config back to live, restoring the full functionality of the application:
71
+
72
+ ProcessControl.run { |monitor|
73
+ monitor.interval = 10
74
+ monitor.exec = "/usr/local/nginx/sbin/nginx -c"
75
+ monitor.exec_live_cfg = "/cyber_platform/config/nginx.conf"
76
+ monitor.exec_maintenance_cfg = "/cyber_platform/config/nginx.conf.maintenance"
77
+ monitor.kill_children = false
78
+ monitor.kill_signal='QUIT'
79
+ monitor.monitor # required last line, or child process will not be launched
80
+ }
81
+
82
+
83
+ == REQUIREMENTS:
84
+
85
+ Tested on GNU/Linux, but should work on other variants of Unix type OS's as well.
86
+
87
+ == INSTALL:
88
+
89
+ * sudo gem install process_control
90
+
91
+ == LICENSE:
92
+
93
+ GPLv3: http://www.gnu.org/licenses/gpl.html
@@ -0,0 +1,26 @@
1
+ # -*- ruby -*-
2
+
3
+ require 'rubygems'
4
+ require 'hoe'
5
+
6
+ # Hoe.plugin :compiler
7
+ # Hoe.plugin :gem_prelude_sucks
8
+ # Hoe.plugin :inline
9
+ # Hoe.plugin :racc
10
+ # Hoe.plugin :rubyforge
11
+
12
+ Hoe.spec 'process_control' do
13
+ # HEY! If you fill these out in ~/.hoe_template/Rakefile.erb then
14
+ # you'll never have to touch them again!
15
+ # (delete this comment too, of course)
16
+
17
+ # developer('FIX', 'FIX@example.com')
18
+
19
+ # self.rubyforge_name = 'process_controlx' # if different than 'process_control'
20
+ developer('', 'cliff.cyphers@gmail.com')
21
+ extra_deps << 'platform_helpers'
22
+ extra_deps << 'wait_for'
23
+ extra_deps << 'process_mgt'
24
+ end
25
+
26
+ # vim: syntax=ruby
@@ -0,0 +1,60 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # Authod: Cliff Cyphers
4
+ # Published as part of the cyberconnect's platform mainly used
5
+ # in hosting rails applications.
6
+ # Licesnse: GPLv3: http://www.gnu.org/licenses/gpl.html
7
+
8
+
9
+
10
+ require 'rubygems'
11
+ require 'process_mgt'
12
+ require 'process_control'
13
+ require 'getoptlong'
14
+
15
+ module Init
16
+ def run
17
+ opts = GetoptLong.new( [ '--help', '-h', GetoptLong::NO_ARGUMENT ],
18
+ [ '--config', '-c', GetoptLong::REQUIRED_ARGUMENT ],
19
+ [ '--exec', '-e', GetoptLong::REQUIRED_ARGUMENT ] )
20
+ dir = nil
21
+ name = nil
22
+ repetitions = 1
23
+ opts.each { |opt, arg|
24
+ case opt
25
+ when '--help'
26
+ RDoc::usage
27
+ when '--config'
28
+ type = 'config'
29
+ f = File.expand_path("#{arg}")
30
+ raise StandardError, "config file not found: #{f}" unless File.exists?(f)
31
+ self_pid = Process.pid
32
+ #p "SELF: #{self_pid}"
33
+ all_pids = ProcessMgt.pids_with_children(:search => "--config #{arg}")
34
+ #p "ALL_PIDS: #{all_pids}"
35
+ kill_pids = all_pids.gsub(/#{self_pid}/, '')
36
+ #p "KILL_PIDS: #{kill_pids}"
37
+ ProcessMgt.kill(:pid_list => kill_pids)
38
+ #ProcessMgt.kill(:search => "--config #{arg}")
39
+ load f
40
+ when '--exec'
41
+ type = 'exec'
42
+ begin
43
+ ProcessControl.run { |monitor|
44
+ monitor.interval = 5
45
+ monitor.exec = arg
46
+ monitor.kill_children = true
47
+ monitor.kill_signal='TERM'
48
+ monitor.monitor
49
+ }
50
+ rescue => e
51
+ end
52
+ end
53
+ }
54
+ end
55
+
56
+ module_function :run
57
+ end
58
+
59
+ Init.run
60
+
@@ -0,0 +1,155 @@
1
+ # Authod: Cliff Cyphers
2
+ # Published as part of the cyberconnect's platform mainly used
3
+ # in hosting rails applications.
4
+ # Licesnse: GPLv3: http://www.gnu.org/licenses/gpl.html
5
+
6
+
7
+ require 'rubygems'
8
+ require 'wait_for'
9
+ BASE = File.expand_path(File.dirname(__FILE__)) + '/..'
10
+ require "process_mgt"
11
+
12
+
13
+ class ProcessHellFire
14
+ attr_accessor :exec, :interval, :kill_children, :exec_live_cfg, :exec_maintenance_cfg, :kill_signal, :usr1
15
+ def initialize
16
+ @exec = ''
17
+ @orig_exec = ''
18
+ @wait_until_timeout = 0
19
+ @wait_until_proc = nil
20
+ @kill_children = kill_children
21
+ @interval = interval
22
+ @restart_items = []
23
+ @exec_live_cfg = ''
24
+ @exec_maintenance_cfg = ''
25
+ @kill_signal = 'TERM'
26
+ @restart = true
27
+ @usr1= ''
28
+ @mode = 'live'
29
+ end
30
+
31
+ def logger
32
+ begin
33
+ require BASE + '/lib/log'
34
+ include InlineLogger
35
+ rescue => e
36
+ puts "EEEEE: #{e.inspect}"
37
+ end
38
+ end
39
+
40
+ def wait_until(timeout=10, proc_='')
41
+ raise StandardError unless proc_.kind_of?(Proc)
42
+ @wait_until_timeout = timeout
43
+ @wait_until_proc = proc_
44
+ end
45
+
46
+ def restart_on_condition(condition)
47
+ @restart_items << condition
48
+ end
49
+
50
+
51
+ def monitor
52
+ raise StandardError if @exec == '' || @interval < 2
53
+ set_traps
54
+ while true
55
+ exec = use_exec
56
+ pids = ProcessMgt.pids_with_children(:search => exec, :exclude => 'process_control')
57
+ res=false
58
+ @restart_items.each { |item|
59
+ begin
60
+ next unless item.respond_to?(:call)
61
+ res = item.call
62
+ break if res == true
63
+ rescue => e
64
+ end
65
+ }
66
+ if (pids == '' || res) && @restart
67
+ restart
68
+ end
69
+ sleep @interval
70
+ end
71
+ end
72
+
73
+ def stop
74
+ stop_items = []
75
+
76
+ if @exec_live_cfg == '' && @exec_maintenance_cfg == ''
77
+ stop_items << @exec
78
+ else
79
+ stop_items += [@exec_live_cfg, @exec_maintenance_cfg]
80
+ end
81
+
82
+ stop_items.each { |exec|
83
+ p "stop with exec: #{exec}"
84
+ begin
85
+ if @kill_children
86
+ ProcessMgt.kill(:search => exec, :with_children => nil, :force => true, :exclude => 'process_control')
87
+ else
88
+ ProcessMgt.kill(:search => exec, :signal => @kill_signal, :exclude => 'process_control')
89
+ end
90
+ rescue => e
91
+ puts "EEEEE: #{e.inspect}"
92
+ end
93
+ }
94
+ end
95
+
96
+ def start
97
+ cfg = use_exec
98
+ Thread.new {
99
+ begin
100
+ Process.fork {Process.exec(cfg)}
101
+ @pid, status = Process.wait2
102
+ rescue => e
103
+ p e.inspect
104
+ end
105
+ }
106
+ wait_for(@wait_until_timeout) { @wait_until_proc } if @wait_until_proc.kind_of?(Proc)
107
+ end
108
+
109
+ def restart
110
+ stop
111
+ start
112
+ end
113
+
114
+ def use_exec
115
+ if @exec_live_cfg != '' && @exec_maintenance_cfg != ''
116
+ if @mode == 'live'
117
+ return "#{@exec} #{@exec_live_cfg}"
118
+ else
119
+ return "#{@exec} #{@exec_maintenance_cfg}"
120
+ end
121
+ else
122
+ return @exec
123
+ end
124
+ end
125
+
126
+ def set_traps
127
+ trap('TERM') {
128
+ stop
129
+ exit
130
+ }
131
+ trap('HUP') { restart }
132
+ trap('QUIT') {
133
+ @mode = 'maintenance'
134
+ @restart = false
135
+ restart
136
+ }
137
+ trap('CONT') {
138
+ @mode = 'live'
139
+ restart
140
+ @restart = true
141
+ }
142
+ trap('USR1') { @usr1.call if @usr1.kind_of?(Proc) }
143
+ end
144
+
145
+ private :set_traps, :start, :stop, :restart, :use_exec
146
+ end
147
+
148
+ module ProcessControl
149
+ VERSION = '0.1.0'
150
+ def self.run(&blk)
151
+ raise ArgumentError unless block_given?
152
+ cfg = ProcessHellFire.new()
153
+ yield cfg
154
+ end
155
+ end
@@ -0,0 +1,16 @@
1
+ # Authod: Cliff Cyphers
2
+ # Published as part of the cyberconnect's platform mainly used
3
+ # in hosting rails applications.
4
+ # Licesnse: GPLv3: http://www.gnu.org/licenses/gpl.html
5
+
6
+
7
+ require "./lib/process_control"
8
+ require 'process_mgt'
9
+ require "test/unit"
10
+
11
+ class TestProcessControl < Test::Unit::TestCase
12
+ def test_
13
+ end
14
+
15
+
16
+ end
metadata ADDED
@@ -0,0 +1,114 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: process_control
3
+ version: !ruby/object:Gem::Version
4
+ prerelease:
5
+ version: 0.1.0
6
+ platform: ruby
7
+ authors:
8
+ - ""
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+
13
+ date: 2011-08-22 00:00:00 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: platform_helpers
17
+ prerelease: false
18
+ requirement: &id001 !ruby/object:Gem::Requirement
19
+ none: false
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ type: :runtime
25
+ version_requirements: *id001
26
+ - !ruby/object:Gem::Dependency
27
+ name: wait_for
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: "0"
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: process_mgt
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: "0"
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ - !ruby/object:Gem::Dependency
49
+ name: hoe
50
+ prerelease: false
51
+ requirement: &id004 !ruby/object:Gem::Requirement
52
+ none: false
53
+ requirements:
54
+ - - ~>
55
+ - !ruby/object:Gem::Version
56
+ version: "2.12"
57
+ type: :development
58
+ version_requirements: *id004
59
+ description: |-
60
+ Process Control is a wrapper to allow easy control for any external daemon type process. The
61
+ Process Control app is minimal, such that there should never be any errors and the process can
62
+ run in a daemon state yielding a consistant means for controlling a child process. The child
63
+ process being controlled is done so via signals, QUIT, CONT, HUP, USR1 and TERM (see SIGNALS
64
+ section).
65
+ email:
66
+ - cliff.cyphers@gmail.com
67
+ executables:
68
+ - process_control
69
+ extensions: []
70
+
71
+ extra_rdoc_files:
72
+ - History.txt
73
+ - Manifest.txt
74
+ - README.txt
75
+ files:
76
+ - .autotest
77
+ - History.txt
78
+ - Manifest.txt
79
+ - README.txt
80
+ - Rakefile
81
+ - bin/process_control
82
+ - lib/process_control.rb
83
+ - test/test_process_control.rb
84
+ - .gemtest
85
+ homepage: http://cyberconnect.biz/opensource
86
+ licenses: []
87
+
88
+ post_install_message:
89
+ rdoc_options:
90
+ - --main
91
+ - README.txt
92
+ require_paths:
93
+ - lib
94
+ required_ruby_version: !ruby/object:Gem::Requirement
95
+ none: false
96
+ requirements:
97
+ - - ">="
98
+ - !ruby/object:Gem::Version
99
+ version: "0"
100
+ required_rubygems_version: !ruby/object:Gem::Requirement
101
+ none: false
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: "0"
106
+ requirements: []
107
+
108
+ rubyforge_project: process_control
109
+ rubygems_version: 1.8.8
110
+ signing_key:
111
+ specification_version: 3
112
+ summary: Process Control is a wrapper to allow easy control for any external daemon type process
113
+ test_files:
114
+ - test/test_process_control.rb