aspera-cli 4.5.0 → 4.8.0

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.
Files changed (104) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +1 -0
  3. data/README.md +1894 -1574
  4. data/bin/ascli +21 -1
  5. data/bin/asession +38 -34
  6. data/docs/test_env.conf +14 -3
  7. data/examples/aoc.rb +17 -15
  8. data/examples/dascli +26 -0
  9. data/examples/faspex4.rb +42 -35
  10. data/examples/proxy.pac +1 -1
  11. data/examples/transfer.rb +38 -37
  12. data/lib/aspera/aoc.rb +245 -205
  13. data/lib/aspera/ascmd.rb +111 -90
  14. data/lib/aspera/ats_api.rb +16 -14
  15. data/lib/aspera/cli/basic_auth_plugin.rb +19 -18
  16. data/lib/aspera/cli/extended_value.rb +50 -39
  17. data/lib/aspera/cli/formater.rb +161 -135
  18. data/lib/aspera/cli/info.rb +18 -0
  19. data/lib/aspera/cli/listener/line_dump.rb +4 -2
  20. data/lib/aspera/cli/listener/logger.rb +3 -1
  21. data/lib/aspera/cli/listener/progress.rb +20 -21
  22. data/lib/aspera/cli/listener/progress_multi.rb +29 -31
  23. data/lib/aspera/cli/main.rb +194 -183
  24. data/lib/aspera/cli/manager.rb +213 -206
  25. data/lib/aspera/cli/plugin.rb +71 -49
  26. data/lib/aspera/cli/plugins/alee.rb +8 -7
  27. data/lib/aspera/cli/plugins/aoc.rb +675 -558
  28. data/lib/aspera/cli/plugins/ats.rb +116 -109
  29. data/lib/aspera/cli/plugins/bss.rb +35 -34
  30. data/lib/aspera/cli/plugins/config.rb +722 -542
  31. data/lib/aspera/cli/plugins/console.rb +28 -22
  32. data/lib/aspera/cli/plugins/cos.rb +28 -37
  33. data/lib/aspera/cli/plugins/faspex.rb +281 -227
  34. data/lib/aspera/cli/plugins/faspex5.rb +129 -84
  35. data/lib/aspera/cli/plugins/node.rb +426 -232
  36. data/lib/aspera/cli/plugins/orchestrator.rb +106 -98
  37. data/lib/aspera/cli/plugins/preview.rb +196 -191
  38. data/lib/aspera/cli/plugins/server.rb +131 -126
  39. data/lib/aspera/cli/plugins/shares.rb +49 -36
  40. data/lib/aspera/cli/plugins/sync.rb +27 -28
  41. data/lib/aspera/cli/transfer_agent.rb +84 -79
  42. data/lib/aspera/cli/version.rb +3 -1
  43. data/lib/aspera/colors.rb +37 -28
  44. data/lib/aspera/command_line_builder.rb +84 -63
  45. data/lib/aspera/cos_node.rb +68 -34
  46. data/lib/aspera/data_repository.rb +4 -2
  47. data/lib/aspera/environment.rb +61 -46
  48. data/lib/aspera/fasp/agent_base.rb +36 -31
  49. data/lib/aspera/fasp/agent_connect.rb +44 -37
  50. data/lib/aspera/fasp/agent_direct.rb +101 -104
  51. data/lib/aspera/fasp/agent_httpgw.rb +91 -90
  52. data/lib/aspera/fasp/agent_node.rb +36 -33
  53. data/lib/aspera/fasp/agent_trsdk.rb +28 -31
  54. data/lib/aspera/fasp/error.rb +3 -1
  55. data/lib/aspera/fasp/error_info.rb +81 -54
  56. data/lib/aspera/fasp/installation.rb +171 -151
  57. data/lib/aspera/fasp/listener.rb +2 -0
  58. data/lib/aspera/fasp/parameters.rb +105 -111
  59. data/lib/aspera/fasp/parameters.yaml +305 -249
  60. data/lib/aspera/fasp/resume_policy.rb +20 -20
  61. data/lib/aspera/fasp/transfer_spec.rb +27 -0
  62. data/lib/aspera/fasp/uri.rb +31 -29
  63. data/lib/aspera/faspex_gw.rb +95 -118
  64. data/lib/aspera/hash_ext.rb +12 -13
  65. data/lib/aspera/id_generator.rb +11 -9
  66. data/lib/aspera/keychain/encrypted_hash.rb +73 -57
  67. data/lib/aspera/keychain/macos_security.rb +27 -29
  68. data/lib/aspera/log.rb +40 -39
  69. data/lib/aspera/nagios.rb +24 -22
  70. data/lib/aspera/node.rb +38 -30
  71. data/lib/aspera/oauth.rb +217 -248
  72. data/lib/aspera/open_application.rb +9 -7
  73. data/lib/aspera/persistency_action_once.rb +15 -14
  74. data/lib/aspera/persistency_folder.rb +15 -18
  75. data/lib/aspera/preview/file_types.rb +266 -270
  76. data/lib/aspera/preview/generator.rb +94 -92
  77. data/lib/aspera/preview/image_error.png +0 -0
  78. data/lib/aspera/preview/options.rb +20 -17
  79. data/lib/aspera/preview/utils.rb +99 -102
  80. data/lib/aspera/preview/video_error.png +0 -0
  81. data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
  82. data/lib/aspera/proxy_auto_config.rb +114 -21
  83. data/lib/aspera/rest.rb +144 -142
  84. data/lib/aspera/rest_call_error.rb +3 -2
  85. data/lib/aspera/rest_error_analyzer.rb +31 -31
  86. data/lib/aspera/rest_errors_aspera.rb +18 -16
  87. data/lib/aspera/secret_hider.rb +68 -0
  88. data/lib/aspera/ssh.rb +20 -16
  89. data/lib/aspera/sync.rb +57 -54
  90. data/lib/aspera/temp_file_manager.rb +20 -14
  91. data/lib/aspera/timer_limiter.rb +10 -8
  92. data/lib/aspera/uri_reader.rb +14 -15
  93. data/lib/aspera/web_auth.rb +85 -80
  94. data.tar.gz.sig +0 -0
  95. metadata +169 -40
  96. metadata.gz.sig +2 -0
  97. data/bin/dascli +0 -13
  98. data/docs/Makefile +0 -63
  99. data/docs/README.erb.md +0 -4221
  100. data/docs/README.md +0 -13
  101. data/docs/diagrams.txt +0 -49
  102. data/docs/doc_tools.rb +0 -58
  103. data/lib/aspera/cli/plugins/shares2.rb +0 -114
  104. data/lib/aspera/fasp/default.rb +0 -17
