aspera-cli 4.13.0 → 4.15.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 +81 -7
- data/CONTRIBUTING.md +22 -6
- data/README.md +2038 -1080
- data/bin/ascli +18 -9
- data/bin/asession +12 -14
- data/examples/dascli +1 -1
- data/examples/proxy.pac +1 -1
- data/examples/rubyc +24 -0
- data/lib/aspera/aoc.rb +219 -159
- data/lib/aspera/ascmd.rb +25 -14
- data/lib/aspera/cli/basic_auth_plugin.rb +12 -9
- data/lib/aspera/cli/error.rb +17 -0
- data/lib/aspera/cli/extended_value.rb +47 -12
- data/lib/aspera/cli/formatter.rb +260 -179
- data/lib/aspera/cli/hints.rb +80 -0
- data/lib/aspera/cli/main.rb +104 -156
- data/lib/aspera/cli/manager.rb +259 -209
- data/lib/aspera/cli/plugin.rb +123 -63
- data/lib/aspera/cli/plugins/alee.rb +2 -3
- data/lib/aspera/cli/plugins/aoc.rb +341 -261
- data/lib/aspera/cli/plugins/ats.rb +22 -21
- data/lib/aspera/cli/plugins/bss.rb +5 -5
- data/lib/aspera/cli/plugins/config.rb +578 -627
- data/lib/aspera/cli/plugins/console.rb +44 -6
- data/lib/aspera/cli/plugins/cos.rb +15 -17
- data/lib/aspera/cli/plugins/faspex.rb +114 -100
- data/lib/aspera/cli/plugins/faspex5.rb +411 -264
- data/lib/aspera/cli/plugins/node.rb +354 -259
- data/lib/aspera/cli/plugins/orchestrator.rb +61 -29
- data/lib/aspera/cli/plugins/preview.rb +82 -90
- data/lib/aspera/cli/plugins/server.rb +79 -32
- data/lib/aspera/cli/plugins/shares.rb +55 -42
- data/lib/aspera/cli/sync_actions.rb +68 -0
- data/lib/aspera/cli/transfer_agent.rb +66 -73
- data/lib/aspera/cli/transfer_progress.rb +74 -0
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/colors.rb +12 -8
- data/lib/aspera/command_line_builder.rb +14 -11
- data/lib/aspera/cos_node.rb +3 -2
- data/lib/aspera/data/6 +0 -0
- data/lib/aspera/environment.rb +24 -9
- data/lib/aspera/fasp/agent_aspera.rb +126 -0
- data/lib/aspera/fasp/agent_base.rb +31 -77
- data/lib/aspera/fasp/agent_connect.rb +25 -21
- data/lib/aspera/fasp/agent_direct.rb +89 -103
- data/lib/aspera/fasp/agent_httpgw.rb +231 -149
- data/lib/aspera/fasp/agent_node.rb +41 -34
- data/lib/aspera/fasp/agent_trsdk.rb +75 -32
- data/lib/aspera/fasp/error_info.rb +4 -2
- data/lib/aspera/fasp/faux_file.rb +52 -0
- data/lib/aspera/fasp/installation.rb +53 -195
- data/lib/aspera/fasp/management.rb +244 -0
- data/lib/aspera/fasp/parameters.rb +71 -37
- data/lib/aspera/fasp/parameters.yaml +76 -8
- data/lib/aspera/fasp/products.rb +162 -0
- data/lib/aspera/fasp/resume_policy.rb +3 -3
- data/lib/aspera/fasp/transfer_spec.rb +7 -6
- data/lib/aspera/fasp/uri.rb +26 -24
- data/lib/aspera/faspex_gw.rb +2 -2
- data/lib/aspera/faspex_postproc.rb +2 -2
- data/lib/aspera/hash_ext.rb +14 -4
- data/lib/aspera/json_rpc.rb +49 -0
- data/lib/aspera/keychain/macos_security.rb +13 -13
- data/lib/aspera/line_logger.rb +23 -0
- data/lib/aspera/log.rb +58 -16
- data/lib/aspera/node.rb +157 -92
- data/lib/aspera/oauth.rb +37 -19
- data/lib/aspera/open_application.rb +4 -4
- data/lib/aspera/persistency_action_once.rb +1 -1
- data/lib/aspera/persistency_folder.rb +2 -2
- data/lib/aspera/preview/file_types.rb +4 -2
- data/lib/aspera/preview/generator.rb +22 -35
- data/lib/aspera/preview/options.rb +2 -0
- data/lib/aspera/preview/terminal.rb +73 -16
- data/lib/aspera/preview/utils.rb +21 -28
- data/lib/aspera/proxy_auto_config.js +2 -2
- data/lib/aspera/rest.rb +136 -68
- data/lib/aspera/rest_call_error.rb +1 -1
- data/lib/aspera/rest_error_analyzer.rb +15 -14
- data/lib/aspera/rest_errors_aspera.rb +37 -34
- data/lib/aspera/secret_hider.rb +18 -15
- data/lib/aspera/ssh.rb +5 -2
- data/lib/aspera/sync.rb +127 -119
- data/lib/aspera/temp_file_manager.rb +10 -3
- data/lib/aspera/web_auth.rb +10 -7
- data/lib/aspera/web_server_simple.rb +9 -4
- data.tar.gz.sig +0 -0
- metadata +34 -17
- metadata.gz.sig +0 -0
- data/docs/test_env.conf +0 -186
- data/lib/aspera/cli/listener/line_dump.rb +0 -19
- data/lib/aspera/cli/listener/logger.rb +0 -22
- data/lib/aspera/cli/listener/progress.rb +0 -50
- data/lib/aspera/cli/listener/progress_multi.rb +0 -84
- data/lib/aspera/cli/plugins/sync.rb +0 -44
- data/lib/aspera/data/7 +0 -0
- data/lib/aspera/fasp/listener.rb +0 -13
@@ -1,8 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
require 'aspera/fasp/transfer_spec'
|
4
|
-
require 'aspera/cli/listener/logger'
|
5
|
-
require 'aspera/cli/listener/progress_multi'
|
6
4
|
require 'aspera/cli/info'
|
7
5
|
|
8
6
|
module Aspera
|
@@ -16,7 +14,7 @@ module Aspera
|
|
16
14
|
# special value for --sources : read file list from transfer spec (--ts)
|
17
15
|
FILE_LIST_FROM_TRANSFER_SPEC = '@ts'
|
18
16
|
FILE_LIST_OPTIONS = [FILE_LIST_FROM_ARGS, FILE_LIST_FROM_TRANSFER_SPEC, 'Array'].freeze
|
19
|
-
|
17
|
+
DEFAULT_TRANSFER_NOTIFY_TEMPLATE = <<~END_OF_TEMPLATE
|
20
18
|
From: <%=from_name%> <<%=from_email%>>
|
21
19
|
To: <<%=to%>>
|
22
20
|
Subject: <%=subject%>
|
@@ -29,7 +27,7 @@ module Aspera
|
|
29
27
|
private_constant :FILE_LIST_FROM_ARGS,
|
30
28
|
:FILE_LIST_FROM_TRANSFER_SPEC,
|
31
29
|
:FILE_LIST_OPTIONS,
|
32
|
-
:
|
30
|
+
:DEFAULT_TRANSFER_NOTIFY_TEMPLATE
|
33
31
|
TRANSFER_AGENTS = %i[direct node connect httpgw trsdk].freeze
|
34
32
|
|
35
33
|
class << self
|
@@ -43,81 +41,79 @@ module Aspera
|
|
43
41
|
end
|
44
42
|
|
45
43
|
# @param env external objects: option manager, config file manager
|
46
|
-
def initialize(opt_mgr,
|
44
|
+
def initialize(opt_mgr, config_plugin)
|
47
45
|
@opt_mgr = opt_mgr
|
48
|
-
@config =
|
46
|
+
@config = config_plugin
|
49
47
|
# command line can override transfer spec
|
50
|
-
@
|
48
|
+
@transfer_spec_command_line = {'create_dir' => true}
|
49
|
+
# options for transfer agent
|
51
50
|
@transfer_info = {}
|
52
51
|
# the currently selected transfer agent
|
53
52
|
@agent = nil
|
54
|
-
@progress_listener = Listener::ProgressMulti.new
|
55
53
|
# source/destination pair, like "paths" of transfer spec
|
56
54
|
@transfer_paths = nil
|
57
|
-
@opt_mgr.
|
58
|
-
@opt_mgr.
|
59
|
-
@opt_mgr.
|
60
|
-
@opt_mgr.
|
61
|
-
@opt_mgr.
|
62
|
-
@opt_mgr.
|
63
|
-
@opt_mgr.add_opt_list(:transfer, TRANSFER_AGENTS, 'Type of transfer agent')
|
64
|
-
@opt_mgr.add_opt_simple(:transfer_info, 'Parameters for transfer agent (Hash)')
|
65
|
-
@opt_mgr.add_opt_list(:progress, %i[none native multi], 'Type of progress bar')
|
66
|
-
@opt_mgr.set_option(:transfer, :direct)
|
67
|
-
@opt_mgr.set_option(:src_type, :list)
|
68
|
-
@opt_mgr.set_option(:progress, :native) # use native ascp progress bar as it is more reliable
|
55
|
+
@opt_mgr.declare(:ts, 'Override transfer spec values', types: Hash, handler: {o: self, m: :option_transfer_spec})
|
56
|
+
@opt_mgr.declare(:to_folder, 'Destination folder for transferred files')
|
57
|
+
@opt_mgr.declare(:sources, "How list of transferred files is provided (#{FILE_LIST_OPTIONS.join(',')})")
|
58
|
+
@opt_mgr.declare(:src_type, 'Type of file list', values: %i[list pair], default: :list)
|
59
|
+
@opt_mgr.declare(:transfer, 'Type of transfer agent', values: TRANSFER_AGENTS, default: :direct)
|
60
|
+
@opt_mgr.declare(:transfer_info, 'Parameters for transfer agent', types: Hash, handler: {o: self, m: :transfer_info})
|
69
61
|
@opt_mgr.parse_options!
|
70
62
|
end
|
71
63
|
|
72
|
-
def option_transfer_spec; @
|
64
|
+
def option_transfer_spec; @transfer_spec_command_line; end
|
73
65
|
|
74
66
|
# multiple option are merged
|
75
67
|
def option_transfer_spec=(value)
|
76
68
|
raise 'option ts shall be a Hash' unless value.is_a?(Hash)
|
77
|
-
@
|
69
|
+
@transfer_spec_command_line.deep_merge!(value)
|
78
70
|
end
|
79
71
|
|
80
|
-
|
72
|
+
# add other transfer spec parameters
|
73
|
+
def option_transfer_spec_deep_merge(ts); @transfer_spec_command_line.deep_merge!(ts); end
|
81
74
|
|
82
|
-
#
|
83
|
-
def
|
84
|
-
|
85
|
-
|
75
|
+
# @return [Hash] transfer spec with updated values from command line, including removed values
|
76
|
+
def updated_ts(transfer_spec={})
|
77
|
+
transfer_spec.deep_merge!(@transfer_spec_command_line)
|
78
|
+
# recursively remove values that are nil (user wants to delete)
|
79
|
+
transfer_spec.deep_do { |hash, key, value, _unused| hash.delete(key) if value.nil?}
|
80
|
+
return transfer_spec
|
86
81
|
end
|
87
82
|
|
88
|
-
|
83
|
+
attr_reader :transfer_info
|
84
|
+
|
85
|
+
# multiple option are merged
|
86
|
+
def transfer_info=(value)
|
87
|
+
@transfer_info.deep_merge!(value)
|
88
|
+
end
|
89
89
|
|
90
90
|
def agent_instance=(instance)
|
91
91
|
@agent = instance
|
92
|
-
@agent.add_listener(Listener::Logger.new)
|
93
|
-
# use local progress bar if asked so, or if native and non local ascp (because only local ascp has native progress bar)
|
94
|
-
if @opt_mgr.get_option(:progress, is_type: :mandatory).eql?(:multi) ||
|
95
|
-
(@opt_mgr.get_option(:progress, is_type: :mandatory).eql?(:native) && !instance.class.to_s.eql?('Aspera::Fasp::AgentDirect'))
|
96
|
-
@agent.add_listener(@progress_listener)
|
97
|
-
end
|
98
92
|
end
|
99
93
|
|
100
94
|
# analyze options and create new agent if not already created or set
|
101
95
|
def set_agent_by_options
|
102
96
|
return nil unless @agent.nil?
|
103
|
-
agent_type = @opt_mgr.get_option(:transfer,
|
97
|
+
agent_type = @opt_mgr.get_option(:transfer, mandatory: true)
|
104
98
|
# agent plugin is loaded on demand to avoid loading unnecessary dependencies
|
105
99
|
require "aspera/fasp/agent_#{agent_type}"
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
100
|
+
# set keys as symbols
|
101
|
+
agent_options = @opt_mgr.get_option(:transfer_info).symbolize_keys
|
102
|
+
# special cases
|
103
|
+
case agent_type
|
104
|
+
when :node
|
105
|
+
if agent_options.empty?
|
106
|
+
param_set_name = @config.get_plugin_default_config_name(:node)
|
107
|
+
raise Cli::BadArgument, "No default node configured. Please specify #{Manager.option_name_to_line(:transfer_info)}" if param_set_name.nil?
|
108
|
+
agent_options = @config.preset_by_name(param_set_name).symbolize_keys
|
109
|
+
end
|
110
|
+
when :direct
|
111
|
+
# by default do not display ascp native progress bar
|
112
|
+
agent_options[:quiet] = true unless agent_options.key?(:quiet)
|
113
|
+
agent_options[:check_ignore] = ->(host, port){@config.ignore_cert?(host, port)}
|
114
|
+
agent_options[:trusted_certs] = @config.trusted_cert_locations(files_only: true) unless agent_options.key?(:trusted_certs)
|
118
115
|
end
|
119
|
-
|
120
|
-
agent_options = agent_options.symbolize_keys
|
116
|
+
agent_options[:progress] = @config.progress_bar
|
121
117
|
# get agent instance
|
122
118
|
new_agent = Kernel.const_get("Aspera::Fasp::Agent#{agent_type.capitalize}").new(agent_options)
|
123
119
|
self.agent_instance = new_agent
|
@@ -131,7 +127,7 @@ module Aspera
|
|
131
127
|
dest_folder = @opt_mgr.get_option(:to_folder)
|
132
128
|
# do not expand path, if user wants to expand path: user @path:
|
133
129
|
return dest_folder unless dest_folder.nil?
|
134
|
-
dest_folder = @
|
130
|
+
dest_folder = @transfer_spec_command_line['destination_root']
|
135
131
|
return dest_folder unless dest_folder.nil?
|
136
132
|
# default: / on remote, . on local
|
137
133
|
case direction.to_s
|
@@ -157,7 +153,7 @@ module Aspera
|
|
157
153
|
# return cache if set
|
158
154
|
return @transfer_paths unless @transfer_paths.nil?
|
159
155
|
# start with lower priority : get paths from transfer spec on command line
|
160
|
-
@transfer_paths = @
|
156
|
+
@transfer_paths = @transfer_spec_command_line['paths'] if @transfer_spec_command_line.key?('paths')
|
161
157
|
# is there a source list option ?
|
162
158
|
file_list = @opt_mgr.get_option(:sources)
|
163
159
|
case file_list
|
@@ -165,32 +161,32 @@ module Aspera
|
|
165
161
|
Log.log.debug('getting file list as parameters')
|
166
162
|
# get remaining arguments
|
167
163
|
file_list = @opt_mgr.get_next_argument('source file list', expected: :multiple)
|
168
|
-
raise
|
164
|
+
raise Cli::BadArgument, 'specify at least one file on command line or use ' \
|
169
165
|
"--sources=#{FILE_LIST_FROM_TRANSFER_SPEC} to use transfer spec" if !file_list.is_a?(Array) || file_list.empty?
|
170
166
|
when FILE_LIST_FROM_TRANSFER_SPEC
|
171
167
|
Log.log.debug('assume list provided in transfer spec')
|
172
168
|
special_case_direct_with_list =
|
173
|
-
@opt_mgr.get_option(:transfer,
|
174
|
-
Fasp::Parameters.ts_has_ascp_file_list(@
|
175
|
-
raise
|
169
|
+
@opt_mgr.get_option(:transfer, mandatory: true).eql?(:direct) &&
|
170
|
+
Fasp::Parameters.ts_has_ascp_file_list(@transfer_spec_command_line, @opt_mgr.get_option(:transfer_info))
|
171
|
+
raise Cli::BadArgument, 'transfer spec on command line must have sources' if @transfer_paths.nil? && !special_case_direct_with_list
|
176
172
|
# here we assume check of sources is made in transfer agent
|
177
173
|
return @transfer_paths
|
178
174
|
when Array
|
179
175
|
Log.log.debug('getting file list as extended value')
|
180
|
-
raise
|
176
|
+
raise Cli::BadArgument, 'sources must be a Array of String' if !file_list.reject{|f|f.is_a?(String)}.empty?
|
181
177
|
else
|
182
|
-
raise
|
178
|
+
raise Cli::BadArgument, "sources must be a Array, not #{file_list.class}"
|
183
179
|
end
|
184
180
|
# here, file_list is an Array or String
|
185
181
|
if !@transfer_paths.nil?
|
186
182
|
Log.log.warn('--sources overrides paths from --ts')
|
187
183
|
end
|
188
|
-
case @opt_mgr.get_option(:src_type,
|
184
|
+
case @opt_mgr.get_option(:src_type, mandatory: true)
|
189
185
|
when :list
|
190
186
|
# when providing a list, just specify source
|
191
187
|
@transfer_paths = file_list.map{|i|{'source' => i}}
|
192
188
|
when :pair
|
193
|
-
raise
|
189
|
+
raise Cli::BadArgument, "When using pair, provide an even number of paths: #{file_list.length}" unless file_list.length.even?
|
194
190
|
@transfer_paths = file_list.each_slice(2).to_a.map{|s, d|{'source' => s, 'destination' => d}}
|
195
191
|
else raise 'Unsupported src_type'
|
196
192
|
end
|
@@ -208,40 +204,37 @@ module Aspera
|
|
208
204
|
case transfer_spec['direction']
|
209
205
|
when Fasp::TransferSpec::DIRECTION_RECEIVE
|
210
206
|
# init default if required in any case
|
211
|
-
@
|
207
|
+
@transfer_spec_command_line['destination_root'] ||= destination_folder(transfer_spec['direction'])
|
212
208
|
when Fasp::TransferSpec::DIRECTION_SEND
|
213
209
|
if transfer_spec.dig('tags', Fasp::TransferSpec::TAG_RESERVED, 'node', 'access_key')
|
214
210
|
# gen4
|
215
|
-
@
|
211
|
+
@transfer_spec_command_line.delete('destination_root') if @transfer_spec_command_line.key?('destination_root_id')
|
216
212
|
elsif transfer_spec.key?('token')
|
217
213
|
# gen3
|
218
214
|
# in that case, destination is set in return by application (API/upload_setup)
|
219
215
|
# but to_folder was used in initial API call
|
220
|
-
@
|
216
|
+
@transfer_spec_command_line.delete('destination_root')
|
221
217
|
else
|
222
218
|
# init default if required
|
223
|
-
@
|
219
|
+
@transfer_spec_command_line['destination_root'] ||= destination_folder(transfer_spec['direction'])
|
224
220
|
end
|
225
221
|
end
|
226
222
|
# update command line paths, unless destination already has one
|
227
|
-
@
|
228
|
-
|
229
|
-
|
230
|
-
transfer_spec.delete_if { |_key, value| value.nil? }
|
223
|
+
@transfer_spec_command_line['paths'] = transfer_spec['paths'] || ts_source_paths
|
224
|
+
# updated transfer spec with command line
|
225
|
+
updated_ts(transfer_spec)
|
231
226
|
# create transfer agent
|
232
227
|
set_agent_by_options
|
233
228
|
Log.log.debug{"transfer agent is a #{@agent.class}"}
|
234
229
|
@agent.start_transfer(transfer_spec, token_regenerator: rest_token)
|
235
|
-
# list of
|
236
|
-
result = @agent.
|
237
|
-
@progress_listener.reset
|
238
|
-
Fasp::AgentBase.validate_status_list(result)
|
230
|
+
# list of: :success or "error message string"
|
231
|
+
result = @agent.wait_for_completion
|
239
232
|
send_email_transfer_notification(transfer_spec, result)
|
240
233
|
return result
|
241
234
|
end
|
242
235
|
|
243
236
|
def send_email_transfer_notification(transfer_spec, statuses)
|
244
|
-
return if @opt_mgr.get_option(:
|
237
|
+
return if @opt_mgr.get_option(:notify_to).nil?
|
245
238
|
global_status = self.class.session_status(statuses)
|
246
239
|
email_vars = {
|
247
240
|
global_transfer_status: global_status,
|
@@ -249,7 +242,7 @@ module Aspera
|
|
249
242
|
body: "Transfer is: #{global_status}",
|
250
243
|
ts: transfer_spec
|
251
244
|
}
|
252
|
-
@config.send_email_template(email_template_default:
|
245
|
+
@config.send_email_template(email_template_default: DEFAULT_TRANSFER_NOTIFY_TEMPLATE, values: email_vars)
|
253
246
|
end
|
254
247
|
|
255
248
|
# shut down if agent requires it
|
@@ -0,0 +1,74 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'aspera/log'
|
4
|
+
require 'ruby-progressbar'
|
5
|
+
|
6
|
+
module Aspera
|
7
|
+
module Cli
|
8
|
+
# progress bar for transfers, supports multi-session
|
9
|
+
class TransferProgress
|
10
|
+
def initialize
|
11
|
+
reset
|
12
|
+
end
|
13
|
+
|
14
|
+
def reset
|
15
|
+
@progress_bar = nil
|
16
|
+
# key is session id
|
17
|
+
@sessions = {}
|
18
|
+
@completed = false
|
19
|
+
@title = ''
|
20
|
+
end
|
21
|
+
|
22
|
+
def total(key)
|
23
|
+
@sessions.values.inject(0){|m, s|m + s[key]}
|
24
|
+
end
|
25
|
+
|
26
|
+
def event(session_id:, type:, info: nil)
|
27
|
+
Log.log.debug{"progress: #{type} #{session_id} #{info}"}
|
28
|
+
if session_id.nil? && !type.eql?(:pre_start)
|
29
|
+
raise 'Internal error: session_id is nil'
|
30
|
+
end
|
31
|
+
return if @completed
|
32
|
+
if @progress_bar.nil?
|
33
|
+
@progress_bar = ProgressBar.create(
|
34
|
+
format: '%t %a %B %p%% %r Mbps %E',
|
35
|
+
rate_scale: lambda{|rate|rate / Environment::BYTES_PER_MEBIBIT},
|
36
|
+
title: '',
|
37
|
+
total: nil)
|
38
|
+
end
|
39
|
+
need_increment = true
|
40
|
+
case type
|
41
|
+
when :pre_start
|
42
|
+
@title = info
|
43
|
+
when :session_start
|
44
|
+
raise "Session #{session_id} already started" if @sessions[session_id]
|
45
|
+
@sessions[session_id] = {
|
46
|
+
job_size: 0, # total size of transfer (pre-calc)
|
47
|
+
current: 0
|
48
|
+
}
|
49
|
+
@title = ''
|
50
|
+
when :session_size
|
51
|
+
@sessions[session_id][:job_size] = info.to_i
|
52
|
+
current_total = total(:job_size)
|
53
|
+
@progress_bar.total = current_total unless current_total.eql?(@progress_bar.total) || current_total < @progress_bar.progress
|
54
|
+
when :transfer
|
55
|
+
if !@progress_bar.total.nil?
|
56
|
+
need_increment = false
|
57
|
+
@sessions[session_id][:current] = info.to_i
|
58
|
+
current_total = total(:current)
|
59
|
+
@progress_bar.progress = current_total unless @progress_bar.progress.eql?(current_total)
|
60
|
+
end
|
61
|
+
when :end
|
62
|
+
@title = ''
|
63
|
+
@completed = true
|
64
|
+
@progress_bar.finish
|
65
|
+
else
|
66
|
+
raise "Unknown event type #{type}"
|
67
|
+
end
|
68
|
+
new_title = @sessions.length < 2 ? @title : "[#{@sessions.length}] #{@title}"
|
69
|
+
@progress_bar.title = new_title unless @progress_bar.title.eql?(new_title)
|
70
|
+
@progress_bar.increment if need_increment && !@completed
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
data/lib/aspera/cli/version.rb
CHANGED
data/lib/aspera/colors.rb
CHANGED
@@ -1,21 +1,25 @@
|
|
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,
|
17
|
+
dim: 2,
|
15
18
|
italic: 3,
|
16
19
|
underline: 4,
|
17
20
|
blink: 5,
|
18
21
|
reverse_color: 7,
|
22
|
+
invisible: 8,
|
19
23
|
black: 30,
|
20
24
|
red: 31,
|
21
25
|
green: 32,
|
@@ -33,17 +37,17 @@ class String
|
|
33
37
|
bg_cyan: 46,
|
34
38
|
bg_gray: 47
|
35
39
|
}.freeze
|
36
|
-
private_constant :
|
37
|
-
# defines methods to String, one per entry in
|
38
|
-
|
39
|
-
if $
|
40
|
-
begin_seq =
|
40
|
+
private_constant :VT_STYLES
|
41
|
+
# defines methods to String, one per entry in VT_STYLES
|
42
|
+
VT_STYLES.each do |name, code|
|
43
|
+
if $stdout.tty?
|
44
|
+
begin_seq = vt_cmd(code)
|
41
45
|
end_code = 0 # by default reset all
|
42
46
|
if code <= 7 then code + 20
|
43
47
|
elsif code <= 37 then 39
|
44
48
|
elsif code <= 47 then 49
|
45
49
|
end
|
46
|
-
end_seq =
|
50
|
+
end_seq = vt_cmd(end_code)
|
47
51
|
define_method(name){"#{begin_seq}#{self}#{end_seq}"}
|
48
52
|
else
|
49
53
|
define_method(name){self}
|
@@ -55,31 +55,34 @@ module Aspera
|
|
55
55
|
|
56
56
|
attr_reader :params_definition
|
57
57
|
|
58
|
-
# @param param_hash
|
58
|
+
# @param [Hash] param_hash with parameters
|
59
|
+
# @param [Hash] params_definition with definition of parameters
|
59
60
|
def initialize(param_hash, params_definition)
|
60
61
|
@param_hash = param_hash # keep reference so that it can be modified by caller before calling `process_params`
|
61
62
|
@params_definition = params_definition
|
62
|
-
@
|
63
|
-
|
63
|
+
@result = {
|
64
|
+
env: {},
|
65
|
+
args: []
|
66
|
+
}
|
64
67
|
@used_param_names = []
|
65
68
|
end
|
66
69
|
|
67
|
-
#
|
68
|
-
#
|
69
|
-
def add_env_args(
|
70
|
-
Log.log.debug{"ENV=#{@
|
70
|
+
# add processed parameters to env and args, warns about unused parameters
|
71
|
+
# @param [Hash] env_args with :env and :args
|
72
|
+
def add_env_args(env_args)
|
73
|
+
Log.log.debug{"add_env_args: ENV=#{@result[:env]}, ARGS=#{@result[:args]}"}
|
71
74
|
# warn about non translated arguments
|
72
75
|
@param_hash.each_pair{|key, val|Log.log.warn{"unrecognized parameter: #{key} = \"#{val}\""} if !@used_param_names.include?(key)}
|
73
76
|
# set result
|
74
|
-
env.merge!(@
|
75
|
-
args.push(*@
|
77
|
+
env_args[:env].merge!(@result[:env])
|
78
|
+
env_args[:args].push(*@result[:args])
|
76
79
|
return nil
|
77
80
|
end
|
78
81
|
|
79
82
|
# add options directly to command line
|
80
83
|
def add_command_line_options(options)
|
81
84
|
return if options.nil?
|
82
|
-
options.each{|o|@
|
85
|
+
options.each{|o|@result[:args].push(o.to_s)}
|
83
86
|
end
|
84
87
|
|
85
88
|
def process_params
|
@@ -157,7 +160,7 @@ module Aspera
|
|
157
160
|
return
|
158
161
|
when :envvar # set in env var
|
159
162
|
raise 'error' unless options[:cli].key?(:variable)
|
160
|
-
@
|
163
|
+
@result[:env][options[:cli][:variable]] = parameter_value
|
161
164
|
when :opt_without_arg # if present and true : just add option without value
|
162
165
|
add_param = false
|
163
166
|
case parameter_value
|
data/lib/aspera/cos_node.rb
CHANGED
@@ -2,12 +2,13 @@
|
|
2
2
|
|
3
3
|
require 'aspera/log'
|
4
4
|
require 'aspera/rest'
|
5
|
+
require 'aspera/oauth'
|
5
6
|
require 'xmlsimple'
|
6
7
|
|
7
8
|
module Aspera
|
8
9
|
class CosNode < Aspera::Node
|
9
10
|
class << self
|
10
|
-
def
|
11
|
+
def parameters_from_svc_credentials(service_credentials, bucket_region)
|
11
12
|
# check necessary contents
|
12
13
|
raise 'service_credentials must be a Hash' unless service_credentials.is_a?(Hash)
|
13
14
|
%w[apikey resource_instance_id endpoints].each do |field|
|
@@ -85,7 +86,7 @@ module Aspera
|
|
85
86
|
receiver_client_ids: 'aspera_ats'
|
86
87
|
}})
|
87
88
|
# get delegated token to be placed in rest call header and in transfer tags
|
88
|
-
@storage_credentials['token'][TOKEN_FIELD] = delegated_oauth.get_authorization
|
89
|
+
@storage_credentials['token'][TOKEN_FIELD] = Oauth.bearer_extract(delegated_oauth.get_authorization)
|
89
90
|
@params[:headers] = {'X-Aspera-Storage-Credentials' => JSON.generate(@storage_credentials)}
|
90
91
|
end
|
91
92
|
end
|
data/lib/aspera/data/6
CHANGED
Binary file
|
data/lib/aspera/environment.rb
CHANGED
@@ -1,8 +1,11 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
# cspell:ignore USERPROFILE HOMEDRIVE HOMEPATH LC_CTYPE msys aarch
|
3
4
|
require 'aspera/log'
|
4
5
|
require 'rbconfig'
|
5
6
|
|
7
|
+
# cspell:words MEBI mswin bccwin
|
8
|
+
|
6
9
|
module Aspera
|
7
10
|
# detect OS, architecture, and specific stuff
|
8
11
|
class Environment
|
@@ -50,7 +53,7 @@ module Aspera
|
|
50
53
|
return CPU_PPC64
|
51
54
|
when /s390/
|
52
55
|
return CPU_S390
|
53
|
-
when /arm/
|
56
|
+
when /arm/, /aarch64/
|
54
57
|
# arm on mac has rosetta 2
|
55
58
|
return CPU_X86_64 if os.eql?(OS_X)
|
56
59
|
end
|
@@ -69,9 +72,9 @@ module Aspera
|
|
69
72
|
# on Windows, the env var %USERPROFILE% provides the path to user's home more reliably than %HOMEDRIVE%%HOMEPATH%
|
70
73
|
# so, tell Ruby the right way
|
71
74
|
def fix_home
|
72
|
-
return unless os.eql?(OS_WINDOWS) && ENV.key?('USERPROFILE') && Dir.exist?(ENV
|
73
|
-
ENV['HOME'] = ENV
|
74
|
-
Log.log.debug{"Windows: set
|
75
|
+
return unless os.eql?(OS_WINDOWS) && ENV.key?('USERPROFILE') && Dir.exist?(ENV.fetch('USERPROFILE', nil))
|
76
|
+
ENV['HOME'] = ENV.fetch('USERPROFILE', nil)
|
77
|
+
Log.log.debug{"Windows: set HOME to USERPROFILE: #{Dir.home}"}
|
75
78
|
end
|
76
79
|
|
77
80
|
def empty_binding
|
@@ -79,17 +82,19 @@ module Aspera
|
|
79
82
|
end
|
80
83
|
|
81
84
|
# secure execution of Ruby code
|
82
|
-
def secure_eval(code)
|
83
|
-
Kernel.send('lave'.reverse, code, empty_binding,
|
85
|
+
def secure_eval(code, file, line)
|
86
|
+
Kernel.send('lave'.reverse, code, empty_binding, file, line)
|
84
87
|
end
|
85
88
|
|
86
89
|
# value is provided in block
|
87
|
-
def write_file_restricted(path, force: false)
|
90
|
+
def write_file_restricted(path, force: false, mode: nil)
|
88
91
|
raise 'coding error, missing content block' unless block_given?
|
89
92
|
if force || !File.exist?(path)
|
90
|
-
|
93
|
+
# Windows may give error
|
94
|
+
File.unlink(path) rescue nil
|
95
|
+
# content provided by block
|
91
96
|
File.write(path, yield)
|
92
|
-
restrict_file_access(path)
|
97
|
+
restrict_file_access(path, mode: mode)
|
93
98
|
end
|
94
99
|
return path
|
95
100
|
end
|
@@ -109,6 +114,16 @@ module Aspera
|
|
109
114
|
rescue => e
|
110
115
|
Log.log.warn(e.message)
|
111
116
|
end
|
117
|
+
|
118
|
+
def terminal?
|
119
|
+
$stdout.tty?
|
120
|
+
end
|
121
|
+
|
122
|
+
# @return true if we can display Unicode characters
|
123
|
+
def use_unicode?
|
124
|
+
@use_unicode = terminal? && ENV.values_at('LC_ALL', 'LC_CTYPE', 'LANG').compact.first.include?('UTF-8') if @use_unicode.nil?
|
125
|
+
return @use_unicode
|
126
|
+
end
|
112
127
|
end # self
|
113
128
|
end # Environment
|
114
129
|
end # Aspera
|