aspera-cli 4.15.0 → 4.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/BUGS.md +29 -3
- data/CHANGELOG.md +292 -228
- data/CONTRIBUTING.md +69 -18
- data/README.md +1102 -952
- data/bin/ascli +13 -31
- data/bin/asession +3 -1
- data/examples/dascli +2 -2
- data/lib/aspera/aoc.rb +28 -33
- data/lib/aspera/ascmd.rb +3 -6
- data/lib/aspera/assert.rb +45 -0
- data/lib/aspera/cli/extended_value.rb +5 -5
- data/lib/aspera/cli/formatter.rb +26 -13
- data/lib/aspera/cli/hints.rb +4 -3
- data/lib/aspera/cli/main.rb +16 -3
- data/lib/aspera/cli/manager.rb +45 -36
- data/lib/aspera/cli/plugin.rb +20 -13
- data/lib/aspera/cli/plugins/aoc.rb +103 -73
- data/lib/aspera/cli/plugins/ats.rb +4 -3
- data/lib/aspera/cli/plugins/config.rb +114 -119
- data/lib/aspera/cli/plugins/cos.rb +2 -2
- data/lib/aspera/cli/plugins/faspex.rb +23 -19
- data/lib/aspera/cli/plugins/faspex5.rb +75 -43
- data/lib/aspera/cli/plugins/node.rb +28 -15
- data/lib/aspera/cli/plugins/orchestrator.rb +4 -2
- data/lib/aspera/cli/plugins/preview.rb +9 -7
- data/lib/aspera/cli/plugins/server.rb +6 -3
- data/lib/aspera/cli/plugins/shares.rb +30 -26
- data/lib/aspera/cli/sync_actions.rb +9 -9
- data/lib/aspera/cli/transfer_agent.rb +21 -14
- data/lib/aspera/cli/transfer_progress.rb +2 -3
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +13 -11
- data/lib/aspera/cos_node.rb +3 -2
- data/lib/aspera/coverage.rb +22 -0
- data/lib/aspera/data_repository.rb +33 -2
- data/lib/aspera/environment.rb +4 -2
- data/lib/aspera/fasp/{agent_aspera.rb → agent_alpha.rb} +29 -39
- data/lib/aspera/fasp/agent_base.rb +17 -7
- data/lib/aspera/fasp/agent_direct.rb +88 -84
- data/lib/aspera/fasp/agent_httpgw.rb +4 -3
- data/lib/aspera/fasp/agent_node.rb +3 -2
- data/lib/aspera/fasp/agent_trsdk.rb +79 -37
- data/lib/aspera/fasp/installation.rb +51 -12
- data/lib/aspera/fasp/management.rb +11 -6
- data/lib/aspera/fasp/parameters.rb +53 -47
- data/lib/aspera/fasp/resume_policy.rb +7 -5
- data/lib/aspera/fasp/sync.rb +273 -0
- data/lib/aspera/fasp/transfer_spec.rb +10 -8
- data/lib/aspera/fasp/uri.rb +2 -2
- data/lib/aspera/faspex_gw.rb +11 -8
- data/lib/aspera/faspex_postproc.rb +6 -5
- data/lib/aspera/id_generator.rb +3 -1
- data/lib/aspera/json_rpc.rb +10 -8
- data/lib/aspera/keychain/encrypted_hash.rb +46 -11
- data/lib/aspera/keychain/macos_security.rb +15 -13
- data/lib/aspera/log.rb +4 -3
- data/lib/aspera/nagios.rb +7 -2
- data/lib/aspera/node.rb +17 -16
- data/lib/aspera/node_simulator.rb +214 -0
- data/lib/aspera/oauth.rb +22 -19
- data/lib/aspera/persistency_action_once.rb +13 -14
- data/lib/aspera/persistency_folder.rb +3 -2
- data/lib/aspera/preview/file_types.rb +53 -267
- data/lib/aspera/preview/generator.rb +7 -5
- data/lib/aspera/preview/terminal.rb +14 -5
- data/lib/aspera/preview/utils.rb +8 -7
- data/lib/aspera/proxy_auto_config.rb +6 -3
- data/lib/aspera/rest.rb +29 -13
- data/lib/aspera/rest_error_analyzer.rb +1 -0
- data/lib/aspera/rest_errors_aspera.rb +2 -0
- data/lib/aspera/secret_hider.rb +5 -2
- data/lib/aspera/ssh.rb +10 -8
- data/lib/aspera/temp_file_manager.rb +1 -1
- data/lib/aspera/web_server_simple.rb +2 -1
- data.tar.gz.sig +0 -0
- metadata +96 -45
- metadata.gz.sig +0 -0
- data/lib/aspera/sync.rb +0 -219
@@ -5,6 +5,7 @@ require 'aspera/environment'
|
|
5
5
|
require 'aspera/data_repository'
|
6
6
|
require 'aspera/fasp/products'
|
7
7
|
require 'aspera/log'
|
8
|
+
require 'aspera/assert'
|
8
9
|
require 'aspera/web_server_simple'
|
9
10
|
require 'English'
|
10
11
|
require 'singleton'
|
@@ -107,6 +108,7 @@ module Aspera
|
|
107
108
|
# get path of one resource file of currently activated product
|
108
109
|
# keys and certs are generated locally... (they are well known values, arch. independent)
|
109
110
|
def path(k)
|
111
|
+
file_is_optional = false
|
110
112
|
case k
|
111
113
|
when :ascp, :ascp4
|
112
114
|
use_ascp_from_product(FIRST_FOUND) if @path_to_ascp.nil?
|
@@ -115,17 +117,13 @@ module Aspera
|
|
115
117
|
file = file.gsub('ascp', 'ascp4') if k.eql?(:ascp4)
|
116
118
|
when :transferd
|
117
119
|
file = transferd_filepath
|
120
|
+
file_is_optional = true
|
118
121
|
when :ssh_private_dsa, :ssh_private_rsa
|
119
122
|
# assume last 3 letters are type
|
120
|
-
type = k.to_s[-3..-1]
|
121
|
-
file = check_or_create_sdk_file("aspera_bypass_#{type}.pem")
|
122
|
-
# generate PEM from DER
|
123
|
-
OpenSSL::PKey.const_get(type.upcase).new(DataRepository.instance.data(type.eql?('dsa') ? 1 : 2)).to_pem
|
124
|
-
end
|
123
|
+
type = k.to_s[-3..-1].to_sym
|
124
|
+
file = check_or_create_sdk_file("aspera_bypass_#{type}.pem") {DataRepository.instance.item(type)}
|
125
125
|
when :aspera_license
|
126
|
-
file = check_or_create_sdk_file('aspera-license')
|
127
|
-
Zlib::Inflate.inflate(DataRepository.instance.data(6))
|
128
|
-
end
|
126
|
+
file = check_or_create_sdk_file('aspera-license') {DataRepository.instance.item(:license)}
|
129
127
|
when :aspera_conf
|
130
128
|
file = check_or_create_sdk_file('aspera.conf') {DEFAULT_ASPERA_CONF}
|
131
129
|
when :fallback_certificate, :fallback_private_key
|
@@ -141,16 +139,16 @@ module Aspera
|
|
141
139
|
check_or_create_sdk_file('aspera_fallback_cert.pem', force: true) {cert.to_pem}
|
142
140
|
end
|
143
141
|
file = k.eql?(:fallback_certificate) ? file_cert : file_key
|
144
|
-
else
|
145
|
-
raise "INTERNAL ERROR: #{k}"
|
142
|
+
else error_unexpected_value(k)
|
146
143
|
end
|
147
|
-
|
144
|
+
return nil if file_is_optional && !File.exist?(file)
|
145
|
+
assert(File.exist?(file)){"no such file: #{file}"}
|
148
146
|
return file
|
149
147
|
end
|
150
148
|
|
151
149
|
# default bypass key phrase
|
152
150
|
def ssh_cert_uuid
|
153
|
-
return
|
151
|
+
return DataRepository.instance.item(:uuid)
|
154
152
|
end
|
155
153
|
|
156
154
|
def aspera_token_ssh_key_paths
|
@@ -175,6 +173,47 @@ module Aspera
|
|
175
173
|
return exe_version
|
176
174
|
end
|
177
175
|
|
176
|
+
def ascp_info
|
177
|
+
data = file_paths
|
178
|
+
# read PATHs from ascp directly, and pvcl modules as well
|
179
|
+
Open3.popen3(data['ascp'], '-DDL-') do |_stdin, _stdout, stderr, thread|
|
180
|
+
last_line = ''
|
181
|
+
while (line = stderr.gets)
|
182
|
+
line.chomp!
|
183
|
+
last_line = line
|
184
|
+
case line
|
185
|
+
when /^DBG Path ([^ ]+) (dir|file) +: (.*)$/
|
186
|
+
data[Regexp.last_match(1)] = Regexp.last_match(3)
|
187
|
+
when /^DBG Added module group:"(?<module>[^"]+)" name:"(?<scheme>[^"]+)", version:"(?<version>[^"]+)" interface:"(?<interface>[^"]+)"$/
|
188
|
+
c = Regexp.last_match.named_captures.symbolize_keys
|
189
|
+
data[c[:interface]] ||= {}
|
190
|
+
data[c[:interface]][c[:module]] ||= []
|
191
|
+
data[c[:interface]][c[:module]].push("#{c[:scheme]} v#{c[:version]}")
|
192
|
+
when %r{^DBG License result \(/license/(\S+)\): (.+)$}
|
193
|
+
data[Regexp.last_match(1)] = Regexp.last_match(2)
|
194
|
+
when /^LOG (.+) version ([0-9.]+)$/
|
195
|
+
data['product_name'] = Regexp.last_match(1)
|
196
|
+
data['product_version'] = Regexp.last_match(2)
|
197
|
+
when /^LOG Initializing FASP version ([^,]+),/
|
198
|
+
data['ascp_version'] = Regexp.last_match(1)
|
199
|
+
end
|
200
|
+
end
|
201
|
+
if !thread.value.exitstatus.eql?(1) && !data.key?('root')
|
202
|
+
raise last_line
|
203
|
+
end
|
204
|
+
end
|
205
|
+
# ascp's openssl directory
|
206
|
+
ascp_file = data['ascp']
|
207
|
+
File.binread(ascp_file).scan(/[\x20-\x7E]{4,}/) do |match|
|
208
|
+
if (m = match.match(/OPENSSLDIR.*"(.*)"/))
|
209
|
+
data['openssldir'] = m[1]
|
210
|
+
end
|
211
|
+
end if File.file?(ascp_file)
|
212
|
+
# log is "-" no need to display
|
213
|
+
data.delete('log')
|
214
|
+
return data
|
215
|
+
end
|
216
|
+
|
178
217
|
# download aspera SDK or use local file
|
179
218
|
# extracts ascp binary for current system architecture
|
180
219
|
# @return ascp version (from execution)
|
@@ -185,6 +185,8 @@ module Aspera
|
|
185
185
|
ExtraCreatePolicy]
|
186
186
|
# Management port start message
|
187
187
|
MGT_HEADER = 'FASPMGR 2'
|
188
|
+
# empty line is separator to end event information
|
189
|
+
MGT_FRAME_SEPARATOR = ''
|
188
190
|
# fields description for JSON generation
|
189
191
|
# spellchecker: disable
|
190
192
|
INTEGER_FIELDS = %w[Bytescont FaspFileArgIndex StartByte Rate MinRate Port Priority RateCap MinRateCap TCPPort CreatePolicy TimePolicy
|
@@ -193,10 +195,11 @@ module Aspera
|
|
193
195
|
ArgScansCompleted PathScansAttempted FileScansCompleted TransfersAttempted TransfersPassed Delay].freeze
|
194
196
|
BOOLEAN_FIELDS = %w[Encryption Remote RateLock MinRateLock PolicyLock FilesEncrypt FilesDecrypt VLinkLocalEnabled VLinkRemoteEnabled
|
195
197
|
MoveRange Keepalive TestLogin UseProxy Precalc RTTAutocorrect].freeze
|
198
|
+
BOOLEAN_TRUE = 'Yes'
|
196
199
|
# cspell: enable
|
197
200
|
|
198
201
|
class << self
|
199
|
-
# translates
|
202
|
+
# translates mgt port event into (enhanced) typed event
|
200
203
|
def enhanced_event_format(event)
|
201
204
|
return event.keys.each_with_object({}) do |e, h|
|
202
205
|
# capital_to_snake_case
|
@@ -207,14 +210,16 @@ module Aspera
|
|
207
210
|
.downcase
|
208
211
|
value = event[e]
|
209
212
|
value = value.to_i if INTEGER_FIELDS.include?(e)
|
210
|
-
value = value.eql?(
|
213
|
+
value = value.eql?(BOOLEAN_TRUE) if BOOLEAN_FIELDS.include?(e)
|
211
214
|
h[new_name] = value
|
212
215
|
end
|
213
216
|
end
|
214
217
|
end # class << self
|
215
218
|
|
216
219
|
def initialize
|
220
|
+
# current event being parsed line by line
|
217
221
|
@event_build = nil
|
222
|
+
# last fully built event
|
218
223
|
@last_event = nil
|
219
224
|
end
|
220
225
|
attr_reader :last_event
|
@@ -226,16 +231,16 @@ module Aspera
|
|
226
231
|
# begin event
|
227
232
|
@event_build = {}
|
228
233
|
when /^([^:]+): (.*)$/
|
234
|
+
raise 'mgt port: unexpected line: data without header' if @event_build.nil?
|
229
235
|
# event field
|
230
236
|
@event_build[Regexp.last_match(1)] = Regexp.last_match(2)
|
231
|
-
when
|
232
|
-
|
233
|
-
raise 'unexpected empty line' if @event_build.nil?
|
237
|
+
when MGT_FRAME_SEPARATOR
|
238
|
+
raise 'mgt port: unexpected line: end frame without header' if @event_build.nil?
|
234
239
|
@last_event = @event_build
|
235
240
|
@event_build = nil
|
236
241
|
return @last_event
|
237
242
|
else
|
238
|
-
raise "unexpected line:[#{line}]"
|
243
|
+
raise "mgt port: unexpected line: [#{line}]"
|
239
244
|
end # case
|
240
245
|
return nil
|
241
246
|
end
|
@@ -1,6 +1,7 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'aspera/log'
|
4
|
+
require 'aspera/assert'
|
4
5
|
require 'aspera/command_line_builder'
|
5
6
|
require 'aspera/temp_file_manager'
|
6
7
|
require 'aspera/fasp/error'
|
@@ -23,9 +24,10 @@ module Aspera
|
|
23
24
|
# Short names of columns in manual
|
24
25
|
SUPPORTED_AGENTS_SHORT = SUPPORTED_AGENTS.map{|a|a.to_s[0].to_sym}
|
25
26
|
FILE_LIST_OPTIONS = ['--file-list', '--file-pair-list'].freeze
|
26
|
-
|
27
|
+
# options that can be provided to the constructor, and then in @options
|
28
|
+
SUPPORTED_OPTIONS = %i[ascp_args wss check_ignore quiet trusted_certs].freeze
|
27
29
|
|
28
|
-
private_constant :SUPPORTED_AGENTS, :FILE_LIST_OPTIONS
|
30
|
+
private_constant :SUPPORTED_AGENTS, :FILE_LIST_OPTIONS, :SUPPORTED_OPTIONS
|
29
31
|
|
30
32
|
class << self
|
31
33
|
# Temp folder for file lists, must contain only file lists
|
@@ -125,17 +127,21 @@ module Aspera
|
|
125
127
|
|
126
128
|
# @param options [Hash] key: :wss: bool, :ascp_args: array of strings
|
127
129
|
def initialize(job_spec, options)
|
130
|
+
assert_type(job_spec, Hash)
|
131
|
+
assert_type(options, Hash)
|
128
132
|
@job_spec = job_spec
|
129
133
|
# check necessary options
|
130
134
|
missing_options = SUPPORTED_OPTIONS - options.keys
|
131
|
-
|
135
|
+
assert(missing_options.empty?){"missing options: #{missing_options.join(', ')}"}
|
132
136
|
@options = SUPPORTED_OPTIONS.each_with_object({}){|o, h| h[o] = options[o]}
|
133
137
|
Log.log.debug{Log.dump(:parameters_options, @options)}
|
134
|
-
|
135
|
-
|
138
|
+
Log.log.debug{Log.dump(:dismiss_options, options.keys - SUPPORTED_OPTIONS)}
|
139
|
+
assert_type(@options[:ascp_args], Array){'ascp_args'}
|
140
|
+
assert(@options[:ascp_args].all?(String)){'ascp arguments must Strings'}
|
136
141
|
@builder = Aspera::CommandLineBuilder.new(@job_spec, self.class.description)
|
137
142
|
end
|
138
143
|
|
144
|
+
# either place source files on command line, or add file list file
|
139
145
|
def process_file_list
|
140
146
|
# is the file list provided through EX_ parameters?
|
141
147
|
ascp_file_list_provided = self.class.ts_has_ascp_file_list(@job_spec, @options[:ascp_args])
|
@@ -160,7 +166,7 @@ module Aspera
|
|
160
166
|
Log.log.debug('placing source file list on command line (no file list file)')
|
161
167
|
@builder.add_command_line_options(ts_paths_array.map{|i|i['source']})
|
162
168
|
else
|
163
|
-
|
169
|
+
assert(ts_paths_array.all?{|i|i.key?('source')}){"All elements of paths must have a 'source' key"}
|
164
170
|
is_pair_list = ts_paths_array.any?{|i|i.key?('destination')}
|
165
171
|
raise "All elements of paths must be consistent with 'destination' key" if is_pair_list && !ts_paths_array.all?{|i|i.key?('destination')}
|
166
172
|
# safer option: generate a file list file if there is storage defined for it
|
@@ -184,92 +190,92 @@ module Aspera
|
|
184
190
|
@builder.add_command_line_options(["#{option}=#{file_list_file}"]) unless option.nil?
|
185
191
|
end
|
186
192
|
|
187
|
-
|
188
|
-
|
189
|
-
def ascp_args
|
190
|
-
env_args = {
|
191
|
-
args: [],
|
192
|
-
env: {},
|
193
|
-
ascp_version: :ascp
|
194
|
-
}
|
195
|
-
|
196
|
-
# special cases
|
197
|
-
@job_spec.delete('source_root') if @job_spec.key?('source_root') && @job_spec['source_root'].empty?
|
198
|
-
|
199
|
-
# notify multi-session was already used, anyway it was deleted by agent direct
|
200
|
-
raise 'internal error' if @builder.read_param('multi_session')
|
201
|
-
|
193
|
+
def remote_certificates
|
194
|
+
certificates_to_use = []
|
202
195
|
# use web socket secure for session ?
|
203
196
|
if @builder.read_param('wss_enabled') && (@options[:wss] || !@job_spec.key?('fasp_port'))
|
204
197
|
# by default use web socket session if available, unless removed by user
|
205
198
|
@builder.add_command_line_options(['--ws-connect'])
|
206
|
-
# TODO: option to give order ssh,ws (legacy http is implied
|
199
|
+
# TODO: option to give order ssh,ws (legacy http is implied by ssh)
|
207
200
|
# This will need to be cleaned up in aspera core
|
208
201
|
@job_spec['ssh_port'] = @builder.read_param('wss_port')
|
209
202
|
@job_spec.delete('fasp_port')
|
210
203
|
@job_spec.delete('EX_ssh_key_paths')
|
211
204
|
@job_spec.delete('sshfp')
|
205
|
+
# ignore cert for wss ?
|
212
206
|
if @options[:check_ignore]&.call(@job_spec['remote_host'], @job_spec['wss_port'])
|
213
|
-
http_session = Rest.start_http_session("https://#{@job_spec['remote_host']}:#{@job_spec['wss_port']}")
|
214
|
-
# wss_api = Rest.new(base_url: "/v1/transfer")
|
215
|
-
# wss_api.read('start') rescue nil
|
216
207
|
wss_cert_file = TempFileManager.instance.new_file_path_global('wss_cert')
|
217
|
-
|
218
|
-
|
219
|
-
|
220
|
-
Log.log.debug{"CA certs for wss: remote cert: #{wss_cert_file}"}
|
221
|
-
else
|
222
|
-
# set location for CA bundle to be the one of Ruby, see env var SSL_CERT_FILE / SSL_CERT_DIR
|
223
|
-
@options[:trusted_certs].each do |file|
|
224
|
-
env_args[:args].unshift('-i', file)
|
225
|
-
Log.log.debug{"trusted certs for wss: #{file}"}
|
226
|
-
end
|
208
|
+
wss_url = "https://#{@job_spec['remote_host']}:#{@job_spec['wss_port']}"
|
209
|
+
File.write(wss_cert_file, Rest.remote_certificates(wss_url))
|
210
|
+
certificates_to_use.push(wss_cert_file)
|
227
211
|
end
|
212
|
+
# set location for CA bundle to be the one of Ruby, see env var SSL_CERT_FILE / SSL_CERT_DIR
|
213
|
+
certificates_to_use.concat(@options[:trusted_certs]) if @options[:trusted_certs]
|
228
214
|
else
|
229
215
|
# remove unused parameter (avoid warning)
|
230
216
|
@job_spec.delete('wss_port')
|
231
217
|
# add SSH bypass keys when authentication is token and no auth is provided
|
232
218
|
if @job_spec.key?('token') && !@job_spec.key?('remote_password')
|
233
219
|
# @job_spec['remote_password'] = Installation.instance.ssh_cert_uuid # not used: no passphrase
|
234
|
-
Installation.instance.aspera_token_ssh_key_paths
|
220
|
+
certificates_to_use.concat(Installation.instance.aspera_token_ssh_key_paths)
|
235
221
|
end
|
236
222
|
end
|
223
|
+
return certificates_to_use
|
224
|
+
end
|
225
|
+
|
226
|
+
# translate transfer spec to env vars and command line arguments for ascp
|
227
|
+
# NOTE: parameters starting with "EX_" (extended) are not standard
|
228
|
+
def ascp_args
|
229
|
+
env_args = {
|
230
|
+
args: [],
|
231
|
+
env: {},
|
232
|
+
ascp_version: :ascp
|
233
|
+
}
|
234
|
+
|
235
|
+
# special cases
|
236
|
+
@job_spec.delete('source_root') if @job_spec.key?('source_root') && @job_spec['source_root'].empty?
|
237
|
+
|
238
|
+
# notify multi-session was already used, anyway it was deleted by agent direct
|
239
|
+
assert(!@builder.read_param('multi_session'))
|
240
|
+
|
241
|
+
# add ssh or wss certificates
|
242
|
+
remote_certificates.each do |cert|
|
243
|
+
Log.log.trace1{"adding certificate: #{cert}"}
|
244
|
+
env_args[:args].unshift('-i', cert)
|
245
|
+
end
|
237
246
|
|
238
247
|
# process parameters as specified in table
|
239
248
|
@builder.process_params
|
240
249
|
|
250
|
+
base64_destination = false
|
241
251
|
# symbol must be index of Installation.paths
|
242
252
|
if @builder.read_param('use_ascp4')
|
243
253
|
env_args[:ascp_version] = :ascp4
|
244
254
|
else
|
245
255
|
env_args[:ascp_version] = :ascp
|
246
|
-
|
247
|
-
@builder.add_command_line_options(['--dest64'])
|
256
|
+
base64_destination = true
|
248
257
|
end
|
249
|
-
#
|
250
|
-
|
258
|
+
# destination will be base64 encoded, put this before source path arguments
|
259
|
+
@builder.add_command_line_options(['--dest64']) if base64_destination
|
251
260
|
# optional arguments, at the end to override previous ones (to allow override)
|
252
261
|
@builder.add_command_line_options(@builder.read_param('EX_ascp_args'))
|
253
262
|
@builder.add_command_line_options(@options[:ascp_args])
|
263
|
+
# get list of source files to transfer and build arg for ascp
|
264
|
+
process_file_list
|
254
265
|
# process destination folder
|
255
266
|
destination_folder = @builder.read_param('destination_root') || '/'
|
256
267
|
# ascp4 does not support base64 encoding of destination
|
257
|
-
destination_folder = Base64.strict_encode64(destination_folder)
|
268
|
+
destination_folder = Base64.strict_encode64(destination_folder) if base64_destination
|
258
269
|
# destination MUST be last command line argument to ascp
|
259
270
|
@builder.add_command_line_options([destination_folder])
|
260
|
-
|
261
|
-
Log.log.debug{"ascp args: #{env_args}"}
|
262
|
-
|
263
271
|
@builder.add_env_args(env_args)
|
264
|
-
|
265
272
|
env_args[:args].unshift('-q') if @options[:quiet]
|
266
|
-
|
267
273
|
# add fallback cert and key as arguments if needed
|
268
274
|
if ['1', 1, true, 'force'].include?(@job_spec['http_fallback'])
|
269
275
|
env_args[:args].unshift('-Y', Installation.instance.path(:fallback_private_key))
|
270
276
|
env_args[:args].unshift('-I', Installation.instance.path(:fallback_certificate))
|
271
277
|
end
|
272
|
-
|
278
|
+
Log.log.debug{"ascp args: #{env_args}"}
|
273
279
|
return env_args
|
274
280
|
end
|
275
281
|
end # Parameters
|
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require 'singleton'
|
4
4
|
require 'aspera/log'
|
5
|
+
require 'aspera/assert'
|
5
6
|
|
6
7
|
module Aspera
|
7
8
|
module Fasp
|
@@ -19,10 +20,10 @@ module Aspera
|
|
19
20
|
def initialize(params=nil)
|
20
21
|
@parameters = DEFAULTS.dup
|
21
22
|
if !params.nil?
|
22
|
-
|
23
|
+
assert_type(params, Hash)
|
23
24
|
params.each do |k, v|
|
24
|
-
|
25
|
-
|
25
|
+
assert_values(k, DEFAULTS.keys){'resume parameter'}
|
26
|
+
assert_type(v, Integer){k}
|
26
27
|
@parameters[k] = v
|
27
28
|
end
|
28
29
|
end
|
@@ -32,7 +33,7 @@ module Aspera
|
|
32
33
|
# calls block a number of times (resumes) until success or limit reached
|
33
34
|
# this is re-entrant, one resumer can handle multiple transfers in //
|
34
35
|
def execute_with_resume
|
35
|
-
|
36
|
+
assert(block_given?)
|
36
37
|
# maximum of retry
|
37
38
|
remaining_resumes = @parameters[:iter_max]
|
38
39
|
sleep_seconds = @parameters[:sleep_initial]
|
@@ -43,9 +44,10 @@ module Aspera
|
|
43
44
|
begin
|
44
45
|
# call provided block
|
45
46
|
yield
|
47
|
+
# exit retry loop if success
|
46
48
|
break
|
47
49
|
rescue Fasp::Error => e
|
48
|
-
Log.log.warn{"An error occurred: #{e.message}"}
|
50
|
+
Log.log.warn{"An error occurred during transfer: #{e.message}"}
|
49
51
|
# failure in ascp
|
50
52
|
if e.retryable?
|
51
53
|
# exit if we exceed the max number of retry
|