@@ -1,20 +1,17 @@
1
- #!/bin/echo this is a ruby class:
2
- #
3
- # FASP manager for Ruby
4
- # Aspera 2016
5
- # Laurent Martin
6
- #
7
- ##############################################################################
1
+ # frozen_string_literal: true
2
+
3
+ require 'English'
8
4
  require 'aspera/fasp/agent_base'
9
5
  require 'aspera/fasp/error'
10
6
  require 'aspera/fasp/parameters'
11
7
  require 'aspera/fasp/installation'
12
8
  require 'aspera/fasp/resume_policy'
13
- require 'aspera/fasp/default'
9
+ require 'aspera/fasp/transfer_spec'
14
10
  require 'aspera/log'
15
11
  require 'socket'
16
12
  require 'timeout'
17
13
  require 'securerandom'
14
+ require 'shellwords'
18
15
 
19
16
  module Aspera
20
17
  module Fasp
@@ -27,8 +24,8 @@ module Aspera
27
24
  wss: false,
28
25
  multi_incr_udp: true,
29
26
  resume: {},
30
- quiet: true # by default no interactive progress bar
31
- }
27
+ quiet: true # by default no interactive progress bar
28
+ }.freeze
32
29
  private_constant :DEFAULT_OPTIONS
33
30
 
