rexec 1.2.1 → 1.2.3
Sign up to get free protection for your applications and to get access to all the features.
- data/README.rdoc +59 -12
- data/bin/daemon-exec +17 -12
- data/lib/rexec.rb +22 -26
- data/lib/rexec/client.rb +2 -14
- data/lib/rexec/connection.rb +138 -146
- data/lib/rexec/daemon.rb +20 -20
- data/lib/rexec/daemon/base.rb +157 -142
- data/lib/rexec/daemon/controller.rb +18 -13
- data/lib/rexec/daemon/pidfile.rb +57 -52
- data/lib/rexec/environment.rb +24 -5
- data/lib/rexec/priviledges.rb +42 -23
- data/lib/rexec/reverse_io.rb +86 -67
- data/lib/rexec/server.rb +86 -53
- data/lib/rexec/task.rb +145 -49
- data/lib/rexec/version.rb +23 -18
- data/test/client.rb +17 -12
- data/test/daemon.rb +17 -12
- data/test/daemon_test.rb +17 -12
- data/test/listing_example.rb +17 -12
- data/test/remote_server_test.rb +18 -13
- data/test/server_test.rb +17 -12
- data/test/task.rb +17 -12
- data/test/task_test.rb +17 -12
- metadata +5 -4
data/lib/rexec/daemon.rb
CHANGED
@@ -1,27 +1,27 @@
|
|
1
|
-
# Copyright (c) 2007, 2009 Samuel
|
2
|
-
#
|
3
|
-
# This program is free software: you can redistribute it and/or modify
|
4
|
-
# it under the terms of the GNU General Public License as published by
|
5
|
-
# the Free Software Foundation, either version 3 of the License, or
|
6
|
-
# (at your option) any later version.
|
1
|
+
# Copyright (c) 2007, 2009, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
|
7
2
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
12
9
|
#
|
13
|
-
#
|
14
|
-
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
15
20
|
|
16
21
|
require 'rexec/daemon/base'
|
17
22
|
|
18
23
|
module RExec
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
#def run_daemon(options = {}, &block)
|
23
|
-
#
|
24
|
-
#end
|
25
|
-
|
26
|
-
end
|
24
|
+
module Daemon
|
25
|
+
|
26
|
+
end
|
27
27
|
end
|
data/lib/rexec/daemon/base.rb
CHANGED
@@ -1,151 +1,166 @@
|
|
1
|
-
# Copyright (c) 2007, 2009 Samuel
|
2
|
-
#
|
3
|
-
# This program is free software: you can redistribute it and/or modify
|
4
|
-
# it under the terms of the GNU General Public License as published by
|
5
|
-
# the Free Software Foundation, either version 3 of the License, or
|
6
|
-
# (at your option) any later version.
|
1
|
+
# Copyright (c) 2007, 2009, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
|
7
2
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
12
9
|
#
|
13
|
-
#
|
14
|
-
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
15
20
|
|
16
21
|
require 'fileutils'
|
17
22
|
require 'rexec/daemon/controller'
|
18
23
|
require 'rexec/reverse_io'
|
19
24
|
|
20
25
|
module RExec
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
150
|
-
|
26
|
+
module Daemon
|
27
|
+
# This class is the base daemon class. If you are writing a daemon, you should inherit from this class.
|
28
|
+
#
|
29
|
+
# The basic structure of a daemon is as follows:
|
30
|
+
#
|
31
|
+
# class Server < RExec::Daemon::Base
|
32
|
+
# def self.run
|
33
|
+
# # Long running process, e.g. web server, game server, etc.
|
34
|
+
# end
|
35
|
+
# end
|
36
|
+
#
|
37
|
+
# Server.daemonize
|
38
|
+
class Base
|
39
|
+
@@var_directory = nil
|
40
|
+
@@log_directory = nil
|
41
|
+
@@pid_directory = nil
|
42
|
+
|
43
|
+
# Return the name of the daemon
|
44
|
+
def self.daemon_name
|
45
|
+
return name.gsub(/[^a-zA-Z0-9]+/, '-')
|
46
|
+
end
|
47
|
+
|
48
|
+
# Base directory for daemon log files / run files
|
49
|
+
def self.var_directory
|
50
|
+
@@var_directory || File.join("", "var")
|
51
|
+
end
|
52
|
+
|
53
|
+
# The directory the daemon will run in (Dir.chdir)
|
54
|
+
def self.working_directory
|
55
|
+
var_directory
|
56
|
+
end
|
57
|
+
|
58
|
+
# Return the directory to store log files in
|
59
|
+
def self.log_directory
|
60
|
+
@@log_directory || File.join(var_directory, "log", daemon_name)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Standard log file for errors
|
64
|
+
def self.err_fn
|
65
|
+
File.join(log_directory, "stderr.log")
|
66
|
+
end
|
67
|
+
|
68
|
+
# Standard log file for normal output
|
69
|
+
def self.log_fn
|
70
|
+
File.join(log_directory, "stdout.log")
|
71
|
+
end
|
72
|
+
|
73
|
+
# Standard location of pid file
|
74
|
+
def self.pid_directory
|
75
|
+
@@pid_directory || File.join(var_directory, "run", daemon_name)
|
76
|
+
end
|
77
|
+
|
78
|
+
# Standard pid file
|
79
|
+
def self.pid_fn
|
80
|
+
File.join(pid_directory, "#{daemon_name}.pid")
|
81
|
+
end
|
82
|
+
|
83
|
+
# Mark the error log
|
84
|
+
def self.mark_err_log
|
85
|
+
fp = File.open(err_fn, "a")
|
86
|
+
fp.puts "=== Error Log Opened @ #{Time.now.to_s} ==="
|
87
|
+
fp.close
|
88
|
+
end
|
89
|
+
|
90
|
+
# Prints some information relating to daemon startup problems
|
91
|
+
def self.tail_err_log(outp)
|
92
|
+
lines = []
|
93
|
+
|
94
|
+
File.open(err_fn, "r") do |fp|
|
95
|
+
fp.seek_end
|
96
|
+
|
97
|
+
fp.reverse_each_line do |line|
|
98
|
+
lines << line
|
99
|
+
break if line.match("=== Error Log") || line.match("=== Daemon Exception Backtrace")
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
lines.reverse_each do |line|
|
104
|
+
outp.puts line
|
105
|
+
end
|
106
|
+
end
|
107
|
+
|
108
|
+
# Check the last few lines of the log file to find out if
|
109
|
+
# the daemon crashed.
|
110
|
+
def self.crashed?
|
111
|
+
File.open(err_fn, "r") do |fp|
|
112
|
+
fp.seek_end
|
113
|
+
|
114
|
+
count = 2
|
115
|
+
fp.reverse_each_line do |line|
|
116
|
+
return true if line.match("=== Daemon Crashed")
|
117
|
+
|
118
|
+
count -= 1
|
119
|
+
|
120
|
+
break if count == 0
|
121
|
+
end
|
122
|
+
end
|
123
|
+
|
124
|
+
return false
|
125
|
+
end
|
126
|
+
|
127
|
+
# Corresponds to controller method of the same name
|
128
|
+
def self.daemonize
|
129
|
+
Controller.daemonize(self)
|
130
|
+
end
|
131
|
+
|
132
|
+
# Corresponds to controller method of the same name
|
133
|
+
def self.start
|
134
|
+
Controller.start(self)
|
135
|
+
end
|
136
|
+
|
137
|
+
# Corresponds to controller method of the same name
|
138
|
+
def self.stop
|
139
|
+
Controller.stop(self)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Corresponds to controller method of the same name
|
143
|
+
def self.status
|
144
|
+
Controller.status(self)
|
145
|
+
end
|
146
|
+
|
147
|
+
# The main function to setup any environment required by the daemon
|
148
|
+
def self.prefork
|
149
|
+
@@var_directory = File.expand_path(@@var_directory) if @@var_directory
|
150
|
+
@@log_directory = File.expand_path(@@log_directory) if @@log_directory
|
151
|
+
@@pid_directory = File.expand_path(@@pid_directory) if @@pid_directory
|
152
|
+
|
153
|
+
FileUtils.mkdir_p(log_directory)
|
154
|
+
FileUtils.mkdir_p(pid_directory)
|
155
|
+
end
|
156
|
+
|
157
|
+
# The main function to start the daemon
|
158
|
+
def self.run
|
159
|
+
end
|
160
|
+
|
161
|
+
# The main function to stop the daemon
|
162
|
+
def self.shutdown
|
163
|
+
end
|
164
|
+
end
|
165
|
+
end
|
151
166
|
end
|
@@ -1,17 +1,22 @@
|
|
1
|
-
# Copyright (c) 2007, 2009 Samuel
|
2
|
-
#
|
3
|
-
# This program is free software: you can redistribute it and/or modify
|
4
|
-
# it under the terms of the GNU General Public License as published by
|
5
|
-
# the Free Software Foundation, either version 3 of the License, or
|
6
|
-
# (at your option) any later version.
|
1
|
+
# Copyright (c) 2007, 2009, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
|
7
2
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
12
9
|
#
|
13
|
-
#
|
14
|
-
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
15
20
|
|
16
21
|
require 'rexec/daemon/pidfile'
|
17
22
|
require 'rexec/task'
|
@@ -24,7 +29,7 @@ module RExec
|
|
24
29
|
# This module contains functionality related to starting and stopping the daemon, and code for processing command line input.
|
25
30
|
module Controller
|
26
31
|
# This function is called from the daemon executable. It processes ARGV and checks whether the user is asking for
|
27
|
-
#
|
32
|
+
# +start+, +stop+, +restart+ or +status+.
|
28
33
|
def self.daemonize(daemon)
|
29
34
|
#puts "Running in #{WorkingDirectory}, logs in #{LogDirectory}"
|
30
35
|
case !ARGV.empty? && ARGV[0]
|
data/lib/rexec/daemon/pidfile.rb
CHANGED
@@ -1,64 +1,69 @@
|
|
1
|
-
# Copyright (c) 2007, 2009 Samuel
|
2
|
-
#
|
3
|
-
# This program is free software: you can redistribute it and/or modify
|
4
|
-
# it under the terms of the GNU General Public License as published by
|
5
|
-
# the Free Software Foundation, either version 3 of the License, or
|
6
|
-
# (at your option) any later version.
|
1
|
+
# Copyright (c) 2007, 2009, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
|
7
2
|
#
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
11
|
-
#
|
3
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
4
|
+
# of this software and associated documentation files (the "Software"), to deal
|
5
|
+
# in the Software without restriction, including without limitation the rights
|
6
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
7
|
+
# copies of the Software, and to permit persons to whom the Software is
|
8
|
+
# furnished to do so, subject to the following conditions:
|
12
9
|
#
|
13
|
-
#
|
14
|
-
#
|
10
|
+
# The above copyright notice and this permission notice shall be included in
|
11
|
+
# all copies or substantial portions of the Software.
|
12
|
+
#
|
13
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
14
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
15
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
16
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
17
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
18
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
19
|
+
# THE SOFTWARE.
|
15
20
|
|
16
21
|
module RExec
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
22
|
+
module Daemon
|
23
|
+
# This module controls the storage and retrieval of process id files.
|
24
|
+
module PidFile
|
25
|
+
# Saves the pid for the given daemon
|
26
|
+
def self.store(daemon, pid)
|
27
|
+
File.open(daemon.pid_fn, 'w') {|f| f << pid}
|
28
|
+
end
|
29
|
+
|
30
|
+
# Retrieves the pid for the given daemon
|
31
|
+
def self.recall(daemon)
|
32
|
+
IO.read(daemon.pid_fn).to_i rescue nil
|
33
|
+
end
|
24
34
|
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
35
|
+
# Removes the pid saved for a particular daemon
|
36
|
+
def self.clear(daemon)
|
37
|
+
if File.exist? daemon.pid_fn
|
38
|
+
FileUtils.rm(daemon.pid_fn)
|
39
|
+
end
|
40
|
+
end
|
29
41
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
FileUtils.rm(daemon.pid_fn)
|
34
|
-
end
|
35
|
-
end
|
42
|
+
# Checks whether the daemon is running by checking the saved pid and checking the corresponding process
|
43
|
+
def self.running(daemon)
|
44
|
+
pid = recall(daemon)
|
36
45
|
|
37
|
-
|
38
|
-
def self.running(daemon)
|
39
|
-
pid = recall(daemon)
|
46
|
+
return false if pid == nil
|
40
47
|
|
41
|
-
|
48
|
+
gpid = Process.getpgid(pid) rescue nil
|
42
49
|
|
43
|
-
|
50
|
+
return gpid != nil ? true : false
|
51
|
+
end
|
44
52
|
|
45
|
-
|
46
|
-
|
53
|
+
# Remove the pid file if the daemon is not running
|
54
|
+
def self.cleanup(daemon)
|
55
|
+
clear(daemon) unless running(daemon)
|
56
|
+
end
|
47
57
|
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
return :stopped
|
60
|
-
end
|
61
|
-
end
|
62
|
-
end
|
63
|
-
end
|
58
|
+
# This function returns the status of the daemon. This can be one of +:running+, +:unknown+ (pid file exists but no
|
59
|
+
# corresponding process can be found) or +:stopped+.
|
60
|
+
def self.status(daemon)
|
61
|
+
if File.exist? daemon.pid_fn
|
62
|
+
return PidFile.running(daemon) ? :running : :unknown
|
63
|
+
else
|
64
|
+
return :stopped
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
64
69
|
end
|