aspera-cli 4.15.0 → 4.16.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.
- 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
|