aspera-cli 4.7.0 → 4.9.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/README.md +1267 -999
- data/bin/ascli +20 -1
- data/bin/asession +37 -34
- data/docs/test_env.conf +7 -3
- data/examples/aoc.rb +13 -12
- data/examples/dascli +23 -0
- data/examples/faspex4.rb +34 -29
- data/examples/{transfer.rb → node.rb} +31 -59
- data/examples/server.rb +93 -0
- data/lib/aspera/aoc.rb +153 -143
- data/lib/aspera/ascmd.rb +56 -45
- data/lib/aspera/ats_api.rb +9 -6
- data/lib/aspera/cli/basic_auth_plugin.rb +18 -16
- data/lib/aspera/cli/extended_value.rb +33 -30
- data/lib/aspera/cli/formater.rb +105 -111
- data/lib/aspera/cli/info.rb +3 -2
- data/lib/aspera/cli/listener/line_dump.rb +1 -0
- data/lib/aspera/cli/listener/logger.rb +1 -0
- data/lib/aspera/cli/listener/progress.rb +13 -12
- data/lib/aspera/cli/listener/progress_multi.rb +21 -20
- data/lib/aspera/cli/main.rb +110 -90
- data/lib/aspera/cli/manager.rb +99 -88
- data/lib/aspera/cli/plugin.rb +98 -39
- data/lib/aspera/cli/plugins/alee.rb +6 -5
- data/lib/aspera/cli/plugins/aoc.rb +581 -450
- data/lib/aspera/cli/plugins/ats.rb +84 -83
- data/lib/aspera/cli/plugins/bss.rb +30 -27
- data/lib/aspera/cli/plugins/config.rb +488 -397
- data/lib/aspera/cli/plugins/console.rb +17 -15
- data/lib/aspera/cli/plugins/cos.rb +26 -35
- data/lib/aspera/cli/plugins/faspex.rb +206 -172
- data/lib/aspera/cli/plugins/faspex5.rb +109 -74
- data/lib/aspera/cli/plugins/node.rb +379 -189
- data/lib/aspera/cli/plugins/orchestrator.rb +71 -65
- data/lib/aspera/cli/plugins/preview.rb +131 -122
- data/lib/aspera/cli/plugins/server.rb +50 -150
- data/lib/aspera/cli/plugins/shares.rb +61 -27
- data/lib/aspera/cli/plugins/sync.rb +15 -14
- data/lib/aspera/cli/transfer_agent.rb +75 -64
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +29 -28
- data/lib/aspera/command_line_builder.rb +50 -43
- data/lib/aspera/cos_node.rb +64 -38
- data/lib/aspera/data_repository.rb +1 -0
- data/lib/aspera/environment.rb +33 -10
- data/lib/aspera/fasp/agent_base.rb +35 -30
- data/lib/aspera/fasp/agent_connect.rb +35 -30
- data/lib/aspera/fasp/agent_direct.rb +68 -60
- data/lib/aspera/fasp/agent_httpgw.rb +71 -64
- data/lib/aspera/fasp/agent_node.rb +24 -23
- data/lib/aspera/fasp/agent_trsdk.rb +19 -20
- data/lib/aspera/fasp/error.rb +2 -1
- data/lib/aspera/fasp/error_info.rb +79 -68
- data/lib/aspera/fasp/installation.rb +130 -126
- data/lib/aspera/fasp/listener.rb +1 -0
- data/lib/aspera/fasp/parameters.rb +71 -60
- data/lib/aspera/fasp/parameters.yaml +69 -17
- data/lib/aspera/fasp/resume_policy.rb +14 -11
- data/lib/aspera/fasp/transfer_spec.rb +6 -5
- data/lib/aspera/fasp/uri.rb +25 -24
- data/lib/aspera/faspex_gw.rb +83 -72
- data/lib/aspera/hash_ext.rb +23 -13
- data/lib/aspera/id_generator.rb +16 -13
- data/lib/aspera/keychain/encrypted_hash.rb +61 -46
- data/lib/aspera/keychain/macos_security.rb +26 -24
- data/lib/aspera/log.rb +35 -39
- data/lib/aspera/nagios.rb +36 -28
- data/lib/aspera/node.rb +19 -19
- data/lib/aspera/oauth.rb +120 -100
- data/lib/aspera/open_application.rb +25 -22
- data/lib/aspera/persistency_action_once.rb +9 -8
- data/lib/aspera/persistency_folder.rb +13 -9
- data/lib/aspera/preview/file_types.rb +261 -266
- data/lib/aspera/preview/generator.rb +74 -73
- data/lib/aspera/preview/image_error.png +0 -0
- data/lib/aspera/preview/options.rb +7 -6
- data/lib/aspera/preview/utils.rb +30 -33
- data/lib/aspera/preview/video_error.png +0 -0
- data/lib/aspera/proxy_auto_config.rb +27 -23
- data/lib/aspera/rest.rb +73 -74
- data/lib/aspera/rest_call_error.rb +1 -0
- data/lib/aspera/rest_error_analyzer.rb +23 -19
- data/lib/aspera/rest_errors_aspera.rb +43 -40
- data/lib/aspera/secret_hider.rb +74 -0
- data/lib/aspera/ssh.rb +13 -10
- data/lib/aspera/sync.rb +49 -47
- data/lib/aspera/temp_file_manager.rb +7 -5
- data/lib/aspera/timer_limiter.rb +9 -8
- data/lib/aspera/uri_reader.rb +17 -18
- data/lib/aspera/web_auth.rb +17 -15
- data.tar.gz.sig +5 -0
- metadata +119 -35
- metadata.gz.sig +0 -0
- data/bin/dascli +0 -13
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'aspera/fasp/agent_base'
|
3
4
|
require 'aspera/fasp/transfer_spec'
|
4
5
|
require 'aspera/log'
|
@@ -15,9 +16,9 @@ module Aspera
|
|
15
16
|
# start a transfer using Aspera HTTP Gateway, using web socket session
|
16
17
|
class AgentHttpgw < AgentBase
|
17
18
|
# message returned by HTTP GW in case of success
|
18
|
-
OK_MESSAGE='end upload'
|
19
|
+
OK_MESSAGE = 'end upload'
|
19
20
|
# refresh rate for progress
|
20
|
-
UPLOAD_REFRESH_SEC=0.5
|
21
|
+
UPLOAD_REFRESH_SEC = 0.5
|
21
22
|
private_constant :OK_MESSAGE,:UPLOAD_REFRESH_SEC
|
22
23
|
# send message on http gw web socket
|
23
24
|
def ws_send(ws,type,data)
|
@@ -26,9 +27,9 @@ module Aspera
|
|
26
27
|
|
27
28
|
def upload(transfer_spec)
|
28
29
|
# total size of all files
|
29
|
-
total_size=0
|
30
|
+
total_size = 0
|
30
31
|
# we need to keep track of actual file path because transfer spec is modified to be sent in web socket
|
31
|
-
source_paths=[]
|
32
|
+
source_paths = []
|
32
33
|
# get source root or nil
|
33
34
|
source_root = transfer_spec.has_key?('source_root') && !transfer_spec['source_root'].empty? ? transfer_spec['source_root'] : nil
|
34
35
|
# source root is ignored by GW, used only here
|
@@ -37,41 +38,46 @@ module Aspera
|
|
37
38
|
# modify transfer spec to be suitable for GW
|
38
39
|
transfer_spec['paths'].each do |item|
|
39
40
|
# save actual file location to be able read contents later
|
40
|
-
full_src_filepath=item['source']
|
41
|
+
full_src_filepath = item['source']
|
41
42
|
# add source root if needed
|
42
|
-
full_src_filepath=File.join(source_root,full_src_filepath) unless source_root.nil?
|
43
|
+
full_src_filepath = File.join(source_root,full_src_filepath) unless source_root.nil?
|
43
44
|
# GW expects a simple file name in 'source' but if user wants to change the name, we take it
|
44
|
-
item['source']=File.basename(item['destination'].nil? ? item['source'] : item['destination'])
|
45
|
-
item['file_size']=File.size(full_src_filepath)
|
46
|
-
total_size+=item['file_size']
|
45
|
+
item['source'] = File.basename(item['destination'].nil? ? item['source'] : item['destination'])
|
46
|
+
item['file_size'] = File.size(full_src_filepath)
|
47
|
+
total_size += item['file_size']
|
47
48
|
# save so that we can actually read the file later
|
48
49
|
source_paths.push(full_src_filepath)
|
49
50
|
end
|
50
51
|
|
51
|
-
session_id=SecureRandom.uuid
|
52
|
-
ws
|
52
|
+
session_id = SecureRandom.uuid
|
53
|
+
ws = ::WebSocket::Client::Simple::Client.new
|
53
54
|
# error message if any in callback
|
54
|
-
error=nil
|
55
|
+
error = nil
|
55
56
|
# number of files totally sent
|
56
|
-
received=0
|
57
|
+
received = 0
|
57
58
|
# setup callbacks on websocket
|
58
|
-
ws.on
|
59
|
+
ws.on(:message) do |msg|
|
59
60
|
Log.log.info("ws: message: #{msg.data}")
|
60
|
-
message=msg.data
|
61
|
+
message = msg.data
|
61
62
|
if message.eql?(OK_MESSAGE)
|
62
|
-
received+=1
|
63
|
+
received += 1
|
63
64
|
else
|
64
65
|
message.chomp!
|
65
|
-
error=
|
66
|
+
error =
|
67
|
+
if message.start_with?('"') && message.end_with?('"')
|
68
|
+
JSON.parse(Base64.strict_decode64(message.chomp[1..-2]))['message']
|
69
|
+
else
|
70
|
+
"expecting quotes in [#{message}]"
|
71
|
+
end
|
66
72
|
end
|
67
73
|
end
|
68
|
-
ws.on
|
69
|
-
error=e
|
74
|
+
ws.on(:error) do |e|
|
75
|
+
error = e
|
70
76
|
end
|
71
|
-
ws.on
|
77
|
+
ws.on(:open) do
|
72
78
|
Log.log.info('ws: open')
|
73
79
|
end
|
74
|
-
ws.on
|
80
|
+
ws.on(:close) do
|
75
81
|
Log.log.info('ws: close')
|
76
82
|
end
|
77
83
|
# open web socket to end point
|
@@ -87,76 +93,77 @@ module Aspera
|
|
87
93
|
Log.dump(:ws_spec,transfer_spec)
|
88
94
|
ws_send(ws,:transfer_spec,transfer_spec)
|
89
95
|
# current file index
|
90
|
-
file_index=0
|
96
|
+
file_index = 0
|
91
97
|
# aggregate size sent
|
92
|
-
sent_bytes=0
|
98
|
+
sent_bytes = 0
|
93
99
|
# last progress event
|
94
|
-
lastevent=nil
|
100
|
+
lastevent = nil
|
95
101
|
transfer_spec['paths'].each do |item|
|
96
102
|
# TODO: get mime type?
|
97
|
-
file_mime_type=''
|
98
|
-
file_size=item['file_size']
|
99
|
-
file_name=File.basename(item[item['destination'].nil? ? 'source' : 'destination'])
|
103
|
+
file_mime_type = ''
|
104
|
+
file_size = item['file_size']
|
105
|
+
file_name = File.basename(item[item['destination'].nil? ? 'source' : 'destination'])
|
100
106
|
# compute total number of slices
|
101
|
-
numslices=1+((file_size-1)
|
107
|
+
numslices = 1 + ((file_size - 1) / @upload_chunksize)
|
102
108
|
File.open(source_paths[file_index]) do |file|
|
103
109
|
# current slice index
|
104
|
-
slicenum=0
|
110
|
+
slicenum = 0
|
105
111
|
while !file.eof?
|
106
|
-
data=file.read(@upload_chunksize)
|
107
|
-
slice_data={
|
108
|
-
name:
|
109
|
-
type:
|
110
|
-
size:
|
111
|
-
data:
|
112
|
-
slice:
|
112
|
+
data = file.read(@upload_chunksize)
|
113
|
+
slice_data = {
|
114
|
+
name: file_name,
|
115
|
+
type: file_mime_type,
|
116
|
+
size: file_size,
|
117
|
+
data: Base64.strict_encode64(data),
|
118
|
+
slice: slicenum,
|
113
119
|
total_slices: numslices,
|
114
|
-
fileIndex:
|
120
|
+
fileIndex: file_index
|
115
121
|
}
|
116
122
|
# log without data
|
117
|
-
Log.dump(:slide_data,slice_data.keys.each_with_object({}){|i,m|m[i]=i.eql?(:data)?'base64 data':slice_data[i];}) if slicenum.eql?(0)
|
123
|
+
Log.dump(:slide_data,slice_data.keys.each_with_object({}){|i,m|m[i] = i.eql?(:data) ? 'base64 data' : slice_data[i];}) if slicenum.eql?(0)
|
118
124
|
ws_send(ws,:slice_upload, slice_data)
|
119
|
-
sent_bytes+=data.length
|
120
|
-
currenttime=Time.now
|
121
|
-
if lastevent.nil? || ((currenttime-lastevent)>UPLOAD_REFRESH_SEC)
|
125
|
+
sent_bytes += data.length
|
126
|
+
currenttime = Time.now
|
127
|
+
if lastevent.nil? || ((currenttime - lastevent) > UPLOAD_REFRESH_SEC)
|
122
128
|
notify_progress(session_id,sent_bytes)
|
123
|
-
lastevent=currenttime
|
129
|
+
lastevent = currenttime
|
124
130
|
end
|
125
|
-
slicenum+=1
|
131
|
+
slicenum += 1
|
126
132
|
raise error unless error.nil?
|
127
133
|
end
|
128
134
|
end
|
129
|
-
file_index+=1
|
135
|
+
file_index += 1
|
130
136
|
end
|
131
137
|
ws.close
|
132
138
|
notify_end(session_id)
|
133
139
|
end
|
134
140
|
|
135
141
|
def download(transfer_spec)
|
136
|
-
transfer_spec['zip_required']||=false
|
137
|
-
transfer_spec['source_root']||='/'
|
142
|
+
transfer_spec['zip_required'] ||= false
|
143
|
+
transfer_spec['source_root'] ||= '/'
|
138
144
|
# is normally provided by application, like package name
|
139
145
|
if !transfer_spec.has_key?('download_name')
|
140
146
|
# by default it is the name of first file
|
141
|
-
dname=File.basename(transfer_spec['paths'].first['source'])
|
147
|
+
dname = File.basename(transfer_spec['paths'].first['source'])
|
142
148
|
# we remove extension
|
143
|
-
dname=dname.gsub(/\.@gw_api.*$/,'')
|
149
|
+
dname = dname.gsub(/\.@gw_api.*$/,'')
|
144
150
|
# ands add indication of number of files if there is more than one
|
145
151
|
if transfer_spec['paths'].length > 1
|
146
|
-
dname+=" #{transfer_spec['paths'].length} Files"
|
152
|
+
dname += " #{transfer_spec['paths'].length} Files"
|
147
153
|
end
|
148
|
-
transfer_spec['download_name']=dname
|
149
|
-
end
|
150
|
-
creation=@gw_api.create('download',{'transfer_spec'=>transfer_spec})[:data]
|
151
|
-
transfer_uuid=creation['url'].split('/').last
|
152
|
-
file_dest=if transfer_spec['zip_required'] || transfer_spec['paths'].length > 1
|
153
|
-
# it is a zip file if zip is required or there is more than 1 file
|
154
|
-
transfer_spec['download_name']+'.zip'
|
155
|
-
else
|
156
|
-
# it is a plain file if we don't require zip and there is only one file
|
157
|
-
File.basename(transfer_spec['paths'].first['source'])
|
154
|
+
transfer_spec['download_name'] = dname
|
158
155
|
end
|
159
|
-
|
156
|
+
creation = @gw_api.create('download',{'transfer_spec' => transfer_spec})[:data]
|
157
|
+
transfer_uuid = creation['url'].split('/').last
|
158
|
+
file_dest =
|
159
|
+
if transfer_spec['zip_required'] || transfer_spec['paths'].length > 1
|
160
|
+
# it is a zip file if zip is required or there is more than 1 file
|
161
|
+
transfer_spec['download_name'] + '.zip'
|
162
|
+
else
|
163
|
+
# it is a plain file if we don't require zip and there is only one file
|
164
|
+
File.basename(transfer_spec['paths'].first['source'])
|
165
|
+
end
|
166
|
+
file_dest = File.join(transfer_spec['destination_root'],file_dest)
|
160
167
|
@gw_api.call({operation: 'GET',subpath: "download/#{transfer_uuid}",save_to_file: file_dest})
|
161
168
|
end
|
162
169
|
|
@@ -169,7 +176,7 @@ module Aspera
|
|
169
176
|
raise 'paths: must be Array' unless transfer_spec['paths'].is_a?(Array)
|
170
177
|
raise 'only token based transfer is supported in GW' unless transfer_spec['token'].is_a?(String)
|
171
178
|
Log.dump(:user_spec,transfer_spec)
|
172
|
-
transfer_spec['authentication']||='token'
|
179
|
+
transfer_spec['authentication'] ||= 'token'
|
173
180
|
case transfer_spec['direction']
|
174
181
|
when Fasp::TransferSpec::DIRECTION_SEND
|
175
182
|
upload(transfer_spec)
|
@@ -195,13 +202,13 @@ module Aspera
|
|
195
202
|
|
196
203
|
def initialize(params)
|
197
204
|
raise 'params must be Hash' unless params.is_a?(Hash)
|
198
|
-
params=params.symbolize_keys
|
205
|
+
params = params.symbolize_keys
|
199
206
|
raise 'must have only one param: url' unless params.keys.eql?([:url])
|
200
207
|
super()
|
201
|
-
@gw_api=Rest.new({base_url: params[:url]})
|
208
|
+
@gw_api = Rest.new({base_url: params[:url]})
|
202
209
|
api_info = @gw_api.read('info')[:data]
|
203
210
|
Log.log.info(api_info.to_s)
|
204
|
-
@upload_chunksize=128_000 # TODO: configurable ?
|
211
|
+
@upload_chunksize = 128_000 # TODO: configurable ?
|
205
212
|
end
|
206
213
|
end # AgentHttpgw
|
207
214
|
end
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'aspera/fasp/agent_base'
|
3
4
|
require 'aspera/fasp/transfer_spec'
|
4
5
|
require 'aspera/log'
|
@@ -13,27 +14,27 @@ module Aspera
|
|
13
14
|
attr_writer :options
|
14
15
|
def initialize(options)
|
15
16
|
raise 'node specification must be Hash' unless options.is_a?(Hash)
|
16
|
-
[
|
17
|
+
%i[url username password].each { |k| raise "missing parameter [#{k}] in node specification: #{options}" unless options.has_key?(k) }
|
17
18
|
super()
|
18
19
|
# root id is required for access key
|
19
|
-
@root_id=options[:root_id]
|
20
|
-
rest_params={ base_url: options[:url]}
|
21
|
-
if options[:password]
|
22
|
-
rest_params[:headers]={
|
23
|
-
'X-Aspera-AccessKey'=>options[:username],
|
24
|
-
'Authorization'
|
20
|
+
@root_id = options[:root_id]
|
21
|
+
rest_params = { base_url: options[:url]}
|
22
|
+
if /^Bearer /.match?(options[:password])
|
23
|
+
rest_params[:headers] = {
|
24
|
+
'X-Aspera-AccessKey' => options[:username],
|
25
|
+
'Authorization' => options[:password]
|
25
26
|
}
|
26
27
|
raise 'root_id is required for access key' if @root_id.nil?
|
27
28
|
else
|
28
|
-
rest_params[:auth]={
|
29
|
+
rest_params[:auth] = {
|
29
30
|
type: :basic,
|
30
31
|
username: options[:username],
|
31
32
|
password: options[:password]
|
32
33
|
}
|
33
34
|
end
|
34
|
-
@node_api=Rest.new(rest_params)
|
35
|
+
@node_api = Rest.new(rest_params)
|
35
36
|
# TODO: currently only supports one transfer. This is bad shortcut. but ok for CLI.
|
36
|
-
@transfer_id=nil
|
37
|
+
@transfer_id = nil
|
37
38
|
end
|
38
39
|
|
39
40
|
# used internally to ensure node api is set before using.
|
@@ -49,7 +50,7 @@ module Aspera
|
|
49
50
|
if !@node_api.nil? && !new_value.nil?
|
50
51
|
Log.log.warn('overriding existing node api value')
|
51
52
|
end
|
52
|
-
@node_api=new_value
|
53
|
+
@node_api = new_value
|
53
54
|
end
|
54
55
|
|
55
56
|
# generic method
|
@@ -57,8 +58,8 @@ module Aspera
|
|
57
58
|
# add root id if access key
|
58
59
|
if !@root_id.nil?
|
59
60
|
case transfer_spec['direction']
|
60
|
-
when Fasp::TransferSpec::DIRECTION_SEND then transfer_spec['source_root_id']
|
61
|
-
when Fasp::TransferSpec::DIRECTION_RECEIVE then transfer_spec['destination_root_id']
|
61
|
+
when Fasp::TransferSpec::DIRECTION_SEND then transfer_spec['source_root_id'] = @root_id
|
62
|
+
when Fasp::TransferSpec::DIRECTION_RECEIVE then transfer_spec['destination_root_id'] = @root_id
|
62
63
|
else raise "unexpected direction in ts: #{transfer_spec['direction']}"
|
63
64
|
end
|
64
65
|
end
|
@@ -69,31 +70,31 @@ module Aspera
|
|
69
70
|
Log.log.warn('Both ssh_private_key and EX_ssh_key_paths are present, using ssh_private_key')
|
70
71
|
else
|
71
72
|
Log.log.warn('EX_ssh_key_paths has multiple keys, using first one only') unless transfer_spec['EX_ssh_key_paths'].length.eql?(1)
|
72
|
-
transfer_spec['ssh_private_key']=File.read(transfer_spec['EX_ssh_key_paths'].first)
|
73
|
+
transfer_spec['ssh_private_key'] = File.read(transfer_spec['EX_ssh_key_paths'].first)
|
73
74
|
transfer_spec.delete('EX_ssh_key_paths')
|
74
75
|
end
|
75
76
|
end
|
76
77
|
if transfer_spec['tags'].is_a?(Hash) && transfer_spec['tags']['aspera'].is_a?(Hash)
|
77
|
-
transfer_spec['tags']['aspera']['xfer_retry']||=150
|
78
|
+
transfer_spec['tags']['aspera']['xfer_retry'] ||= 150
|
78
79
|
end
|
79
80
|
# optimisation in case of sending to the same node
|
80
81
|
if transfer_spec['remote_host'].eql?(URI.parse(node_api_.params[:base_url]).host)
|
81
|
-
transfer_spec['remote_host']='localhost'
|
82
|
+
transfer_spec['remote_host'] = 'localhost'
|
82
83
|
end
|
83
|
-
resp=node_api_.create('ops/transfers',transfer_spec)[:data]
|
84
|
-
@transfer_id=resp['id']
|
84
|
+
resp = node_api_.create('ops/transfers',transfer_spec)[:data]
|
85
|
+
@transfer_id = resp['id']
|
85
86
|
Log.log.debug("tr_id=#{@transfer_id}")
|
86
87
|
return @transfer_id
|
87
88
|
end
|
88
89
|
|
89
90
|
# generic method
|
90
91
|
def wait_for_transfers_completion
|
91
|
-
started=false
|
92
|
-
spinner=nil
|
92
|
+
started = false
|
93
|
+
spinner = nil
|
93
94
|
# lets emulate management events to display progress bar
|
94
95
|
loop do
|
95
96
|
# status is empty sometimes with status 200...
|
96
|
-
trdata=node_api_.read("ops/transfers/#{@transfer_id}")[:data] || {'status'=>'unknown'} rescue {'status'=>'waiting(read error)'}
|
97
|
+
trdata = node_api_.read("ops/transfers/#{@transfer_id}")[:data] || {'status' => 'unknown'} rescue {'status' => 'waiting(read error)'}
|
97
98
|
case trdata['status']
|
98
99
|
when 'completed'
|
99
100
|
notify_end(@transfer_id)
|
@@ -111,7 +112,7 @@ module Aspera
|
|
111
112
|
if !started && trdata['precalc'].is_a?(Hash) &&
|
112
113
|
trdata['precalc']['status'].eql?('ready')
|
113
114
|
notify_begin(@transfer_id,trdata['precalc']['bytes_expected'])
|
114
|
-
started=true
|
115
|
+
started = true
|
115
116
|
else
|
116
117
|
notify_progress(@transfer_id,trdata['bytes_transferred'])
|
117
118
|
end
|
@@ -119,7 +120,7 @@ module Aspera
|
|
119
120
|
Log.log.warn("trdata -> #{trdata}")
|
120
121
|
raise Fasp::Error, "#{trdata['status']}: #{trdata['error_desc']}"
|
121
122
|
end
|
122
|
-
sleep
|
123
|
+
sleep(1)
|
123
124
|
end
|
124
125
|
#TODO get status of sessions
|
125
126
|
return []
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'aspera/fasp/agent_base'
|
3
4
|
require 'aspera/fasp/installation'
|
4
5
|
require 'json'
|
@@ -9,19 +10,17 @@ module Aspera
|
|
9
10
|
DEFAULT_OPTIONS = {
|
10
11
|
address: '127.0.0.1',
|
11
12
|
port: 55_002
|
12
|
-
}
|
13
|
+
}.freeze
|
13
14
|
private_constant :DEFAULT_OPTIONS
|
14
15
|
|
15
16
|
# options come from transfer_info
|
16
17
|
def initialize(user_opts)
|
17
18
|
raise "expecting Hash (or nil), but have #{user_opts.class}" unless user_opts.nil? || user_opts.is_a?(Hash)
|
18
19
|
# set default options and override if specified
|
19
|
-
options=DEFAULT_OPTIONS.
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
options[k]=v
|
24
|
-
end
|
20
|
+
options = DEFAULT_OPTIONS.dup
|
21
|
+
user_opts&.each do |k,v|
|
22
|
+
raise "Unknown local agent parameter: #{k}, expect one of #{DEFAULT_OPTIONS.keys.map(&:to_s).join(',')}" unless DEFAULT_OPTIONS.has_key?(k)
|
23
|
+
options[k] = v
|
25
24
|
end
|
26
25
|
Log.log.debug("options= #{options}")
|
27
26
|
super()
|
@@ -35,20 +34,20 @@ module Aspera
|
|
35
34
|
rescue GRPC::Unavailable
|
36
35
|
Log.log.warn('no daemon present, starting daemon...')
|
37
36
|
# location of daemon binary
|
38
|
-
bin_folder=File.realpath(File.join(Installation.instance.sdk_ruby_folder,'..'))
|
37
|
+
bin_folder = File.realpath(File.join(Installation.instance.sdk_ruby_folder,'..'))
|
39
38
|
# config file and logs are created in same folder
|
40
39
|
conf_file = File.join(bin_folder,'sdk.conf')
|
41
40
|
log_base = File.join(bin_folder,'transferd')
|
42
41
|
# create a config file for daemon
|
43
42
|
config = {
|
44
|
-
address:
|
45
|
-
port:
|
43
|
+
address: options[:address],
|
44
|
+
port: options[:port],
|
46
45
|
fasp_runtime: {
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
use_embedded: false,
|
47
|
+
user_defined: {
|
48
|
+
bin: bin_folder,
|
49
|
+
etc: bin_folder
|
50
|
+
}
|
52
51
|
}
|
53
52
|
}
|
54
53
|
File.write(conf_file,config.to_json)
|
@@ -62,9 +61,9 @@ module Aspera
|
|
62
61
|
def start_transfer(transfer_spec,_options=nil)
|
63
62
|
# create a transfer request
|
64
63
|
transfer_request = Transfersdk::TransferRequest.new(
|
65
|
-
|
66
|
-
|
67
|
-
|
64
|
+
transferType: Transfersdk::TransferType::FILE_REGULAR, # transfer type (file/stream)
|
65
|
+
config: Transfersdk::TransferConfig.new, # transfer configuration
|
66
|
+
transferSpec: transfer_spec.to_json) # transfer definition
|
68
67
|
# send start transfer request to the transfer manager daemon
|
69
68
|
start_transfer_response = @transfer_client.start_transfer(transfer_request)
|
70
69
|
Log.log.debug("start transfer response #{start_transfer_response}")
|
@@ -73,7 +72,7 @@ module Aspera
|
|
73
72
|
end
|
74
73
|
|
75
74
|
def wait_for_transfers_completion
|
76
|
-
started=false
|
75
|
+
started = false
|
77
76
|
# monitor transfer status
|
78
77
|
@transfer_client.monitor_transfers(Transfersdk::RegistrationRequest.new(transferId: [@transfer_id])) do |response|
|
79
78
|
Log.dump(:response, response.to_h)
|
@@ -82,7 +81,7 @@ module Aspera
|
|
82
81
|
when :RUNNING
|
83
82
|
if !started && !response.sessionInfo.preTransferBytes.eql?(0)
|
84
83
|
notify_begin(@transfer_id,response.sessionInfo.preTransferBytes)
|
85
|
-
started=true
|
84
|
+
started = true
|
86
85
|
elsif started
|
87
86
|
notify_progress(@transfer_id,response.transferInfo.bytesTransferred)
|
88
87
|
end
|
data/lib/aspera/fasp/error.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
require 'aspera/fasp/error_info'
|
3
4
|
|
4
5
|
module Aspera
|
@@ -12,7 +13,7 @@ module Aspera
|
|
12
13
|
end
|
13
14
|
|
14
15
|
def info
|
15
|
-
r=Fasp::ERROR_INFO[@err_code] || {r: false, c: 'UNKNOWN', m: 'unknown', a: 'unknown'}
|
16
|
+
r = Fasp::ERROR_INFO[@err_code] || {r: false, c: 'UNKNOWN', m: 'unknown', a: 'unknown'}
|
16
17
|
return r.merge({i: @err_code})
|
17
18
|
end
|
18
19
|
|