34
31
  # start ascp transfer (non blocking), single or multi-session
@@ -41,22 +38,23 @@ module Aspera
41
38
  job_options[:resumer] ||= @resume_policy
42
39
  job_options[:job_id] ||= SecureRandom.uuid
43
40
  # clone transfer spec because we modify it (first level keys)
44
- transfer_spec=transfer_spec.clone
41
+ transfer_spec = transfer_spec.clone
45
42
  # if there is aspera tags
46
- if transfer_spec['tags'].is_a?(Hash) and transfer_spec['tags']['aspera'].is_a?(Hash)
43
+ if transfer_spec['tags'].is_a?(Hash) && transfer_spec['tags']['aspera'].is_a?(Hash)
47
44
  # TODO: what is this for ? only on local ascp ?
48
45
  # NOTE: important: transfer id must be unique: generate random id
49
46
  # using a non unique id results in discard of tags in AoC, and a package is never finalized
50
- transfer_spec['tags']['aspera']['xfer_id']||=SecureRandom.uuid
47
+ # all sessions in a multi-session transfer must have the same xfer_id (see admin manual)
48
+ transfer_spec['tags']['aspera']['xfer_id'] ||= SecureRandom.uuid
51
49
  Log.log.debug("xfer id=#{transfer_spec['xfer_id']}")
52
50
  # TODO: useful ? node only ?
53
- transfer_spec['tags']['aspera']['xfer_retry']||=3600
51
+ transfer_spec['tags']['aspera']['xfer_retry'] ||= 3600
54
52
  end
55
53
  Log.dump('ts',transfer_spec)
56
54
 
57
55
  # add bypass keys when authentication is token and no auth is provided
58
- if transfer_spec.has_key?('token') and
59
- !transfer_spec.has_key?('remote_password') and
56
+ if transfer_spec.has_key?('token') &&
57
+ !transfer_spec.has_key?('remote_password') &&
60
58
  !transfer_spec.has_key?('EX_ssh_key_paths')
61
59
  # transfer_spec['remote_password'] = Installation.instance.bypass_pass # not used
62
60
  transfer_spec['EX_ssh_key_paths'] = Installation.instance.bypass_keys
@@ -64,35 +62,33 @@ module Aspera
64
62
 
65
63
  # Compute this before using transfer spec because it potentially modifies the transfer spec
66
64
  # (even if the var is not used in single session)
67
- multi_session_info=nil
65
+ multi_session_info = nil
68
66
  if transfer_spec.has_key?('multi_session')
