opennebula 6.10.3 → 6.99.85.pre
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.
- checksums.yaml +4 -4
- data/lib/cloud/CloudClient.rb +3 -3
- data/lib/models/role.rb +349 -823
- data/lib/models/service.rb +156 -80
- data/lib/models/vmrole.rb +703 -0
- data/lib/models/vrrole.rb +284 -0
- data/lib/models.rb +3 -1
- data/lib/opennebula/acl.rb +1 -1
- data/lib/opennebula/acl_pool.rb +1 -1
- data/lib/opennebula/backupjob.rb +1 -1
- data/lib/opennebula/backupjob_pool.rb +1 -1
- data/lib/opennebula/client.rb +1 -1
- data/lib/opennebula/cluster.rb +45 -2
- data/lib/opennebula/cluster_pool.rb +1 -1
- data/lib/opennebula/datastore.rb +1 -1
- data/lib/opennebula/datastore_pool.rb +1 -1
- data/lib/opennebula/document.rb +1 -1
- data/lib/opennebula/document_json.rb +1 -1
- data/lib/opennebula/document_pool.rb +1 -1
- data/lib/opennebula/document_pool_json.rb +1 -1
- data/lib/opennebula/error.rb +1 -1
- data/lib/opennebula/flow/grammar.rb +1 -1
- data/lib/opennebula/flow/service_pool.rb +1 -1
- data/lib/opennebula/flow/service_template.rb +353 -97
- data/lib/opennebula/flow/service_template_ext.rb +3 -3
- data/lib/opennebula/flow/service_template_pool.rb +1 -1
- data/lib/opennebula/flow/validator.rb +458 -410
- data/lib/opennebula/flow.rb +1 -1
- data/lib/opennebula/group.rb +1 -1
- data/lib/opennebula/group_pool.rb +1 -1
- data/lib/opennebula/hook.rb +1 -1
- data/lib/opennebula/hook_log.rb +1 -1
- data/lib/opennebula/hook_pool.rb +1 -1
- data/lib/opennebula/host.rb +1 -60
- data/lib/opennebula/host_pool.rb +1 -1
- data/lib/opennebula/image.rb +1 -1
- data/lib/opennebula/image_pool.rb +1 -1
- data/lib/opennebula/ldap_auth.rb +1 -1
- data/lib/opennebula/ldap_auth_spec.rb +1 -1
- data/lib/opennebula/lockable_ext.rb +1 -1
- data/lib/opennebula/marketplace.rb +1 -1
- data/lib/opennebula/marketplace_pool.rb +1 -1
- data/lib/opennebula/marketplaceapp.rb +1 -1
- data/lib/opennebula/marketplaceapp_ext.rb +14 -211
- data/lib/opennebula/marketplaceapp_pool.rb +1 -1
- data/lib/opennebula/oneflow_client.rb +11 -9
- data/lib/opennebula/pool.rb +1 -1
- data/lib/opennebula/pool_element.rb +1 -1
- data/lib/opennebula/security_group.rb +1 -1
- data/lib/opennebula/security_group_pool.rb +1 -1
- data/lib/opennebula/server_cipher_auth.rb +1 -1
- data/lib/opennebula/server_x509_auth.rb +1 -1
- data/lib/opennebula/ssh_auth.rb +1 -1
- data/lib/opennebula/system.rb +1 -1
- data/lib/opennebula/template.rb +1 -1
- data/lib/opennebula/template_ext.rb +1 -1
- data/lib/opennebula/template_pool.rb +1 -1
- data/lib/opennebula/user.rb +1 -1
- data/lib/opennebula/user_pool.rb +1 -1
- data/lib/opennebula/utils.rb +2 -2
- data/lib/opennebula/vdc.rb +1 -1
- data/lib/opennebula/vdc_pool.rb +1 -1
- data/lib/opennebula/virtual_machine.rb +3 -12
- data/lib/opennebula/virtual_machine_ext.rb +2 -31
- data/lib/opennebula/virtual_machine_pool.rb +1 -1
- data/lib/opennebula/virtual_network.rb +1 -1
- data/lib/opennebula/virtual_network_pool.rb +1 -1
- data/lib/opennebula/virtual_router.rb +1 -1
- data/lib/opennebula/virtual_router_pool.rb +1 -1
- data/lib/opennebula/vm_group.rb +1 -1
- data/lib/opennebula/vm_group_pool.rb +1 -1
- data/lib/opennebula/vntemplate.rb +1 -1
- data/lib/opennebula/vntemplate_pool.rb +1 -1
- data/lib/opennebula/wait_ext.rb +1 -1
- data/lib/opennebula/x509_auth.rb +1 -1
- data/lib/opennebula/xml_element.rb +2 -2
- data/lib/opennebula/xml_pool.rb +1 -1
- data/lib/opennebula/xml_utils.rb +1 -1
- data/lib/opennebula/zone.rb +1 -1
- data/lib/opennebula/zone_pool.rb +1 -1
- data/lib/opennebula.rb +2 -2
- metadata +6 -67
- data/lib/ActionManager.rb +0 -280
- data/lib/CommandManager.rb +0 -328
- data/lib/DriverExecHelper.rb +0 -213
- data/lib/HostSyncManager.rb +0 -111
- data/lib/OpenNebulaDriver.rb +0 -223
- data/lib/VirtualMachineDriver.rb +0 -404
- data/lib/datacenter.rb +0 -1319
- data/lib/datastore.rb +0 -1049
- data/lib/distributed_firewall.rb +0 -293
- data/lib/file_helper.rb +0 -374
- data/lib/host.rb +0 -1518
- data/lib/logical_port.rb +0 -50
- data/lib/logical_switch.rb +0 -77
- data/lib/memoize.rb +0 -74
- data/lib/network.rb +0 -705
- data/lib/nsx_client.rb +0 -157
- data/lib/nsx_component.rb +0 -28
- data/lib/nsx_constants.rb +0 -162
- data/lib/nsx_driver.rb +0 -91
- data/lib/nsx_error.rb +0 -77
- data/lib/nsx_rule.rb +0 -206
- data/lib/nsxt_client.rb +0 -189
- data/lib/nsxt_dfw.rb +0 -196
- data/lib/nsxt_logical_port.rb +0 -94
- data/lib/nsxt_rule.rb +0 -188
- data/lib/nsxt_tz.rb +0 -38
- data/lib/nsxv_client.rb +0 -189
- data/lib/nsxv_dfw.rb +0 -202
- data/lib/nsxv_logical_port.rb +0 -107
- data/lib/nsxv_rule.rb +0 -172
- data/lib/nsxv_tz.rb +0 -41
- data/lib/opaque_network.rb +0 -134
- data/lib/rest_client.rb +0 -191
- data/lib/scripts_common.rb +0 -176
- data/lib/transport_zone.rb +0 -43
- data/lib/vcenter_driver.rb +0 -152
- data/lib/vcenter_importer.rb +0 -626
- data/lib/vi_client.rb +0 -273
- data/lib/vi_helper.rb +0 -328
- data/lib/virtual_machine.rb +0 -3574
- data/lib/virtual_wire.rb +0 -158
- data/lib/vm_device.rb +0 -80
- data/lib/vm_disk.rb +0 -202
- data/lib/vm_folder.rb +0 -69
- data/lib/vm_helper.rb +0 -30
- data/lib/vm_monitor.rb +0 -305
- data/lib/vm_nic.rb +0 -70
- data/lib/vm_template.rb +0 -2112
- data/lib/vmm_importer.rb +0 -165
data/lib/ActionManager.rb
DELETED
@@ -1,280 +0,0 @@
|
|
1
|
-
# -------------------------------------------------------------------------- */
|
2
|
-
# Copyright 2002-2024, OpenNebula Project, OpenNebula Systems #
|
3
|
-
# Licensed under the Apache License, Version 2.0 (the "License"); you may */
|
4
|
-
# not use this file except in compliance with the License. You may obtain */
|
5
|
-
# a copy of the License at */
|
6
|
-
# */
|
7
|
-
# http://www.apache.org/licenses/LICENSE-2.0 */
|
8
|
-
# */
|
9
|
-
# Unless required by applicable law or agreed to in writing, software */
|
10
|
-
# distributed under the License is distributed on an "AS IS" BASIS, */
|
11
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
|
12
|
-
# See the License for the specific language governing permissions and */
|
13
|
-
# limitations under the License. */
|
14
|
-
# -------------------------------------------------------------------------- */
|
15
|
-
|
16
|
-
require 'thread'
|
17
|
-
|
18
|
-
=begin rdoc
|
19
|
-
|
20
|
-
This class provides support to handle actions. Class methods, or actions, can be
|
21
|
-
registered in the action manager. The manager will wait for actions to be
|
22
|
-
triggered (thread-safe), and will execute them concurrently. The action manager
|
23
|
-
can be used to synchronize different objects in different threads
|
24
|
-
|
25
|
-
== Example
|
26
|
-
|
27
|
-
class Sample
|
28
|
-
attr_reader :am
|
29
|
-
|
30
|
-
def initialize
|
31
|
-
@am = ActionManager.new(15,true)
|
32
|
-
|
33
|
-
@am.register_action("SLEEP",method("sleep_action"))
|
34
|
-
end
|
35
|
-
|
36
|
-
def sleep_action(secs)
|
37
|
-
sleep(secs)
|
38
|
-
end
|
39
|
-
|
40
|
-
def finalize_action
|
41
|
-
p "Exiting..."
|
42
|
-
@am.stop_listener
|
43
|
-
end
|
44
|
-
end
|
45
|
-
|
46
|
-
|
47
|
-
s = Sample.new
|
48
|
-
|
49
|
-
s.@am.start_listener
|
50
|
-
|
51
|
-
# Objects in other threads can trigger actions like this
|
52
|
-
# s.am.trigger_action("SLEEP",rand(3)+1)
|
53
|
-
# s.am.trigger_action("FINALIZE")
|
54
|
-
=end
|
55
|
-
|
56
|
-
class ActionManager
|
57
|
-
|
58
|
-
# Creates a new Action Manager
|
59
|
-
#
|
60
|
-
# +concurrency+ is the maximun number of actions that can run at the same
|
61
|
-
# time
|
62
|
-
# +threaded+ if true actions will be executed by default in a different
|
63
|
-
# thread
|
64
|
-
def initialize(concurrency=10, threaded=true)
|
65
|
-
@finalize = false
|
66
|
-
@actions = Hash.new
|
67
|
-
@threaded = threaded
|
68
|
-
|
69
|
-
@concurrency = concurrency
|
70
|
-
@num_running = 0
|
71
|
-
|
72
|
-
@action_queue = Array.new
|
73
|
-
@action_running = Hash.new
|
74
|
-
|
75
|
-
@threads_mutex = Mutex.new
|
76
|
-
@threads_cond = ConditionVariable.new
|
77
|
-
end
|
78
|
-
|
79
|
-
# Registers a new action in the manager. An action is defined by:
|
80
|
-
#
|
81
|
-
# +aname+ name of the action, it will identify the action
|
82
|
-
# +method+ it's invoked with call. It should be a Proc or Method object
|
83
|
-
# +threaded+ execute the action in a new thread
|
84
|
-
def register_action(aname, method, threaded=nil)
|
85
|
-
threaded ||= @threaded
|
86
|
-
|
87
|
-
@actions[aname]={
|
88
|
-
:method => method,
|
89
|
-
:threaded => threaded
|
90
|
-
}
|
91
|
-
end
|
92
|
-
|
93
|
-
# Triggers the execution of the action.
|
94
|
-
#
|
95
|
-
# +aname+ name of the action
|
96
|
-
# +action_id+ an id to identify the action (to cancel it later)
|
97
|
-
# +aargs+ arguments to call the action
|
98
|
-
def trigger_action(aname, action_id, *aargs)
|
99
|
-
|
100
|
-
@threads_mutex.synchronize {
|
101
|
-
return if @finalize
|
102
|
-
|
103
|
-
if aname == :FINALIZE
|
104
|
-
finalize if respond_to?(:finalize)
|
105
|
-
@finalize = true
|
106
|
-
@threads_cond.signal if @num_running == 0
|
107
|
-
return
|
108
|
-
end
|
109
|
-
|
110
|
-
if !@actions.has_key?(aname)
|
111
|
-
return
|
112
|
-
end
|
113
|
-
|
114
|
-
arity=@actions[aname][:method].arity
|
115
|
-
|
116
|
-
if arity < 0
|
117
|
-
# Last parameter is an array
|
118
|
-
arity = -arity - 1
|
119
|
-
if arity > aargs.length
|
120
|
-
# Message has not enough parameters
|
121
|
-
return
|
122
|
-
end
|
123
|
-
# Converts last parameters to an array
|
124
|
-
aargs[arity..-1]=[aargs[arity..-1]]
|
125
|
-
else
|
126
|
-
if arity != aargs.length
|
127
|
-
return
|
128
|
-
end
|
129
|
-
end
|
130
|
-
|
131
|
-
@action_queue << @actions[aname].merge(:args => aargs,
|
132
|
-
:id => action_id)
|
133
|
-
|
134
|
-
if @num_running < @concurrency
|
135
|
-
@threads_cond.signal
|
136
|
-
end
|
137
|
-
}
|
138
|
-
end
|
139
|
-
|
140
|
-
def cancel_action(action_id)
|
141
|
-
@threads_mutex.synchronize {
|
142
|
-
action = @action_running[action_id]
|
143
|
-
if action
|
144
|
-
thread = action[:thread]
|
145
|
-
else
|
146
|
-
thread = nil
|
147
|
-
end
|
148
|
-
|
149
|
-
if thread
|
150
|
-
thread.kill
|
151
|
-
|
152
|
-
@num_running -= 1
|
153
|
-
delete_running_action(action_id)
|
154
|
-
|
155
|
-
@threads_cond.signal
|
156
|
-
else
|
157
|
-
i = @action_queue.select{|x| x[:id] == action_id}.first
|
158
|
-
@action_queue.delete(i) if i
|
159
|
-
end
|
160
|
-
}
|
161
|
-
end
|
162
|
-
|
163
|
-
def start_listener
|
164
|
-
while true
|
165
|
-
@threads_mutex.synchronize {
|
166
|
-
while ((@concurrency - @num_running)==0) || empty_queue
|
167
|
-
@threads_cond.wait(@threads_mutex)
|
168
|
-
|
169
|
-
return if (@finalize && @num_running == 0)
|
170
|
-
end
|
171
|
-
|
172
|
-
run_action
|
173
|
-
}
|
174
|
-
end
|
175
|
-
end
|
176
|
-
|
177
|
-
protected
|
178
|
-
|
179
|
-
def delete_running_action(action_id)
|
180
|
-
@action_running.delete(action_id)
|
181
|
-
end
|
182
|
-
|
183
|
-
def get_runable_action
|
184
|
-
@action_queue.shift
|
185
|
-
end
|
186
|
-
|
187
|
-
def empty_queue
|
188
|
-
@action_queue.size==0
|
189
|
-
end
|
190
|
-
|
191
|
-
def run_action
|
192
|
-
action = get_runable_action
|
193
|
-
|
194
|
-
if action
|
195
|
-
@num_running += 1
|
196
|
-
|
197
|
-
if action[:threaded]
|
198
|
-
thread = Thread.new {
|
199
|
-
begin
|
200
|
-
action[:method].call(*action[:args])
|
201
|
-
ensure
|
202
|
-
@threads_mutex.synchronize {
|
203
|
-
@num_running -= 1
|
204
|
-
delete_running_action(action[:id])
|
205
|
-
|
206
|
-
@threads_cond.signal
|
207
|
-
}
|
208
|
-
end
|
209
|
-
}
|
210
|
-
|
211
|
-
action[:thread] = thread
|
212
|
-
@action_running[action[:id]] = action
|
213
|
-
else
|
214
|
-
action[:method].call(*action[:args])
|
215
|
-
|
216
|
-
@num_running -= 1
|
217
|
-
end
|
218
|
-
end
|
219
|
-
end
|
220
|
-
end
|
221
|
-
|
222
|
-
if __FILE__ == $0
|
223
|
-
|
224
|
-
class Sample
|
225
|
-
attr_reader :am
|
226
|
-
|
227
|
-
def initialize
|
228
|
-
@am = ActionManager.new(15,true)
|
229
|
-
|
230
|
-
@am.register_action(:SLEEP,method("sleep_action"))
|
231
|
-
# @am.register_action(:SLEEP,Proc.new{|s,i| p s ; sleep(s)})
|
232
|
-
@am.register_action(:NOP,method("nop_action"))
|
233
|
-
|
234
|
-
def @am.get_runable_action
|
235
|
-
action = super
|
236
|
-
puts "getting: #{action.inspect}"
|
237
|
-
action
|
238
|
-
end
|
239
|
-
|
240
|
-
def @am.delete_running_action(action_id)
|
241
|
-
puts "deleting: #{action_id}"
|
242
|
-
super(action_id)
|
243
|
-
end
|
244
|
-
end
|
245
|
-
|
246
|
-
def sleep_action(secs, id)
|
247
|
-
p "ID: #{id} sleeping #{secs} seconds"
|
248
|
-
sleep(secs)
|
249
|
-
p "ID: #{id} Awaken!"
|
250
|
-
end
|
251
|
-
|
252
|
-
def nop_action
|
253
|
-
p " - Just an action"
|
254
|
-
end
|
255
|
-
|
256
|
-
end
|
257
|
-
|
258
|
-
s = Sample.new
|
259
|
-
|
260
|
-
Thread.new {
|
261
|
-
sleep 1
|
262
|
-
|
263
|
-
100.times {|n|
|
264
|
-
s.am.trigger_action(:SLEEP,n,rand(3)+1,n)
|
265
|
-
s.am.trigger_action(:NOP,100+n)
|
266
|
-
}
|
267
|
-
|
268
|
-
s.am.trigger_action(:SLEEP,301,5,301)
|
269
|
-
|
270
|
-
s.am.cancel_action(301)
|
271
|
-
|
272
|
-
s.am.trigger_action(:FINALIZE,0)
|
273
|
-
|
274
|
-
s.am.trigger_action(:SLEEP,999,rand(3)+1,999)
|
275
|
-
s.am.trigger_action(:SLEEP,333,rand(3)+1,333)
|
276
|
-
}
|
277
|
-
|
278
|
-
s.am.start_listener
|
279
|
-
end
|
280
|
-
|
data/lib/CommandManager.rb
DELETED
@@ -1,328 +0,0 @@
|
|
1
|
-
# --------------------------------------------------------------------------
|
2
|
-
# Copyright 2002-2024, OpenNebula Project, OpenNebula Systems
|
3
|
-
#
|
4
|
-
# Licensed under the Apache License, Version 2.0 (the "License"); you may
|
5
|
-
# not use this file except in compliance with the License. You may obtain
|
6
|
-
# a copy of the License at
|
7
|
-
#
|
8
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
9
|
-
#
|
10
|
-
# Unless required by applicable law or agreed to in writing, software
|
11
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
12
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
13
|
-
# See the License for the specific language governing permissions and
|
14
|
-
# limitations under the License.
|
15
|
-
# --------------------------------------------------------------------------
|
16
|
-
|
17
|
-
require 'pp'
|
18
|
-
require 'open3'
|
19
|
-
require 'timeout'
|
20
|
-
require 'base64'
|
21
|
-
|
22
|
-
# Generic command executor that holds the code shared by all the command
|
23
|
-
# executors.
|
24
|
-
#
|
25
|
-
# Properties:
|
26
|
-
#
|
27
|
-
# * +code+: integer holding the exit code. Read-only
|
28
|
-
# * +stdout+: string of the standard output. Read-only
|
29
|
-
# * +stderr+: string of the standard error. Read-only
|
30
|
-
# * +command+: command to execute. Read-only
|
31
|
-
#
|
32
|
-
# The protocol for scripts to log is as follows:
|
33
|
-
#
|
34
|
-
# * Log messages will be sent to STDOUT
|
35
|
-
# * The script will return 0 if it succeded or any other value
|
36
|
-
# if there was a failure
|
37
|
-
# * In case of failure the cause of the error will be written to STDERR.
|
38
|
-
|
39
|
-
class GenericCommand
|
40
|
-
|
41
|
-
attr_reader :code, :stdout, :stderr, :command
|
42
|
-
|
43
|
-
# Creates a command and runs it
|
44
|
-
def self.run(command, logger=nil, stdin=nil, timeout=nil)
|
45
|
-
cmd = self.new(command, logger, stdin, timeout)
|
46
|
-
cmd.run
|
47
|
-
cmd
|
48
|
-
end
|
49
|
-
|
50
|
-
# Creates the new command:
|
51
|
-
# +command+: string with the command to be executed
|
52
|
-
# +logger+: proc that takes a message parameter and logs it
|
53
|
-
def initialize(command, logger=nil, stdin=nil, timeout=nil)
|
54
|
-
@command = command
|
55
|
-
@logger = logger
|
56
|
-
@stdin = stdin
|
57
|
-
@timeout = timeout
|
58
|
-
end
|
59
|
-
|
60
|
-
# Sends a log message to the logger proc
|
61
|
-
def log(message, all=true)
|
62
|
-
@logger.call(message, all) if @logger
|
63
|
-
end
|
64
|
-
|
65
|
-
# Runs the command
|
66
|
-
def run
|
67
|
-
begin
|
68
|
-
@stdout, @stderr, status = execute
|
69
|
-
|
70
|
-
if status && status.exited?
|
71
|
-
@code = status.exitstatus
|
72
|
-
else
|
73
|
-
@code = 255
|
74
|
-
end
|
75
|
-
|
76
|
-
if @code != 0
|
77
|
-
log("Command execution failed (exit code: #{@code}): #{command}")
|
78
|
-
log(@stderr)
|
79
|
-
end
|
80
|
-
rescue Exception => e
|
81
|
-
if e.is_a?(Timeout::Error)
|
82
|
-
error_message = "Timeout executing #{command}"
|
83
|
-
else
|
84
|
-
error_message = "Internal error #{e}"
|
85
|
-
end
|
86
|
-
|
87
|
-
log(error_message)
|
88
|
-
|
89
|
-
@stderr = error_message
|
90
|
-
@code = 255
|
91
|
-
end
|
92
|
-
|
93
|
-
return @code
|
94
|
-
end
|
95
|
-
|
96
|
-
# Parses error message from +stderr+ output
|
97
|
-
def get_error_message
|
98
|
-
return '-' if @stderr.empty?
|
99
|
-
|
100
|
-
@stderr.tr("\n",' ').strip
|
101
|
-
end
|
102
|
-
|
103
|
-
def to_xml
|
104
|
-
stdout = @stdout.nil? ? '' : @stdout
|
105
|
-
stderr = @stderr.nil? ? '' : @stderr
|
106
|
-
|
107
|
-
'<EXECUTION_RESULT>' \
|
108
|
-
"<COMMAND>#{@command}</COMMAND>" \
|
109
|
-
"<STDOUT>#{Base64.encode64(stdout)}</STDOUT>" \
|
110
|
-
"<STDERR>#{Base64.encode64(stderr)}</STDERR>" \
|
111
|
-
"<CODE>#{@code}</CODE>" \
|
112
|
-
'</EXECUTION_RESULT>'
|
113
|
-
end
|
114
|
-
|
115
|
-
private
|
116
|
-
|
117
|
-
# Low level command execution. This method has to be redefined
|
118
|
-
# for each kind of command execution. Returns an array with
|
119
|
-
# +stdout+, +stderr+ and +status+ of the command execution.
|
120
|
-
def execute
|
121
|
-
puts "About to execute \"#{@command}\""
|
122
|
-
['', '', nil]
|
123
|
-
end
|
124
|
-
|
125
|
-
# modified Open3.capture with terminator thread
|
126
|
-
# to deal with timeouts
|
127
|
-
def capture3_timeout(*cmd)
|
128
|
-
if Hash === cmd.last
|
129
|
-
opts = cmd.pop.dup
|
130
|
-
else
|
131
|
-
opts = {}
|
132
|
-
end
|
133
|
-
|
134
|
-
stdin_data = opts.delete(:stdin_data) || ''
|
135
|
-
binmode = opts.delete(:binmode)
|
136
|
-
|
137
|
-
Open3.popen3(*cmd, opts) {|i, o, e, t|
|
138
|
-
if binmode
|
139
|
-
i.binmode
|
140
|
-
o.binmode
|
141
|
-
e.binmode
|
142
|
-
end
|
143
|
-
|
144
|
-
terminator_e = nil
|
145
|
-
mutex = Mutex.new
|
146
|
-
|
147
|
-
out_reader = Thread.new { o.read }
|
148
|
-
err_reader = Thread.new { e.read }
|
149
|
-
terminator = Thread.new {
|
150
|
-
if @timeout and @timeout>0
|
151
|
-
begin
|
152
|
-
pid = Process.getpgid(t.pid) * -1
|
153
|
-
rescue
|
154
|
-
pid = t.pid
|
155
|
-
end
|
156
|
-
|
157
|
-
if pid
|
158
|
-
begin
|
159
|
-
sleep @timeout
|
160
|
-
|
161
|
-
mutex.synchronize do
|
162
|
-
terminator_e = Timeout::Error
|
163
|
-
end
|
164
|
-
ensure
|
165
|
-
end
|
166
|
-
|
167
|
-
Process.kill('TERM', pid)
|
168
|
-
end
|
169
|
-
end
|
170
|
-
}
|
171
|
-
|
172
|
-
begin
|
173
|
-
i.write stdin_data
|
174
|
-
i.close
|
175
|
-
rescue Errno::EPIPE
|
176
|
-
# the cmd doesn't read the input, ignore error
|
177
|
-
end
|
178
|
-
|
179
|
-
# blocking wait for process termination
|
180
|
-
t.value
|
181
|
-
|
182
|
-
# if reader threads are not dead yet, kill them
|
183
|
-
[out_reader, err_reader].each do |reader|
|
184
|
-
next unless reader.status
|
185
|
-
|
186
|
-
reader.join(0.1)
|
187
|
-
reader.kill
|
188
|
-
end
|
189
|
-
|
190
|
-
mutex.lock
|
191
|
-
terminator.kill
|
192
|
-
raise terminator_e if terminator_e
|
193
|
-
|
194
|
-
# return values
|
195
|
-
[out_reader.value, err_reader.value, t.value]
|
196
|
-
}
|
197
|
-
end
|
198
|
-
|
199
|
-
end
|
200
|
-
|
201
|
-
# Executes commands in the machine where it is called. See documentation
|
202
|
-
# for GenericCommand
|
203
|
-
class LocalCommand < GenericCommand
|
204
|
-
private
|
205
|
-
|
206
|
-
def execute
|
207
|
-
capture3_timeout("#{command}",
|
208
|
-
:pgroup => true, :stdin_data => @stdin)
|
209
|
-
end
|
210
|
-
end
|
211
|
-
|
212
|
-
# Executes commands in a remote machine ussing ssh. See documentation
|
213
|
-
# for GenericCommand
|
214
|
-
class SSHCommand < GenericCommand
|
215
|
-
|
216
|
-
attr_accessor :host, :ssh_opts
|
217
|
-
|
218
|
-
# Creates a command and runs it
|
219
|
-
def self.run(command, host, logger=nil, stdin=nil, timeout=nil, ssh_opts='')
|
220
|
-
cmd=self.new(command, host, logger, stdin, timeout, ssh_opts)
|
221
|
-
cmd.run
|
222
|
-
cmd
|
223
|
-
end
|
224
|
-
|
225
|
-
# This one takes another parameter. +host+ is the machine
|
226
|
-
# where the command is going to be executed
|
227
|
-
def initialize(command, host, logger=nil, stdin=nil, timeout=nil, ssh_opts='')
|
228
|
-
@host=host
|
229
|
-
@ssh_opts = ssh_opts
|
230
|
-
|
231
|
-
super(command, logger, stdin, timeout)
|
232
|
-
end
|
233
|
-
|
234
|
-
private
|
235
|
-
|
236
|
-
def execute
|
237
|
-
if @stdin
|
238
|
-
capture3_timeout("ssh #{@ssh_opts} #{@host} #{@command}",
|
239
|
-
:pgroup => true, :stdin_data => @stdin)
|
240
|
-
else
|
241
|
-
capture3_timeout("ssh -n #{@ssh_opts} #{@host} #{@command}",
|
242
|
-
:pgroup => true)
|
243
|
-
end
|
244
|
-
end
|
245
|
-
end
|
246
|
-
|
247
|
-
class RemotesCommand < SSHCommand
|
248
|
-
|
249
|
-
# Creates a command and runs it
|
250
|
-
def self.run(command, host, remote_dir, logger=nil, stdin=nil, retries=0, timeout=nil)
|
251
|
-
cmd_file = command.split(' ')[0]
|
252
|
-
|
253
|
-
cmd_string = "'if [ -x \"#{cmd_file}\" ]; then #{command}; else\
|
254
|
-
exit #{MAGIC_RC}; fi'"
|
255
|
-
|
256
|
-
cmd = self.new(cmd_string, host, logger, stdin, timeout)
|
257
|
-
cmd.run
|
258
|
-
|
259
|
-
while cmd.code != 0 and retries != 0
|
260
|
-
if cmd.code == MAGIC_RC
|
261
|
-
update_remotes(host, remote_dir, logger)
|
262
|
-
end
|
263
|
-
|
264
|
-
sleep 1
|
265
|
-
cmd.run
|
266
|
-
retries = retries - 1
|
267
|
-
end
|
268
|
-
|
269
|
-
cmd
|
270
|
-
end
|
271
|
-
|
272
|
-
private
|
273
|
-
|
274
|
-
ONE_LOCATION=ENV["ONE_LOCATION"]
|
275
|
-
|
276
|
-
if !ONE_LOCATION
|
277
|
-
REMOTES_LOCATION="/var/lib/one/remotes"
|
278
|
-
else
|
279
|
-
REMOTES_LOCATION=ONE_LOCATION+"/var/remotes/"
|
280
|
-
end
|
281
|
-
|
282
|
-
MAGIC_RC = 42
|
283
|
-
|
284
|
-
def self.update_remotes(host, remote_dir, logger=nil)
|
285
|
-
if logger != nil
|
286
|
-
logger.call("Remote worker node files not found")
|
287
|
-
logger.call("Updating remotes")
|
288
|
-
end
|
289
|
-
|
290
|
-
#recreate remote dir structure
|
291
|
-
SSHCommand.run("mkdir -p #{remote_dir}",host,logger)
|
292
|
-
|
293
|
-
# Use SCP to sync:
|
294
|
-
sync_cmd = "scp -rp #{REMOTES_LOCATION}/* #{host}:#{remote_dir}"
|
295
|
-
|
296
|
-
# Use rsync to sync:
|
297
|
-
# sync_cmd = "rsync -Laz #{REMOTES_LOCATION} #{host}:#{@remote_dir}"
|
298
|
-
LocalCommand.run(sync_cmd, logger)
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
|
303
|
-
if $0 == __FILE__
|
304
|
-
|
305
|
-
command=GenericCommand.run("uname -a")
|
306
|
-
puts command.stderr
|
307
|
-
|
308
|
-
local_command=LocalCommand.run("uname -a")
|
309
|
-
puts "STDOUT:"
|
310
|
-
puts local_command.stdout
|
311
|
-
puts
|
312
|
-
puts "STDERR:"
|
313
|
-
puts local_command.stderr
|
314
|
-
|
315
|
-
ssh_command=SSHCommand.run("uname -a", "localhost")
|
316
|
-
puts "STDOUT:"
|
317
|
-
puts ssh_command.stdout
|
318
|
-
puts
|
319
|
-
puts "STDERR:"
|
320
|
-
puts ssh_command.stderr
|
321
|
-
|
322
|
-
fd = File.new("/etc/passwd")
|
323
|
-
str = String.new
|
324
|
-
fd.each {|line| str << line}
|
325
|
-
fd.close
|
326
|
-
|
327
|
-
ssh_in = SSHCommand.run("cat > /tmp/test","localhost",nil,str)
|
328
|
-
end
|