aspera-cli 4.12.0 → 4.14.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/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
|