69
- multi_session_info={
70
- count: transfer_spec['multi_session'].to_i,
67
+ multi_session_info = {
68
+ count: transfer_spec['multi_session'].to_i
71
69
  }
72
70
  # Managed by multi-session, so delete from transfer spec
73
71
  transfer_spec.delete('multi_session')
74
- if multi_session_info[:count] < 0
72
+ if multi_session_info[:count].negative?
75
73
  Log.log.error("multi_session(#{transfer_spec['multi_session']}) shall be integer >= 0")
76
74
  multi_session_info = nil
77
75
  elsif multi_session_info[:count].eql?(0)
78
- Log.log.debug("multi_session count is zero: no multisession")
76
+ Log.log.debug('multi_session count is zero: no multisession')
79
77
  multi_session_info = nil
80
- else # multi_session_info[:count] > 0
78
+ elsif @options[:multi_incr_udp] # multi_session_info[:count] > 0
81
79
  # if option not true: keep default udp port for all sessions
82
- if @options[:multi_incr_udp]
83
- # override if specified, else use default value
84
- multi_session_info[:udp_base]=transfer_spec.has_key?('fasp_port') ? transfer_spec['fasp_port'] : Default::UDP_PORT
85
- # delete from original transfer spec, as we will increment values
86
- transfer_spec.delete('fasp_port')
87
- end
80
+ multi_session_info[:udp_base] = transfer_spec.has_key?('fasp_port') ? transfer_spec['fasp_port'] : TransferSpec::UDP_PORT
81
+ # delete from original transfer spec, as we will increment values
82
+ transfer_spec.delete('fasp_port')
83
+ # override if specified, else use default value
88
84
  end
89
85
  end
90
86
 
91
87
  # compute known args
92
- env_args=Parameters.ts_to_env_args(transfer_spec,wss: @options[:wss])
88
+ env_args = Parameters.ts_to_env_args(transfer_spec,wss: @options[:wss])
93
89
 
94
90
  # add fallback cert and key as arguments if needed
95
- if ['1','force'].include?(transfer_spec['http_fallback'])
91
+ if %w[1 force].include?(transfer_spec['http_fallback'])
96
92
  env_args[:args].unshift('-Y',Installation.instance.path(:fallback_key))
97
93
  env_args[:args].unshift('-I',Installation.instance.path(:fallback_cert))
98
94
  end
@@ -100,19 +96,19 @@ module Aspera
100
96
  env_args[:args].unshift('-q') if @options[:quiet]
101
97
 
102
98
  # transfer job can be multi session
103
- xfer_job={
104
- :id => job_options[:job_id],
105
- :sessions => [] # all sessions as below
99
+ xfer_job = {
100
+ id: job_options[:job_id],
101
+ sessions: [] # all sessions as below
106
102
  }
107
103
 
108
104
  # generic session information
109
- session={
110
- :thread => nil, # Thread object monitoring management port, not nil when pushed to :sessions
111
- :error => nil, # exception if failed
112
- :io => nil, # management port server socket
113
- :id => nil, # SessionId from INIT message in mgt port
114
- :env_args => env_args, # env vars and args to ascp (from transfer spec)
115
- :options => job_options # [Hash]
105
+ session = {
106
+ thread: nil, # Thread object monitoring management port, not nil when pushed to :sessions
107
+ error: nil, # exception if failed
108
+ io: nil, # management port server socket
109
+ id: nil, # SessionId from INIT message in mgt port
110
+ env_args: env_args, # env vars and args to ascp (from transfer spec)
111
+ options: job_options # [Hash]
116
112
  }
117
113
 
118
114
  if multi_session_info.nil?
@@ -126,12 +122,12 @@ module Aspera
126
122
  # do not delay the first session
127
123
  sleep(@options[:spawn_delay_sec]) unless i.eql?(1)
128
124
  # do deep copy (each thread has its own copy because it is modified here below and in thread)
129
- this_session=session.clone()
130
- this_session[:env_args]=this_session[:env_args].clone()
131
- this_session[:env_args][:args]=this_session[:env_args][:args].clone()
125
+ this_session = session.clone
126
+ this_session[:env_args] = this_session[:env_args].clone
127
+ this_session[:env_args][:args] = this_session[:env_args][:args].clone
132
128
  this_session[:env_args][:args].unshift("-C#{i}:#{multi_session_info[:count]}")
133
129
  # option: increment (default as per ascp manual) or not (cluster on other side ?)
134
- this_session[:env_args][:args].unshift('-O',"#{multi_session_info[:udp_base]+i-1}") if @options[:multi_incr_udp]
130
+ this_session[:env_args][:args].unshift('-O',(multi_session_info[:udp_base] + i - 1).to_s) if @options[:multi_incr_udp]
135
131
  this_session[:thread] = Thread.new(this_session) {|s|transfer_thread_entry(s)}
136
132
  xfer_job[:sessions].push(this_session)
137
133
  end
@@ -139,7 +135,7 @@ module Aspera
139
135
  Log.log.debug('started session thread(s)')
140
136
 
141
137
  # add job to list of jobs
142
- @jobs[job_options[:job_id]]=xfer_job
138
+ @jobs[job_options[:job_id]] = xfer_job
143
139
  Log.log.debug("jobs: #{@jobs.keys.count}")
144
140
 
145
141
  return job_options[:job_id]
@@ -150,12 +146,12 @@ module Aspera
150
146
  def wait_for_transfers_completion
151
147
  Log.log.debug('wait_for_transfers_completion')
152
148
  # set to non-nil to exit loop
153
- result=[]
154
- @jobs.each do |id,job|
149
+ result = []
150
+ @jobs.each do |_id,job|
155
151
  job[:sessions].each do |session|
156
152
  Log.log.debug("join #{session[:thread]}")
157
153
  session[:thread].join
158
- result.push(session[:error] ? session[:error] : :success)
154
+ result.push(session[:error] || :success)
159
155
  end
160
156
  end
161
157
  Log.log.debug('all transfers joined')
@@ -181,29 +177,36 @@ module Aspera
181
177
  raise 'env_args must be Hash' unless env_args.is_a?(Hash)
182
178
  raise 'session must be Hash' unless session.is_a?(Hash)
183
179
  # by default we assume an exception will be raised (for ensure block)
184
- exception_raised=true
180
+ exception_raised = true
185
181
  begin
186
182
  Log.log.debug("env_args=#{env_args.inspect}")
187
183
  # get location of ascp executable
188
- ascp_path=@mutex.synchronize do
184
+ ascp_path = @mutex.synchronize do
189
185
  Fasp::Installation.instance.path(env_args[:ascp_version])
190
186
  end
191
187
  # (optional) check it exists
192
- raise Fasp::Error.new("no such file: #{ascp_path}") unless File.exist?(ascp_path)
188
+ raise Fasp::Error, "no such file: #{ascp_path}" unless File.exist?(ascp_path)
193
189
  # open random local TCP port for listening for ascp management
194
190
  mgt_sock = TCPServer.new('127.0.0.1',0)
195
191
  # clone arguments as we eed to modify with mgt port
196
- ascp_arguments=env_args[:args].clone
192
+ ascp_arguments = env_args[:args].clone
197
193
  # add management port
198
194
  ascp_arguments.unshift('-M', mgt_sock.addr[1].to_s)
199
195
  # start ascp in sub process
200
- Log.log.debug("execute: #{env_args[:env].map{|k,v| "#{k}=\"#{v}\""}.join(' ')} \"#{ascp_path}\" \"#{ascp_arguments.join('" "')}\"")
196
+ Log.log.debug do
197
+ 'execute: '+
198
+ env_args[:env].map{|k,v| "#{k}=#{Shellwords.shellescape(v)}"}.join(' ')+
199
+ ' '+
200
+ Shellwords.shellescape(ascp_path)+
201
+ ' '+
202
+ ascp_arguments.map{|a|Shellwords.shellescape(a)}.join(' ')
203
+ end
201
204
  # start process
202
205
  ascp_pid = Process.spawn(env_args[:env],[ascp_path,ascp_path],*ascp_arguments)
203
206
  # in parent, wait for connection to socket max 3 seconds
204
207
  Log.log.debug("before accept for pid (#{ascp_pid})")
205
208
  # init management socket
206
- ascp_mgt_io=nil
209
+ ascp_mgt_io = nil
207
210
  Timeout.timeout(@options[:spawn_timeout_sec]) do
208
211
  ascp_mgt_io = mgt_sock.accept
209
212
  # management messages include file names which may be utf8
@@ -212,38 +215,38 @@ module Aspera
212
215
  ascp_mgt_io.set_encoding(Encoding::UTF_8)
213
216
  end
214
217
  Log.log.debug("after accept (#{ascp_mgt_io})")
215
- session[:io]=ascp_mgt_io
218
+ session[:io] = ascp_mgt_io
216
219
  # exact text for event, with \n
217
- current_event_text=''
220
+ current_event_text = ''
218
221
  # parsed event (hash)
219
- current_event_data=nil
222
+ current_event_data = nil
220
223
  # this is the last full status
221
- last_status_event=nil
224
+ last_status_event = nil
222
225
  # read management port
223
226
  loop do
224
227
  # TODO: timeout here ?
225
228
  line = ascp_mgt_io.gets
226
229
  # nil when ascp process exits
227
230
  break if line.nil?
228
- current_event_text=current_event_text+line
231
+ current_event_text += line
229
232
  line.chomp!
230
233
  Log.log.debug("line=[#{line}]")
231
234
  case line
232
235
  when 'FASPMGR 2'
233
236
  # begin event
234
- current_event_data = Hash.new
237
+ current_event_data = {}
235
238
  current_event_text = ''
236
239
  when /^([^:]+): (.*)$/
237
240
  # event field
238
- current_event_data[$1] = $2
241
+ current_event_data[Regexp.last_match(1)] = Regexp.last_match(2)
239
242
  when ''
240
243
  # empty line is separator to end event information
241
244
  raise 'unexpected empty line' if current_event_data.nil?
242
- current_event_data[AgentBase::LISTENER_SESSION_ID_B]=ascp_pid
245
+ current_event_data[AgentBase::LISTENER_SESSION_ID_B] = ascp_pid
243
246
  notify_listeners(current_event_text,current_event_data)
244
247
  case current_event_data['Type']
245
248
  when 'INIT'
246
- session[:id]=current_event_data['SessionId']
249
+ session[:id] = current_event_data['SessionId']
247
250
  Log.log.debug("session id: #{session[:id]}")
248
251
  when 'DONE','ERROR'
249
252
  # TODO: check if this is always the last event
@@ -258,15 +261,15 @@ module Aspera
258
261
  case last_status_event['Type']
259
262
  when 'DONE'
260
263
  # all went well
261
- exception_raised=false
264
+ exception_raised = false
262
265
  when 'ERROR'
263
266
  Log.log.error("code: #{last_status_event['Code']}")
264
- if last_status_event['Description'] =~ /bearer token/i
267
+ if /bearer token/i.match?(last_status_event['Description'])
265
268
  Log.log.error('need to regenerate token'.red)
266
- if session[:options].is_a?(Hash) and session[:options].has_key?(:regenerate_token)
269
+ if session[:options].is_a?(Hash) && session[:options].has_key?(:regenerate_token)
267
270
  # regenerate token here, expired, or error on it
268
271
  # Note: in multi-session, each session will have a different one.
269
- env_args[:env]['ASPERA_SCP_TOKEN']=session[:options][:regenerate_token].call(true)
272
+ env_args[:env]['ASPERA_SCP_TOKEN'] = session[:options][:regenerate_token].call(true)
270
273
  end
271
274
  end
272
275
  raise Fasp::Error.new(last_status_event['Description'],last_status_event['Code'].to_i)
@@ -274,32 +277,30 @@ module Aspera
274
277
  raise "unexpected last event type: #{last_status_event['Type']}"
275
278
  end
276
279
  else
277
- exception_raised=false
280
+ exception_raised = false
278
281
  Log.log.debug('no status read from ascp mgt port')
279
282
  end
280
283
  rescue SystemCallError => e
281
284
  # Process.spawn
282
- raise Fasp::Error.new(e.message)
283
- rescue Timeout::Error => e
284
- raise Fasp::Error.new('timeout waiting mgt port connect')
285
- rescue Interrupt => e
286
- raise Fasp::Error.new('transfer interrupted by user')
285
+ raise Fasp::Error, e.message
286
+ rescue Timeout::Error
287
+ raise Fasp::Error, 'timeout waiting mgt port connect'
288
+ rescue Interrupt
289
+ raise Fasp::Error, 'transfer interrupted by user'
287
290
  ensure
288
291
  # if ascp was successfully started
289
292
  unless ascp_pid.nil?
290
293
  # "wait" for process to avoid zombie
291
294
  Process.wait(ascp_pid)
292
- status=$?
293
- ascp_pid=nil
295
+ status = $CHILD_STATUS
296
+ ascp_pid = nil
294
297
  session.delete(:io)
295
298
  if !status.success?
296
- message="ascp failed with code #{status.exitstatus}"
297
- if exception_raised
298
- # just debug, as main exception is already here
299
- Log.log.debug(message)
300
- else
301
- raise Fasp::Error.new(message)
302
- end
299
+ message = "ascp failed with code #{status.exitstatus}"
300
+ # raise error only if there was not already an exception
301
+ raise Fasp::Error, message unless exception_raised
302
+ # else just debug, as main exception is already here
303
+ Log.log.debug(message)
303
304
  end
304
305
  end
305
306
  end # begin-ensure
@@ -312,18 +313,18 @@ module Aspera
312
313
  # {'type'=>'START','source'=>_path_,'destination'=>_path_}
313
314
  # {'type'=>'DONE'}
314
315
  def send_command(job_id,session_index,data)
315
- job=@jobs[job_id]
316
+ job = @jobs[job_id]
316
317
  raise 'no such job' if job.nil?
317
- session=job[:sessions][session_index]
318
+ session = job[:sessions][session_index]
318
319
  raise 'no such session' if session.nil?
319
320
  Log.log.debug("command: #{data}")
320
321
  # build command
321
- command=data.
322
- keys.
323
- map{|k|"#{k.capitalize}: #{data[k]}"}.
324
- unshift('FASPMGR 2').
325
- push('','').
326
- join("\n")
322
+ command = data.
323
+ keys.
324
+ map{|k|"#{k.capitalize}: #{data[k]}"}.
325
+ unshift('FASPMGR 2').
326
+ push('','').
327
+ join("\n")
327
328
  session[:io].puts(command)
328
329
  end
329
330
 
@@ -333,23 +334,20 @@ module Aspera
333
334
  def initialize(options=nil)
334
335
  super()
335
336
  # all transfer jobs, key = SecureRandom.uuid, protected by mutex, condvar on change
336
- @jobs={}
337
+ @jobs = {}
337
338
  # mutex protects global data accessed by threads
338
- @mutex=Mutex.new
339
+ @mutex = Mutex.new
339
340
  # set default options and override if specified
340
- @options=DEFAULT_OPTIONS.clone
341
+ @options = DEFAULT_OPTIONS.dup
341
342
  if !options.nil?
342
343
  raise "expecting Hash (or nil), but have #{options.class}" unless options.is_a?(Hash)
343
344
  options.each do |k,v|
344
- if DEFAULT_OPTIONS.has_key?(k)
345
- @options[k]=v
346
- else
347
- raise "Unknown local agent parameter: #{k}, expect one of #{DEFAULT_OPTIONS.keys.map{|i|i.to_s}.join(",")}"
348
- end
345
+ raise "Unknown local agent parameter: #{k}, expect one of #{DEFAULT_OPTIONS.keys.map(&:to_s).join(',')}" unless DEFAULT_OPTIONS.has_key?(k)
346
+ @options[k] = v
349
347
  end
350
348
  end
351
349
  Log.log.debug("local options= #{options}")
352
- @resume_policy=ResumePolicy.new(@options[:resume].symbolize_keys)
350
+ @resume_policy = ResumePolicy.new(@options[:resume].symbolize_keys)
353
351
  end
354
352
 
355
353
  # transfer thread entry
@@ -357,20 +355,19 @@ module Aspera
357
355
  def transfer_thread_entry(session)
358
356
  begin
359
357
  # set name for logging
360
- Thread.current[:name]='transfer'
358
+ Thread.current[:name] = 'transfer'
361
359
  Log.log.debug("ENTER (#{Thread.current[:name]})")
362
360
  # start transfer with selected resumer policy
363
- session[:options][:resumer].process do
361
+ session[:options][:resumer].execute_with_resume do
364
362
  start_transfer_with_args_env(session[:env_args],session)
365
363
  end
366
364
  Log.log.debug('transfer ok'.bg_green)
367
- rescue => e
368
- session[:error]=e
365
+ rescue StandardError => e
366
+ session[:error] = e
369
367
  Log.log.error("Transfer thread error: #{e.class}:\n#{e.message}:\n#{e.backtrace.join("\n")}".red) if Log.instance.level.eql?(:debug)
370
368
  end
371
369
  Log.log.debug("EXIT (#{Thread.current[:name]})")
372
370
  end
373
-
374
371
  end # AgentDirect
375
372
  end
376
373
  end