aspera-cli 4.13.0 → 4.15.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 +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
|