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 CHANGED
@@ -1,14 +1,61 @@
1
1
  = RExec
2
2
 
3
- Author:: Samuel Williams (http://www.oriontransfer.co.nz/)
4
- Copyright:: Copyright (C) 2009, 2010 Samuel Williams
5
- License:: GPLv3
6
-
7
- RExec stands for Ruby Execute or Remote Execute (depending on how you use it). It provides a number of different things to assist with running Ruby code:
8
-
9
- * A framework to send Ruby code to a remote server for execution
10
- * A framework for writing command line daemons (i.e. <tt>start</tt>, <tt>restart</tt>, <tt>stop</tt>, <tt>status</tt>)
11
- * A comprehensive <tt>Task</tt> class for launching tasks, managing input and output, exit status, etc
12
- * Basic privilege management code for changing the processes owner
13
- * A bunch of helpers for various different things (such as reading a file backwards)
14
- * <tt>daemon-exec</tt> executable for running regular shell tasks in the background
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 Williams. Released under the GNU GPLv3.
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
- # This program is distributed in the hope that it will be useful,
11
- # but WITHOUT ANY WARRANTY; without even the implied warranty of
12
- # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
- # GNU General Public License for more details.
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
- # You should have received a copy of the GNU General Public License
16
- # along with this program. If not, see <http://www.gnu.org/licenses/>.
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 Williams. Released under the GNU GPLv3.
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
- # 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.
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
- # 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/>.
15
-
16
- # = Summary =
17
- # This gem provides a very simple connection based API for communicating
18
- # with remote instances of ruby. These can either be local, or remote, such
19
- # as over SSH.
20
- #
21
- # The API is very simple and deals with sending and receiving objects using
22
- # Marshal. One of the primary goals was to impose as little structure as
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 Williams. Released under the GNU GPLv3.
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
 
@@ -1,153 +1,145 @@
1
- # Copyright (c) 2007 Samuel Williams. Released under the GNU GPLv3.
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
- # This class represents an abstract connection to another ruby process. The interface does not impose
23
- # any structure on the way this communication link works, except for the fact you can send and receive
24
- # objects. You can implement whatever kind of idiom you need for communication on top of this library.
25
- #
26
- # Depending on how you set things up, this can connect to a local ruby process, or a remote ruby process
27
- # via SSH (for example).
28
- class Connection
29
- public
30
-
31
- def self.build(process, options, &block)
32
- cin = process.input
33
- cout = process.output
34
- cerr = process.error
35
-
36
- # We require both cin and cout to be connected in order for connection to work
37
- raise InvalidConnectionError.new("Input (#{cin}) or Output (#{cout}) is not connected!") unless cin and cout
38
-
39
- yield cin
40
-
41
- cin.puts("\004")
42
-
43
- return self.new(cout, cin, cerr)
44
- end
45
-
46
- # Create a new connection. You need to supply a pipe for reading input, a pipe for sending output,
47
- # and optionally a pipe for errors to be read from.
48
- def initialize(input, output, error = nil)
49
- @input = input
50
- @output = output
51
- @running = true
52
-
53
- @error = error
54
-
55
- @receive_mutex = Mutex.new
56
- @send_mutex = Mutex.new
57
- end
58
-
59
- # The pipe used for reading data
60
- def input
61
- @input
62
- end
63
-
64
- # The pipe used for writing data
65
- def output
66
- @output
67
- end
68
-
69
- # The pipe used for receiving errors. On the client side this pipe is writable, on the server
70
- # side this pipe is readable. You should avoid using it on the client side and simply use $stderr.
71
- def error
72
- @error
73
- end
74
-
75
- # Stop the connection, and close the output pipe.
76
- def stop
77
- @running = false
78
- @output.close
79
- end
80
-
81
- # Return whether or not the connection is running.
82
- def running?
83
- @running
84
- end
85
-
86
- # This is a very simple runloop. It provides an object when it is received.
87
- def run(&block)
88
- while @running
89
- pipes = IO.select([@input])
90
-
91
- if pipes[0].size > 0
92
- object = receive_object
93
-
94
- if object == nil
95
- @running = false
96
- return
97
- end
98
-
99
- begin
100
- yield object
101
- rescue Exception => ex
102
- send_object(ex)
103
- end
104
- end
105
- end
106
- end
107
-
108
- # Dump any text which has been written to $stderr in the child process.
109
- def dump_errors(to = $stderr)
110
- if @error and !@error.closed?
111
- while true
112
- result = IO.select([@error], [], [], 0)
113
-
114
- break if result == nil
115
-
116
- to.puts @error.readline.chomp
117
- end
118
- end
119
- end
120
-
121
- # Receive an object from the connection. This function is thread-safe. This function may block.
122
- def receive_object
123
- object = nil
124
-
125
- @receive_mutex.synchronize do
126
- begin
127
- object = Marshal.load(@input)
128
- rescue EOFError
129
- object = nil
130
- @running = false
131
- end
132
- end
133
-
134
- if object and object.kind_of?(Exception)
135
- raise object
136
- end
137
-
138
- return object
139
- end
140
-
141
- # Send object(s). This function is thread-safe.
142
- def send_object(*objects)
143
- @send_mutex.synchronize do
144
- objects.each do |o|
145
- data = Marshal.dump(o)
146
- @output.write(data)
147
- end
148
-
149
- @output.flush
150
- end
151
- end
152
- end
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