rexec 1.2.1 → 1.2.3
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/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/README.rdoc
CHANGED
@@ -1,14 +1,61 @@
|
|
1
1
|
= RExec
|
2
2
|
|
3
|
-
Author:: Samuel Williams (http://www.oriontransfer.co.nz
|
4
|
-
Copyright:: Copyright (C) 2009,
|
5
|
-
License::
|
6
|
-
|
7
|
-
RExec stands for
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
* A
|
12
|
-
*
|
13
|
-
* A
|
14
|
-
*
|
3
|
+
Author:: Samuel G. D. Williams (http://www.oriontransfer.co.nz)
|
4
|
+
Copyright:: Copyright (C) 2007, 2009, 2011 Samuel G. D. Williams
|
5
|
+
License:: MIT
|
6
|
+
|
7
|
+
RExec stands for Remote Execute and provides support for executing processes
|
8
|
+
both locally and remotely. It provides a number of different tools to assist
|
9
|
+
with running Ruby code:
|
10
|
+
|
11
|
+
* A framework to send Ruby code to a remote server for execution.
|
12
|
+
* A framework for writing command line daemons (i.e. +start+, +restart+, +stop+, +status+).
|
13
|
+
* A comprehensive +Task+ class for launching tasks, managing input and output, exit status, etc.
|
14
|
+
* Basic privilege management code for changing the processes owner.
|
15
|
+
* A bunch of helpers for various different things (such as reading a file backwards).
|
16
|
+
* +daemon-exec+ executable for running regular shell tasks in the background.
|
17
|
+
|
18
|
+
== Comprehensive process management
|
19
|
+
|
20
|
+
+RExec::Task+ provides a comprehensive wrapper for low level process execution
|
21
|
+
and life-cycle management. You can easy spawn new child processes, background
|
22
|
+
processes and execute Ruby code in a child instance.
|
23
|
+
|
24
|
+
== Light weight bi-directional communication
|
25
|
+
|
26
|
+
The +RExec::Connection+ provides a simple process based API for communicating
|
27
|
+
with distant instances of Ruby. These can either be local or remote, such
|
28
|
+
as over SSH.
|
29
|
+
|
30
|
+
== Simple daemonization
|
31
|
+
|
32
|
+
The +RExec::Daemon+ module provides the foundation to develop long-running
|
33
|
+
background processes. Simply create a daemon class which inherits from
|
34
|
+
+RExec::Daemon::Base+ and you can have a fully featured background daemon
|
35
|
+
with the standard command line interface, e.g. +start+, +restart+, +status+
|
36
|
+
and +stop+.
|
37
|
+
|
38
|
+
Along with this, a executable is included called +daemon-exec+ which allows
|
39
|
+
for any standard shell script to be run as a background process.
|
40
|
+
|
41
|
+
== License
|
42
|
+
|
43
|
+
Copyright (c) 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
|
44
|
+
|
45
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
46
|
+
of this software and associated documentation files (the "Software"), to deal
|
47
|
+
in the Software without restriction, including without limitation the rights
|
48
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
49
|
+
copies of the Software, and to permit persons to whom the Software is
|
50
|
+
furnished to do so, subject to the following conditions:
|
51
|
+
|
52
|
+
The above copyright notice and this permission notice shall be included in
|
53
|
+
all copies or substantial portions of the Software.
|
54
|
+
|
55
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
56
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
57
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
58
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
59
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
60
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
61
|
+
THE SOFTWARE.
|
data/bin/daemon-exec
CHANGED
@@ -1,19 +1,24 @@
|
|
1
1
|
#!/usr/bin/env ruby
|
2
2
|
|
3
|
-
# Copyright (c) 2010 Samuel
|
4
|
-
#
|
5
|
-
# This program is free software: you can redistribute it and/or modify
|
6
|
-
# it under the terms of the GNU General Public License as published by
|
7
|
-
# the Free Software Foundation, either version 3 of the License, or
|
8
|
-
# (at your option) any later version.
|
3
|
+
# Copyright (c) 2010, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
|
9
4
|
#
|
10
|
-
#
|
11
|
-
#
|
12
|
-
#
|
13
|
-
#
|
5
|
+
# Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
|
+
# of this software and associated documentation files (the "Software"), to deal
|
7
|
+
# in the Software without restriction, including without limitation the rights
|
8
|
+
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
9
|
+
# copies of the Software, and to permit persons to whom the Software is
|
10
|
+
# furnished to do so, subject to the following conditions:
|
14
11
|
#
|
15
|
-
#
|
16
|
-
#
|
12
|
+
# The above copyright notice and this permission notice shall be included in
|
13
|
+
# all copies or substantial portions of the Software.
|
14
|
+
#
|
15
|
+
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
16
|
+
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
17
|
+
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
18
|
+
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
19
|
+
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
20
|
+
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
21
|
+
# THE SOFTWARE.
|
17
22
|
|
18
23
|
require 'rubygems'
|
19
24
|
|
data/lib/rexec.rb
CHANGED
@@ -1,33 +1,29 @@
|
|
1
|
-
# Copyright (c) 2007 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
|
-
#
|
15
|
-
|
16
|
-
#
|
17
|
-
#
|
18
|
-
#
|
19
|
-
#
|
20
|
-
#
|
21
|
-
#
|
22
|
-
#
|
23
|
-
# possible on the end user of this library, while still maintaining a level
|
24
|
-
# of convenience.
|
25
|
-
#
|
26
|
-
# Author:: Samuel Williams (samuel AT oriontransfer DOT org)
|
27
|
-
# Copyright:: Copyright (c) 2009 Samuel Williams.
|
28
|
-
# License:: Released under the GNU GPLv3.
|
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.
|
29
20
|
|
30
21
|
require 'rexec/version'
|
31
22
|
require 'rexec/connection'
|
32
23
|
require 'rexec/server'
|
33
24
|
require 'rexec/priviledges'
|
25
|
+
|
26
|
+
## RExec is a tool to assist with the execution of other processes.
|
27
|
+
module RExec
|
28
|
+
|
29
|
+
end
|
data/lib/rexec/client.rb
CHANGED
@@ -1,17 +1,5 @@
|
|
1
|
-
# Copyright (c) 2007 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.
|
7
|
-
#
|
8
|
-
# This program is distributed in the hope that it will be useful,
|
9
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
-
# GNU General Public License for more details.
|
12
|
-
#
|
13
|
-
# You should have received a copy of the GNU General Public License
|
14
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
1
|
+
# Copyright (c) 2007, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
|
2
|
+
# Released under the MIT license. Please see LICENSE.txt for license details.
|
15
3
|
|
16
4
|
# This code is executed in a remote ruby process.
|
17
5
|
|
data/lib/rexec/connection.rb
CHANGED
@@ -1,153 +1,145 @@
|
|
1
|
-
# Copyright (c) 2007 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.
|
7
|
-
#
|
8
|
-
# This program is distributed in the hope that it will be useful,
|
9
|
-
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
10
|
-
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
11
|
-
# GNU General Public License for more details.
|
12
|
-
#
|
13
|
-
# You should have received a copy of the GNU General Public License
|
14
|
-
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
1
|
+
# Copyright (c) 2007, 2011 Samuel G. D. Williams. <http://www.oriontransfer.co.nz>
|
2
|
+
# Released under the MIT license. Please see LICENSE.txt for license details.
|
15
3
|
|
16
4
|
# This class is as small and independant as possible as it will get sent to clients for execution.
|
17
5
|
|
18
6
|
require 'thread'
|
19
7
|
|
20
8
|
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
|
-
|
151
|
-
|
152
|
-
|
9
|
+
|
10
|
+
# This class represents an abstract connection to another ruby process. The interface does not impose
|
11
|
+
# any structure on the way this communication link works, except for the fact you can send and receive
|
12
|
+
# objects. You can implement whatever kind of idiom you need for communication on top of this library.
|
13
|
+
#
|
14
|
+
# Depending on how you set things up, this could connect to a local ruby process, or a remote ruby process
|
15
|
+
# via `ssh`.
|
16
|
+
#
|
17
|
+
# To set up a connection, you need to use {start_server}.
|
18
|
+
class Connection
|
19
|
+
public
|
20
|
+
|
21
|
+
def self.build(process, options, &block)
|
22
|
+
cin = process.input
|
23
|
+
cout = process.output
|
24
|
+
cerr = process.error
|
25
|
+
|
26
|
+
# We require both cin and cout to be connected in order for connection to work
|
27
|
+
raise InvalidConnectionError.new("Input (#{cin}) or Output (#{cout}) is not connected!") unless cin and cout
|
28
|
+
|
29
|
+
yield cin
|
30
|
+
|
31
|
+
cin.puts("\004")
|
32
|
+
|
33
|
+
return self.new(cout, cin, cerr)
|
34
|
+
end
|
35
|
+
|
36
|
+
# Create a new connection. You need to supply a pipe for reading input, a pipe for sending output,
|
37
|
+
# and optionally a pipe for errors to be read from.
|
38
|
+
def initialize(input, output, error = nil)
|
39
|
+
@input = input
|
40
|
+
@output = output
|
41
|
+
@running = true
|
42
|
+
|
43
|
+
@error = error
|
44
|
+
|
45
|
+
@receive_mutex = Mutex.new
|
46
|
+
@send_mutex = Mutex.new
|
47
|
+
end
|
48
|
+
|
49
|
+
# The pipe used for reading data
|
50
|
+
def input
|
51
|
+
@input
|
52
|
+
end
|
53
|
+
|
54
|
+
# The pipe used for writing data
|
55
|
+
def output
|
56
|
+
@output
|
57
|
+
end
|
58
|
+
|
59
|
+
# The pipe used for receiving errors. On the client side this pipe is writable, on the server
|
60
|
+
# side this pipe is readable. You should avoid using it on the client side and simply use $stderr.
|
61
|
+
def error
|
62
|
+
@error
|
63
|
+
end
|
64
|
+
|
65
|
+
# Stop the connection, and close the output pipe.
|
66
|
+
def stop
|
67
|
+
if @running
|
68
|
+
@running = false
|
69
|
+
@output.close
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
# Return whether or not the connection is running.
|
74
|
+
def running?
|
75
|
+
@running
|
76
|
+
end
|
77
|
+
|
78
|
+
# This is a very simple runloop. It provides an object when it is received.
|
79
|
+
def run(&block)
|
80
|
+
while @running
|
81
|
+
pipes = IO.select([@input])
|
82
|
+
|
83
|
+
if pipes[0].size > 0
|
84
|
+
object = receive_object
|
85
|
+
|
86
|
+
if object == nil
|
87
|
+
@running = false
|
88
|
+
return
|
89
|
+
end
|
90
|
+
|
91
|
+
begin
|
92
|
+
yield object
|
93
|
+
rescue Exception => ex
|
94
|
+
send_object(ex)
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
# Dump any text which has been written to $stderr in the child process.
|
101
|
+
def dump_errors(to = $stderr)
|
102
|
+
if @error and !@error.closed?
|
103
|
+
while true
|
104
|
+
result = IO.select([@error], [], [], 0)
|
105
|
+
|
106
|
+
break if result == nil
|
107
|
+
|
108
|
+
to.puts @error.readline.chomp
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
# Receive an object from the connection. This function is thread-safe. This function may block.
|
114
|
+
def receive_object
|
115
|
+
object = nil
|
116
|
+
|
117
|
+
@receive_mutex.synchronize do
|
118
|
+
begin
|
119
|
+
object = Marshal.load(@input)
|
120
|
+
rescue EOFError
|
121
|
+
object = nil
|
122
|
+
@running = false
|
123
|
+
end
|
124
|
+
end
|
125
|
+
|
126
|
+
if object and object.kind_of?(Exception)
|
127
|
+
raise object
|
128
|
+
end
|
129
|
+
|
130
|
+
return object
|
131
|
+
end
|
132
|
+
|
133
|
+
# Send object(s). This function is thread-safe.
|
134
|
+
def send_object(*objects)
|
135
|
+
@send_mutex.synchronize do
|
136
|
+
objects.each do |o|
|
137
|
+
data = Marshal.dump(o)
|
138
|
+
@output.write(data)
|
139
|
+
end
|
140
|
+
|
141
|
+
@output.flush
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
153
145
|
end
|