aspera-cli 4.12.0 → 4.14.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/CHANGELOG.md +45 -5
- data/CONTRIBUTING.md +113 -22
- data/README.md +1289 -754
- data/bin/ascli +3 -3
- data/examples/dascli +1 -1
- data/examples/rubyc +24 -0
- data/lib/aspera/aoc.rb +63 -74
- data/lib/aspera/ascmd.rb +5 -3
- data/lib/aspera/cli/basic_auth_plugin.rb +6 -6
- data/lib/aspera/cli/extended_value.rb +24 -37
- data/lib/aspera/cli/formatter.rb +23 -25
- data/lib/aspera/cli/info.rb +2 -4
- data/lib/aspera/cli/main.rb +27 -27
- data/lib/aspera/cli/manager.rb +143 -120
- data/lib/aspera/cli/plugin.rb +88 -43
- data/lib/aspera/cli/plugins/alee.rb +2 -2
- data/lib/aspera/cli/plugins/aoc.rb +235 -104
- data/lib/aspera/cli/plugins/ats.rb +16 -18
- data/lib/aspera/cli/plugins/bss.rb +3 -3
- data/lib/aspera/cli/plugins/config.rb +190 -373
- data/lib/aspera/cli/plugins/console.rb +4 -6
- data/lib/aspera/cli/plugins/cos.rb +12 -13
- data/lib/aspera/cli/plugins/faspex.rb +21 -21
- data/lib/aspera/cli/plugins/faspex5.rb +399 -150
- data/lib/aspera/cli/plugins/node.rb +260 -174
- data/lib/aspera/cli/plugins/orchestrator.rb +15 -18
- data/lib/aspera/cli/plugins/preview.rb +40 -62
- data/lib/aspera/cli/plugins/server.rb +33 -16
- data/lib/aspera/cli/plugins/shares.rb +24 -33
- data/lib/aspera/cli/plugins/sync.rb +6 -6
- data/lib/aspera/cli/transfer_agent.rb +47 -30
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +9 -7
- data/lib/aspera/command_line_builder.rb +2 -1
- data/lib/aspera/cos_node.rb +1 -1
- data/lib/aspera/data/6 +0 -0
- data/lib/aspera/environment.rb +7 -3
- data/lib/aspera/fasp/agent_connect.rb +6 -1
- data/lib/aspera/fasp/agent_direct.rb +17 -17
- data/lib/aspera/fasp/agent_httpgw.rb +138 -60
- data/lib/aspera/fasp/agent_node.rb +14 -4
- data/lib/aspera/fasp/agent_trsdk.rb +2 -0
- data/lib/aspera/fasp/error_info.rb +2 -0
- data/lib/aspera/fasp/installation.rb +19 -19
- data/lib/aspera/fasp/parameters.rb +29 -20
- data/lib/aspera/fasp/parameters.yaml +5 -2
- data/lib/aspera/fasp/resume_policy.rb +3 -3
- data/lib/aspera/fasp/transfer_spec.rb +8 -5
- data/lib/aspera/fasp/uri.rb +23 -21
- data/lib/aspera/faspex_gw.rb +1 -0
- data/lib/aspera/faspex_postproc.rb +3 -3
- data/lib/aspera/hash_ext.rb +12 -2
- data/lib/aspera/keychain/macos_security.rb +13 -13
- data/lib/aspera/log.rb +1 -0
- data/lib/aspera/node.rb +73 -84
- data/lib/aspera/oauth.rb +4 -3
- data/lib/aspera/persistency_action_once.rb +1 -1
- data/lib/aspera/preview/file_types.rb +8 -6
- data/lib/aspera/preview/generator.rb +23 -11
- data/lib/aspera/preview/options.rb +3 -2
- data/lib/aspera/preview/terminal.rb +80 -0
- data/lib/aspera/preview/utils.rb +11 -11
- data/lib/aspera/proxy_auto_config.js +2 -2
- data/lib/aspera/rest.rb +42 -4
- data/lib/aspera/rest_call_error.rb +3 -1
- data/lib/aspera/secret_hider.rb +10 -5
- data/lib/aspera/ssh.rb +1 -1
- data/lib/aspera/sync.rb +41 -33
- data/lib/aspera/web_server_simple.rb +22 -18
- data.tar.gz.sig +0 -0
- metadata +40 -48
- metadata.gz.sig +0 -0
- data/docs/test_env.conf +0 -179
- data/examples/aoc.rb +0 -30
- data/examples/faspex4.rb +0 -94
- data/examples/node.rb +0 -96
- data/examples/server.rb +0 -93
- data/lib/aspera/data/7 +0 -0
@@ -48,38 +48,55 @@ module Aspera
|
|
48
48
|
@config = config
|
49
49
|
# command line can override transfer spec
|
50
50
|
@transfer_spec_cmdline = {'create_dir' => true}
|
51
|
+
@transfer_info = {}
|
51
52
|
# the currently selected transfer agent
|
52
53
|
@agent = nil
|
53
54
|
@progress_listener = Listener::ProgressMulti.new
|
54
55
|
# source/destination pair, like "paths" of transfer spec
|
55
56
|
@transfer_paths = nil
|
56
|
-
@opt_mgr.
|
57
|
-
@opt_mgr.
|
58
|
-
@opt_mgr.
|
59
|
-
@opt_mgr.
|
60
|
-
@opt_mgr.
|
61
|
-
@opt_mgr.
|
62
|
-
@opt_mgr.
|
63
|
-
@opt_mgr.add_opt_list(:progress, %i[none native multi], 'Type of progress bar')
|
64
|
-
@opt_mgr.set_option(:transfer, :direct)
|
65
|
-
@opt_mgr.set_option(:src_type, :list)
|
66
|
-
@opt_mgr.set_option(:progress, :native) # use native ascp progress bar as it is more reliable
|
57
|
+
@opt_mgr.declare(:ts, 'Override transfer spec values', types: Hash, handler: {o: self, m: :option_transfer_spec})
|
58
|
+
@opt_mgr.declare(:to_folder, 'Destination folder for transferred files')
|
59
|
+
@opt_mgr.declare(:sources, "How list of transferred files is provided (#{FILE_LIST_OPTIONS.join(',')})")
|
60
|
+
@opt_mgr.declare(:src_type, 'Type of file list', values: %i[list pair], default: :list)
|
61
|
+
@opt_mgr.declare(:transfer, 'Type of transfer agent', values: TRANSFER_AGENTS, default: :direct)
|
62
|
+
@opt_mgr.declare(:transfer_info, 'Parameters for transfer agent', types: Hash, handler: {o: self, m: :option_transfer_info})
|
63
|
+
@opt_mgr.declare(:progress, 'Type of progress bar', values: %i[none native multi], default: :native)
|
67
64
|
@opt_mgr.parse_options!
|
68
65
|
end
|
69
66
|
|
70
67
|
def option_transfer_spec; @transfer_spec_cmdline; end
|
71
68
|
|
72
69
|
# multiple option are merged
|
73
|
-
def option_transfer_spec=(value)
|
70
|
+
def option_transfer_spec=(value)
|
71
|
+
raise 'option ts shall be a Hash' unless value.is_a?(Hash)
|
72
|
+
@transfer_spec_cmdline.deep_merge!(value)
|
73
|
+
end
|
74
74
|
|
75
|
+
# add other transfer spec parameters
|
75
76
|
def option_transfer_spec_deep_merge(ts); @transfer_spec_cmdline.deep_merge!(ts); end
|
76
77
|
|
78
|
+
# @return [Hash] transfer spec with updated values from command line, including removed values
|
79
|
+
def updated_ts(transfer_spec={})
|
80
|
+
transfer_spec.deep_merge!(@transfer_spec_cmdline)
|
81
|
+
# recursively remove values that are nil (user wants to delete)
|
82
|
+
transfer_spec.deep_do { |hash, key, value, _unused| hash.delete(key) if value.nil?}
|
83
|
+
return transfer_spec
|
84
|
+
end
|
85
|
+
|
86
|
+
def option_transfer_info; @transfer_info; end
|
87
|
+
|
88
|
+
# multiple option are merged
|
89
|
+
def option_transfer_info=(value)
|
90
|
+
raise 'option transfer_info shall be a Hash' unless value.is_a?(Hash)
|
91
|
+
@transfer_info.deep_merge!(value)
|
92
|
+
end
|
93
|
+
|
77
94
|
def agent_instance=(instance)
|
78
95
|
@agent = instance
|
79
96
|
@agent.add_listener(Listener::Logger.new)
|
80
97
|
# use local progress bar if asked so, or if native and non local ascp (because only local ascp has native progress bar)
|
81
|
-
if @opt_mgr.get_option(:progress,
|
82
|
-
(@opt_mgr.get_option(:progress,
|
98
|
+
if @opt_mgr.get_option(:progress, mandatory: true).eql?(:multi) ||
|
99
|
+
(@opt_mgr.get_option(:progress, mandatory: true).eql?(:native) && !instance.class.to_s.eql?('Aspera::Fasp::AgentDirect'))
|
83
100
|
@agent.add_listener(@progress_listener)
|
84
101
|
end
|
85
102
|
end
|
@@ -87,24 +104,24 @@ module Aspera
|
|
87
104
|
# analyze options and create new agent if not already created or set
|
88
105
|
def set_agent_by_options
|
89
106
|
return nil unless @agent.nil?
|
90
|
-
agent_type = @opt_mgr.get_option(:transfer,
|
107
|
+
agent_type = @opt_mgr.get_option(:transfer, mandatory: true)
|
91
108
|
# agent plugin is loaded on demand to avoid loading unnecessary dependencies
|
92
109
|
require "aspera/fasp/agent_#{agent_type}"
|
93
110
|
agent_options = @opt_mgr.get_option(:transfer_info)
|
94
111
|
raise CliBadArgument, "the transfer agent configuration shall be Hash, not #{agent_options.class} (#{agent_options}), "\
|
95
|
-
'use
|
96
|
-
# special case
|
97
|
-
if agent_type.eql?(:node) && agent_options.
|
112
|
+
'e.g. use @json:<json>' unless agent_options.is_a?(Hash)
|
113
|
+
# special case: use default node
|
114
|
+
if agent_type.eql?(:node) && agent_options.empty?
|
98
115
|
param_set_name = @config.get_plugin_default_config_name(:node)
|
99
|
-
raise CliBadArgument, "No default node configured
|
116
|
+
raise CliBadArgument, "No default node configured. Please specify #{Manager.option_name_to_line(:transfer_info)}" if param_set_name.nil?
|
100
117
|
agent_options = @config.preset_by_name(param_set_name)
|
101
118
|
end
|
102
|
-
# special case
|
103
|
-
if agent_type.eql?(:direct) && @opt_mgr.get_option(:progress,
|
104
|
-
agent_options = {} if agent_options.nil?
|
119
|
+
# special case: native progress bar
|
120
|
+
if agent_type.eql?(:direct) && @opt_mgr.get_option(:progress, mandatory: true).eql?(:native)
|
105
121
|
agent_options[:quiet] = false
|
106
122
|
end
|
107
|
-
|
123
|
+
# normalize after getting from user or default node
|
124
|
+
agent_options = agent_options.symbolize_keys
|
108
125
|
# get agent instance
|
109
126
|
new_agent = Kernel.const_get("Aspera::Fasp::Agent#{agent_type.capitalize}").new(agent_options)
|
110
127
|
self.agent_instance = new_agent
|
@@ -129,6 +146,7 @@ module Aspera
|
|
129
146
|
return dest_folder
|
130
147
|
end
|
131
148
|
|
149
|
+
# @return [Array] list of source files
|
132
150
|
def source_list
|
133
151
|
return ts_source_paths.map do |i|
|
134
152
|
i['source']
|
@@ -156,7 +174,7 @@ module Aspera
|
|
156
174
|
when FILE_LIST_FROM_TRANSFER_SPEC
|
157
175
|
Log.log.debug('assume list provided in transfer spec')
|
158
176
|
special_case_direct_with_list =
|
159
|
-
@opt_mgr.get_option(:transfer,
|
177
|
+
@opt_mgr.get_option(:transfer, mandatory: true).eql?(:direct) &&
|
160
178
|
Fasp::Parameters.ts_has_ascp_file_list(@transfer_spec_cmdline, @opt_mgr.get_option(:transfer_info))
|
161
179
|
raise CliBadArgument, 'transfer spec on command line must have sources' if @transfer_paths.nil? && !special_case_direct_with_list
|
162
180
|
# here we assume check of sources is made in transfer agent
|
@@ -171,7 +189,7 @@ module Aspera
|
|
171
189
|
if !@transfer_paths.nil?
|
172
190
|
Log.log.warn('--sources overrides paths from --ts')
|
173
191
|
end
|
174
|
-
case @opt_mgr.get_option(:src_type,
|
192
|
+
case @opt_mgr.get_option(:src_type, mandatory: true)
|
175
193
|
when :list
|
176
194
|
# when providing a list, just specify source
|
177
195
|
@transfer_paths = file_list.map{|i|{'source' => i}}
|
@@ -196,7 +214,7 @@ module Aspera
|
|
196
214
|
# init default if required in any case
|
197
215
|
@transfer_spec_cmdline['destination_root'] ||= destination_folder(transfer_spec['direction'])
|
198
216
|
when Fasp::TransferSpec::DIRECTION_SEND
|
199
|
-
if transfer_spec.dig('tags',
|
217
|
+
if transfer_spec.dig('tags', Fasp::TransferSpec::TAG_RESERVED, 'node', 'access_key')
|
200
218
|
# gen4
|
201
219
|
@transfer_spec_cmdline.delete('destination_root') if @transfer_spec_cmdline.key?('destination_root_id')
|
202
220
|
elsif transfer_spec.key?('token')
|
@@ -211,14 +229,13 @@ module Aspera
|
|
211
229
|
end
|
212
230
|
# update command line paths, unless destination already has one
|
213
231
|
@transfer_spec_cmdline['paths'] = transfer_spec['paths'] || ts_source_paths
|
214
|
-
|
215
|
-
|
216
|
-
transfer_spec.delete_if { |_key, value| value.nil? }
|
232
|
+
# updated transfer spec with command line
|
233
|
+
updated_ts(transfer_spec)
|
217
234
|
# create transfer agent
|
218
235
|
set_agent_by_options
|
219
236
|
Log.log.debug{"transfer agent is a #{@agent.class}"}
|
220
237
|
@agent.start_transfer(transfer_spec, token_regenerator: rest_token)
|
221
|
-
# list of
|
238
|
+
# list of: :success or "error message string"
|
222
239
|
result = @agent.wait_for_transfers_completion
|
223
240
|
@progress_listener.reset
|
224
241
|
Fasp::AgentBase.validate_status_list(result)
|
data/lib/aspera/cli/version.rb
CHANGED
data/lib/aspera/colors.rb
CHANGED
@@ -1,16 +1,18 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# cspell:words
|
4
|
+
|
3
5
|
# simple vt100 colors
|
4
6
|
class String
|
5
7
|
class << self
|
6
8
|
private
|
7
9
|
|
8
|
-
def
|
10
|
+
def vt_cmd(code); "\e[#{code}m"; end
|
9
11
|
end
|
10
12
|
# see https://en.wikipedia.org/wiki/ANSI_escape_code
|
11
13
|
# symbol is the method name added to String
|
12
14
|
# it adds control chars to set color (and reset at the end).
|
13
|
-
|
15
|
+
VT_STYLES = {
|
14
16
|
bold: 1,
|
15
17
|
italic: 3,
|
16
18
|
underline: 4,
|
@@ -33,17 +35,17 @@ class String
|
|
33
35
|
bg_cyan: 46,
|
34
36
|
bg_gray: 47
|
35
37
|
}.freeze
|
36
|
-
private_constant :
|
37
|
-
# defines methods to String, one per entry in
|
38
|
-
|
38
|
+
private_constant :VT_STYLES
|
39
|
+
# defines methods to String, one per entry in VT_STYLES
|
40
|
+
VT_STYLES.each do |name, code|
|
39
41
|
if $stderr.tty?
|
40
|
-
begin_seq =
|
42
|
+
begin_seq = vt_cmd(code)
|
41
43
|
end_code = 0 # by default reset all
|
42
44
|
if code <= 7 then code + 20
|
43
45
|
elsif code <= 37 then 39
|
44
46
|
elsif code <= 47 then 49
|
45
47
|
end
|
46
|
-
end_seq =
|
48
|
+
end_seq = vt_cmd(end_code)
|
47
49
|
define_method(name){"#{begin_seq}#{self}#{end_seq}"}
|
48
50
|
else
|
49
51
|
define_method(name){self}
|
@@ -9,7 +9,7 @@ module Aspera
|
|
9
9
|
# parameter with one of those tags is a command line option with --
|
10
10
|
CLI_OPTION_TYPE_SWITCH = %i[opt_without_arg opt_with_arg].freeze
|
11
11
|
CLI_OPTION_TYPES = %i[special ignore envvar].concat(CLI_OPTION_TYPE_SWITCH).freeze
|
12
|
-
OPTIONS_KEYS = %i[desc accepted_types default enum agents required cli ts].freeze
|
12
|
+
OPTIONS_KEYS = %i[desc accepted_types default enum agents required cli ts deprecation].freeze
|
13
13
|
CLI_KEYS = %i[type switch convert variable].freeze
|
14
14
|
|
15
15
|
private_constant :CLI_OPTION_TYPE_SWITCH, :OPTIONS_KEYS, :CLI_KEYS
|
@@ -37,6 +37,7 @@ module Aspera
|
|
37
37
|
# by default : optional
|
38
38
|
options[:mandatory] ||= false
|
39
39
|
options[:desc] ||= ''
|
40
|
+
options[:desc] = "DEPRECATED: #{options[:deprecation]}\n#{options[:desc]}" if options.key?(:deprecation)
|
40
41
|
cli = options[:cli]
|
41
42
|
unsupported_cli_keys = cli.keys - CLI_KEYS
|
42
43
|
raise "Unsupported cli keys: #{unsupported_cli_keys}" unless unsupported_cli_keys.empty?
|
data/lib/aspera/cos_node.rb
CHANGED
@@ -65,7 +65,7 @@ module Aspera
|
|
65
65
|
type: :basic,
|
66
66
|
username: ats_info['AccessKey']['Id'],
|
67
67
|
password: ats_info['AccessKey']['Secret']}},
|
68
|
-
add_tspec: {'tags'=>{
|
68
|
+
add_tspec: {'tags'=>{Fasp::TransferSpec::TAG_RESERVED=>{'node'=>{'storage_credentials'=>@storage_credentials}}}})
|
69
69
|
# update storage_credentials AND Rest params
|
70
70
|
generate_token
|
71
71
|
end
|
data/lib/aspera/data/6
CHANGED
Binary file
|
data/lib/aspera/environment.rb
CHANGED
@@ -3,6 +3,8 @@
|
|
3
3
|
require 'aspera/log'
|
4
4
|
require 'rbconfig'
|
5
5
|
|
6
|
+
# cspell:words MEBI mswin bccwin
|
7
|
+
|
6
8
|
module Aspera
|
7
9
|
# detect OS, architecture, and specific stuff
|
8
10
|
class Environment
|
@@ -84,12 +86,14 @@ module Aspera
|
|
84
86
|
end
|
85
87
|
|
86
88
|
# value is provided in block
|
87
|
-
def write_file_restricted(path, force: false)
|
89
|
+
def write_file_restricted(path, force: false, mode: nil)
|
88
90
|
raise 'coding error, missing content block' unless block_given?
|
89
91
|
if force || !File.exist?(path)
|
90
|
-
|
92
|
+
# Windows may give error
|
93
|
+
File.unlink(path) rescue nil
|
94
|
+
# content provided by block
|
91
95
|
File.write(path, yield)
|
92
|
-
restrict_file_access(path)
|
96
|
+
restrict_file_access(path, mode: mode)
|
93
97
|
end
|
94
98
|
return path
|
95
99
|
end
|
@@ -9,7 +9,9 @@ require 'tty-spinner'
|
|
9
9
|
module Aspera
|
10
10
|
module Fasp
|
11
11
|
class AgentConnect < Aspera::Fasp::AgentBase
|
12
|
+
# try twice the main init url in sequence
|
12
13
|
CONNECT_START_URIS = ['fasp://initialize', 'fasp://initialize', 'aspera-drive://initialize', 'https://test-connect.ibmaspera.com/']
|
14
|
+
# delay between each try to start connect
|
13
15
|
SLEEP_SEC_BETWEEN_RETRY = 3
|
14
16
|
private_constant :CONNECT_START_URIS, :SLEEP_SEC_BETWEEN_RETRY
|
15
17
|
def initialize(_options)
|
@@ -66,7 +68,7 @@ module Aspera
|
|
66
68
|
}]}
|
67
69
|
# asynchronous anyway
|
68
70
|
res = @connect_api.create('transfers/start', connect_transfer_args)[:data]
|
69
|
-
@xfer_id = res['transfer_specs'].first['transfer_spec']['tags'][
|
71
|
+
@xfer_id = res['transfer_specs'].first['transfer_spec']['tags'][Fasp::TransferSpec::TAG_RESERVED]['xfer_id']
|
70
72
|
end
|
71
73
|
|
72
74
|
def wait_for_transfers_completion
|
@@ -106,6 +108,9 @@ module Aspera
|
|
106
108
|
when 'failed'
|
107
109
|
spinner&.error
|
108
110
|
raise Fasp::Error, transfer['error_desc']
|
111
|
+
when 'cancelled'
|
112
|
+
spinner&.error
|
113
|
+
raise Fasp::Error, 'Transfer cancelled by user'
|
109
114
|
else
|
110
115
|
raise Fasp::Error, "unknown status: #{transfer['status']}: #{transfer['error_desc']}"
|
111
116
|
end
|
@@ -25,7 +25,7 @@ module Aspera
|
|
25
25
|
multi_incr_udp: true,
|
26
26
|
resume: {},
|
27
27
|
ascp_args: [],
|
28
|
-
quiet: true # by default no
|
28
|
+
quiet: true # by default no native ascp progress bar
|
29
29
|
}.freeze
|
30
30
|
private_constant :DEFAULT_OPTIONS
|
31
31
|
|
@@ -37,15 +37,15 @@ module Aspera
|
|
37
37
|
# clone transfer spec because we modify it (first level keys)
|
38
38
|
transfer_spec = transfer_spec.clone
|
39
39
|
# if there is aspera tags
|
40
|
-
if transfer_spec['tags'].is_a?(Hash) && transfer_spec['tags'][
|
40
|
+
if transfer_spec['tags'].is_a?(Hash) && transfer_spec['tags'][Fasp::TransferSpec::TAG_RESERVED].is_a?(Hash)
|
41
41
|
# TODO: what is this for ? only on local ascp ?
|
42
42
|
# NOTE: important: transfer id must be unique: generate random id
|
43
43
|
# using a non unique id results in discard of tags in AoC, and a package is never finalized
|
44
44
|
# all sessions in a multi-session transfer must have the same xfer_id (see admin manual)
|
45
|
-
transfer_spec['tags'][
|
45
|
+
transfer_spec['tags'][Fasp::TransferSpec::TAG_RESERVED]['xfer_id'] ||= SecureRandom.uuid
|
46
46
|
Log.log.debug{"xfer id=#{transfer_spec['xfer_id']}"}
|
47
47
|
# TODO: useful ? node only ?
|
48
|
-
transfer_spec['tags'][
|
48
|
+
transfer_spec['tags'][Fasp::TransferSpec::TAG_RESERVED]['xfer_retry'] ||= 3600
|
49
49
|
end
|
50
50
|
Log.dump('ts', transfer_spec)
|
51
51
|
|
@@ -82,12 +82,12 @@ module Aspera
|
|
82
82
|
end
|
83
83
|
|
84
84
|
# compute known args
|
85
|
-
env_args =
|
85
|
+
env_args = Parameters.new(transfer_spec, @options).ascp_args
|
86
86
|
|
87
87
|
# add fallback cert and key as arguments if needed
|
88
|
-
if
|
89
|
-
env_args[:args].unshift('-Y', Installation.instance.path(:
|
90
|
-
env_args[:args].unshift('-I', Installation.instance.path(:
|
88
|
+
if ['1', 1, true, 'force'].include?(transfer_spec['http_fallback'])
|
89
|
+
env_args[:args].unshift('-Y', Installation.instance.path(:fallback_cert_privkey))
|
90
|
+
env_args[:args].unshift('-I', Installation.instance.path(:fallback_certificate))
|
91
91
|
end
|
92
92
|
|
93
93
|
env_args[:args].unshift('-q') if @options[:quiet]
|
@@ -183,20 +183,20 @@ module Aspera
|
|
183
183
|
end
|
184
184
|
# (optional) check it exists
|
185
185
|
raise Fasp::Error, "no such file: #{ascp_path}" unless File.exist?(ascp_path)
|
186
|
-
# open
|
186
|
+
# open an available (0) local TCP port as ascp management
|
187
187
|
mgt_sock = TCPServer.new('127.0.0.1', 0)
|
188
188
|
# clone arguments as we eed to modify with mgt port
|
189
189
|
ascp_arguments = env_args[:args].clone
|
190
|
-
# add management port
|
190
|
+
# add management port on the selected local port
|
191
191
|
ascp_arguments.unshift('-M', mgt_sock.addr[1].to_s)
|
192
192
|
# start ascp in sub process
|
193
193
|
Log.log.debug do
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
Shellwords.shellescape(ascp_path)
|
198
|
-
|
199
|
-
|
194
|
+
[
|
195
|
+
'execute:',
|
196
|
+
env_args[:env].map{|k, v| "#{k}=#{Shellwords.shellescape(v)}"},
|
197
|
+
Shellwords.shellescape(ascp_path),
|
198
|
+
ascp_arguments.map{|a|Shellwords.shellescape(a)}
|
199
|
+
].flatten.join(' ')
|
200
200
|
end
|
201
201
|
# start process
|
202
202
|
ascp_pid = Process.spawn(env_args[:env], [ascp_path, ascp_path], *ascp_arguments)
|
@@ -334,7 +334,7 @@ module Aspera
|
|
334
334
|
# @param options : keys(symbol): see DEFAULT_OPTIONS
|
335
335
|
def initialize(options=nil)
|
336
336
|
super()
|
337
|
-
# all transfer jobs, key = SecureRandom.uuid, protected by mutex,
|
337
|
+
# all transfer jobs, key = SecureRandom.uuid, protected by mutex, cond var on change
|
338
338
|
@jobs = {}
|
339
339
|
# mutex protects global data accessed by threads
|
340
340
|
@mutex = Mutex.new
|