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
data/lib/aspera/cli/main.rb
CHANGED
@@ -7,32 +7,17 @@ require 'aspera/cli/extended_value'
|
|
7
7
|
require 'aspera/cli/transfer_agent'
|
8
8
|
require 'aspera/cli/version'
|
9
9
|
require 'aspera/cli/info'
|
10
|
-
require 'aspera/
|
11
|
-
require 'aspera/open_application'
|
12
|
-
require 'aspera/temp_file_manager'
|
13
|
-
require 'aspera/persistency_folder'
|
14
|
-
require 'aspera/log'
|
15
|
-
require 'aspera/rest'
|
16
|
-
require 'aspera/nagios'
|
17
|
-
require 'aspera/colors'
|
10
|
+
require 'aspera/cli/hints'
|
18
11
|
require 'aspera/secret_hider'
|
19
|
-
require '
|
12
|
+
require 'aspera/log'
|
20
13
|
|
21
14
|
module Aspera
|
22
15
|
module Cli
|
23
16
|
# The main CLI class
|
24
17
|
class Main
|
25
|
-
#
|
26
|
-
ERROR_FLASH = 'ERROR:'.bg_red.gray.blink.freeze
|
27
|
-
WARNING_FLASH = 'WARNING:'.bg_red.gray.blink.freeze
|
28
|
-
private_constant :ERROR_FLASH, :WARNING_FLASH
|
29
|
-
|
30
|
-
# store transfer result using this key and use result_transfer_multiple
|
18
|
+
# Plugins store transfer result using this key and use result_transfer_multiple()
|
31
19
|
STATUS_FIELD = 'status'
|
32
20
|
|
33
|
-
# for testing only
|
34
|
-
SELF_SIGNED_CERT = OpenSSL::SSL.const_get(:enon_yfirev.to_s.upcase.reverse)
|
35
|
-
|
36
21
|
class << self
|
37
22
|
# expect some list, but nothing to display
|
38
23
|
def result_empty; return {type: :empty, data: :nil}; end
|
@@ -68,85 +53,55 @@ module Aspera
|
|
68
53
|
raise global_status unless global_status.eql?(:success)
|
69
54
|
return {type: :object_list, data: status_table}
|
70
55
|
end
|
71
|
-
end
|
56
|
+
end # self
|
72
57
|
|
73
58
|
private
|
74
59
|
|
60
|
+
# shortcuts helpers like in plugins
|
61
|
+
%i[options transfer config formatter persistency].each do |name|
|
62
|
+
define_method(name){@agents[name]}
|
63
|
+
end
|
64
|
+
|
75
65
|
# =============================================================
|
76
66
|
# Parameter handlers
|
77
67
|
#
|
78
|
-
attr_accessor :option_insecure, :option_http_options, :option_cache_tokens
|
79
|
-
|
80
|
-
def option_ui; OpenApplication.instance.url_method; end
|
81
|
-
|
82
|
-
def option_ui=(value); OpenApplication.instance.url_method = value; end
|
83
|
-
|
84
|
-
# called every time a new REST HTTP session is opened
|
85
|
-
# @param http [Net::HTTP] the newly created http session object
|
86
|
-
def http_parameters=(http)
|
87
|
-
if @option_insecure
|
88
|
-
url = http.inspect.gsub(/^[^ ]* /, 'https://').gsub(/ [^ ]*$/, '')
|
89
|
-
if !@ssl_warned_urls.include?(url)
|
90
|
-
@formatter.display_message(:error, "#{WARNING_FLASH} ignoring certificate for: #{url}. Do not use unsafe certificates in production.")
|
91
|
-
@ssl_warned_urls.push(url)
|
92
|
-
end
|
93
|
-
http.verify_mode = SELF_SIGNED_CERT
|
94
|
-
end
|
95
|
-
http.set_debug_output($stdout) if @option_rest_debug
|
96
|
-
raise 'http_options expects Hash' unless @option_http_options.is_a?(Hash)
|
97
|
-
|
98
|
-
@option_http_options.each do |k, v|
|
99
|
-
method = "#{k}=".to_sym
|
100
|
-
# check if accessor is a method of Net::HTTP
|
101
|
-
# continue_timeout= read_timeout= write_timeout=
|
102
|
-
if http.respond_to?(method)
|
103
|
-
http.send(method, v)
|
104
|
-
else
|
105
|
-
Log.log.error{"no such attribute: #{k}"}
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
68
|
|
110
|
-
# minimum initialization
|
69
|
+
# minimum initialization, no exception raised
|
111
70
|
def initialize(argv)
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
current_prog_name = File.basename($PROGRAM_NAME)
|
116
|
-
@formatter.display_message(:error, "#{'WARNING'.bg_red.blink.gray} Please use '#{PROGRAM_NAME}' instead of '#{current_prog_name}'") \
|
117
|
-
unless current_prog_name.eql?(PROGRAM_NAME)
|
71
|
+
@argv = argv
|
72
|
+
# environment provided to plugin for various capabilities
|
73
|
+
@agents = {}
|
118
74
|
@option_help = false
|
119
|
-
@bash_completion = false
|
120
75
|
@option_show_config = false
|
121
|
-
@
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
#
|
127
|
-
|
76
|
+
@bash_completion = false
|
77
|
+
end
|
78
|
+
|
79
|
+
# This can throw exception if there is a problem with the environment, needs to be caught by execute method
|
80
|
+
def init_agents_and_options
|
81
|
+
# first thing : manage debug level (allows debugging of option parser)
|
82
|
+
early_debug_setup
|
83
|
+
@agents[:formatter] = Formatter.new
|
84
|
+
@agents[:options] = Manager.new(PROGRAM_NAME)
|
128
85
|
# give command line arguments to option manager
|
129
|
-
|
86
|
+
options.parse_command_line(@argv)
|
130
87
|
# formatter adds options
|
131
|
-
|
132
|
-
|
133
|
-
|
88
|
+
formatter.declare_options(options)
|
89
|
+
# compare $0 with expected name
|
90
|
+
current_prog_name = File.basename($PROGRAM_NAME)
|
91
|
+
formatter.display_message(
|
92
|
+
:error,
|
93
|
+
"#{Formatter::WARNING_FLASH} Please use '#{PROGRAM_NAME}' instead of '#{current_prog_name}'") unless current_prog_name.eql?(PROGRAM_NAME)
|
134
94
|
# declare and parse global options
|
135
|
-
|
95
|
+
declare_global_options
|
136
96
|
# the Config plugin adds the @preset parser, so declare before TransferAgent which may use it
|
137
|
-
@
|
138
|
-
# the TransferAgent plugin may use the @preset parser
|
139
|
-
@plugin_env[:transfer] = TransferAgent.new(@plugin_env[:options], @plugin_env[:config])
|
97
|
+
@agents[:config] = Plugins::Config.new(@agents, gem: GEM_NAME, name: PROGRAM_NAME, help: DOC_URL, version: Aspera::Cli::VERSION)
|
140
98
|
# data persistency
|
141
|
-
|
99
|
+
raise 'internal error: missing persistency object' unless @agents[:persistency]
|
100
|
+
# the TransferAgent plugin may use the @preset parser
|
101
|
+
@agents[:transfer] = TransferAgent.new(options, config)
|
142
102
|
Log.log.debug('plugin env created'.red)
|
143
|
-
Oauth.persist_mgr = @plugin_env[:persistency] if @option_cache_tokens
|
144
|
-
Fasp::Parameters.file_list_folder = File.join(@plugin_env[:config].main_folder, 'filelists')
|
145
|
-
Aspera::RestErrorAnalyzer.instance.log_file = File.join(@plugin_env[:config].main_folder, 'rest_exceptions.log')
|
146
|
-
# register aspera REST call error handlers
|
147
|
-
Aspera::RestErrorsAspera.register_handlers
|
148
103
|
# set banner when all environment is created so that additional extended value modifiers are known, e.g. @preset
|
149
|
-
|
104
|
+
options.parser.banner = app_banner
|
150
105
|
end
|
151
106
|
|
152
107
|
def app_banner
|
@@ -166,7 +121,6 @@ module Aspera
|
|
166
121
|
#{t}source repo: #{SRC_URL}
|
167
122
|
|
168
123
|
ENVIRONMENT VARIABLES
|
169
|
-
#{t}#{@plugin_env[:config].conf_dir_env_var} config folder, default: $HOME/#{Plugins::Config::ASPERA_HOME_FOLDER_NAME}/#{PROGRAM_NAME}
|
170
124
|
#{t}Any option can be set as an environment variable, refer to the manual
|
171
125
|
|
172
126
|
COMMANDS
|
@@ -185,44 +139,36 @@ module Aspera
|
|
185
139
|
end
|
186
140
|
|
187
141
|
# define header for manual
|
188
|
-
def
|
189
|
-
Log.log.debug('
|
190
|
-
|
191
|
-
|
192
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
196
|
-
|
197
|
-
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
206
|
-
|
207
|
-
@opt_mgr.add_opt_simple(:lock_port, 'prevent dual execution of a command, e.g. in cron')
|
208
|
-
@opt_mgr.add_opt_simple(:http_options, 'options for http socket (extended value)')
|
209
|
-
@opt_mgr.add_opt_boolean(:insecure, 'do not validate HTTPS certificate')
|
210
|
-
@opt_mgr.add_opt_boolean(:once_only, 'process only new items (some commands)')
|
211
|
-
@opt_mgr.add_opt_boolean(:log_secrets, 'show passwords in logs')
|
212
|
-
@opt_mgr.add_opt_boolean(:cache_tokens, 'save and reuse Oauth tokens')
|
213
|
-
@opt_mgr.set_option(:ui, OpenApplication.default_gui_mode)
|
214
|
-
@opt_mgr.set_option(:once_only, false)
|
142
|
+
def declare_global_options
|
143
|
+
Log.log.debug('declare_global_options')
|
144
|
+
options.declare(:help, 'Show this message', values: :none, short: 'h') { @option_help = true }
|
145
|
+
options.declare(:bash_comp, 'Generate bash completion for command', values: :none) { @bash_completion = true }
|
146
|
+
options.declare(:show_config, 'Display parameters used for the provided action', values: :none) { @option_show_config = true }
|
147
|
+
options.declare(:version, 'Display version', values: :none, short: 'v') { formatter.display_message(:data, Aspera::Cli::VERSION); Process.exit(0) } # rubocop:disable Style/Semicolon, Layout/LineLength
|
148
|
+
options.declare(:warnings, 'Check for language warnings', values: :none, short: 'w') { $VERBOSE = true }
|
149
|
+
options.declare(
|
150
|
+
:ui, 'Method to start browser',
|
151
|
+
values: OpenApplication.user_interfaces,
|
152
|
+
handler: {o: OpenApplication.instance, m: :url_method},
|
153
|
+
default: OpenApplication.default_gui_mode)
|
154
|
+
options.declare(:log_level, 'Log level', values: Log.levels, handler: {o: Log.instance, m: :level})
|
155
|
+
options.declare(:logger, 'Logging method', values: Log::LOG_TYPES, handler: {o: Log.instance, m: :logger_type})
|
156
|
+
options.declare(:lock_port, 'Prevent dual execution of a command, e.g. in cron', coerce: Integer, types: Integer)
|
157
|
+
options.declare(:once_only, 'Process only new items (some commands)', values: :bool, default: false)
|
158
|
+
options.declare(:log_secrets, 'Show passwords in logs', values: :bool, handler: {o: SecretHider, m: :log_secrets})
|
159
|
+
options.declare(:clean_temp, 'Cleanup temporary files on exit', values: :bool, handler: {o: TempFileManager.instance, m: :cleanup_on_exit})
|
160
|
+
options.declare(:pid_file, 'Write process identifier to file, delete on exit', types: String)
|
215
161
|
# parse declared options
|
216
|
-
|
162
|
+
options.parse_options!
|
217
163
|
end
|
218
164
|
|
219
165
|
# @return the plugin instance, based on name
|
220
166
|
# also loads the plugin options, and default values from conf file
|
221
167
|
# @param plugin_name_sym : symbol for plugin name
|
222
168
|
def get_plugin_instance_with_options(plugin_name_sym, env=nil)
|
223
|
-
env ||= @
|
169
|
+
env ||= @agents
|
224
170
|
Log.log.debug{"get_plugin_instance_with_options(#{plugin_name_sym})"}
|
225
|
-
require
|
171
|
+
require config.plugins[plugin_name_sym][:require_stanza]
|
226
172
|
# load default params only if no param already loaded before plugin instantiation
|
227
173
|
env[:config].add_plugin_default_preset(plugin_name_sym)
|
228
174
|
command_plugin = Plugins::Config.plugin_class(plugin_name_sym).new(env)
|
@@ -232,8 +178,8 @@ module Aspera
|
|
232
178
|
end
|
233
179
|
|
234
180
|
def generate_bash_completion
|
235
|
-
if
|
236
|
-
|
181
|
+
if options.get_next_argument('', expected: :multiple, mandatory: false).nil?
|
182
|
+
config.plugins.each_key{|p|puts p.to_s}
|
237
183
|
else
|
238
184
|
Log.log.warn('only first level completion so far')
|
239
185
|
end
|
@@ -243,19 +189,19 @@ module Aspera
|
|
243
189
|
def exit_with_usage(all_plugins)
|
244
190
|
Log.log.debug('exit_with_usage'.bg_red)
|
245
191
|
# display main plugin options
|
246
|
-
|
192
|
+
formatter.display_message(:error, options.parser)
|
247
193
|
if all_plugins
|
248
194
|
# list plugins that have a "require" field, i.e. all but main plugin
|
249
|
-
|
195
|
+
config.plugins.each_key do |plugin_name_sym|
|
250
196
|
next if plugin_name_sym.eql?(Plugins::Config::CONF_PLUGIN_SYM)
|
251
197
|
# override main option parser with a brand new, to avoid having global options
|
252
|
-
plugin_env = @
|
253
|
-
plugin_env[:
|
198
|
+
plugin_env = @agents.clone
|
199
|
+
plugin_env[:all_manuals] = true # force declaration of all options
|
254
200
|
plugin_env[:options] = Manager.new(PROGRAM_NAME)
|
255
201
|
plugin_env[:options].parser.banner = '' # remove default banner
|
256
202
|
get_plugin_instance_with_options(plugin_name_sym, plugin_env)
|
257
203
|
# display generated help for plugin options
|
258
|
-
|
204
|
+
formatter.display_message(:error, plugin_env[:options].parser.help)
|
259
205
|
end
|
260
206
|
end
|
261
207
|
Process.exit(0)
|
@@ -265,9 +211,9 @@ module Aspera
|
|
265
211
|
|
266
212
|
# early debug for parser
|
267
213
|
# Note: does not accept shortcuts
|
268
|
-
def early_debug_setup
|
214
|
+
def early_debug_setup
|
269
215
|
Aspera::Log.instance.program_name = PROGRAM_NAME
|
270
|
-
argv.each do |arg|
|
216
|
+
@argv.each do |arg|
|
271
217
|
case arg
|
272
218
|
when '--' then break
|
273
219
|
when /^--log-level=(.*)/ then Aspera::Log.instance.level = Regexp.last_match(1).to_sym
|
@@ -280,69 +226,78 @@ module Aspera
|
|
280
226
|
|
281
227
|
# this is the main function called by initial script just after constructor
|
282
228
|
def process_command_line
|
283
|
-
Log.log.debug('process_command_line')
|
284
229
|
# catch exception information , if any
|
285
230
|
exception_info = nil
|
286
|
-
# false if command shall not be executed (
|
231
|
+
# false if command shall not be executed (e.g. --show-config)
|
287
232
|
execute_command = true
|
233
|
+
# catch exceptions
|
288
234
|
begin
|
235
|
+
init_agents_and_options
|
289
236
|
# find plugins, shall be after parse! ?
|
290
|
-
|
237
|
+
config.add_plugins_from_lookup_folders
|
291
238
|
# help requested without command ? (plugins must be known here)
|
292
|
-
exit_with_usage(true) if @option_help &&
|
239
|
+
exit_with_usage(true) if @option_help && options.command_or_arg_empty?
|
293
240
|
generate_bash_completion if @bash_completion
|
294
|
-
|
241
|
+
config.periodic_check_newer_gem_version
|
295
242
|
command_sym =
|
296
|
-
if @option_show_config &&
|
243
|
+
if @option_show_config && options.command_or_arg_empty?
|
297
244
|
Plugins::Config::CONF_PLUGIN_SYM
|
298
245
|
else
|
299
|
-
|
246
|
+
options.get_next_command(config.plugins.keys.dup.unshift(:help))
|
300
247
|
end
|
301
248
|
# command will not be executed, but we need manual
|
302
|
-
|
249
|
+
options.fail_on_missing_mandatory = false if @option_help || @option_show_config
|
303
250
|
# main plugin is not dynamically instantiated
|
304
251
|
case command_sym
|
305
252
|
when :help
|
306
253
|
exit_with_usage(true)
|
307
254
|
when Plugins::Config::CONF_PLUGIN_SYM
|
308
|
-
command_plugin =
|
255
|
+
command_plugin = config
|
309
256
|
else
|
310
257
|
# get plugin, set options, etc
|
311
258
|
command_plugin = get_plugin_instance_with_options(command_sym)
|
312
259
|
# parse plugin specific options
|
313
|
-
|
260
|
+
options.parse_options!
|
314
261
|
end
|
315
262
|
# help requested for current plugin
|
316
263
|
exit_with_usage(false) if @option_help
|
317
264
|
if @option_show_config
|
318
|
-
|
265
|
+
formatter.display_results({type: :single_object, data: options.known_options(only_defined: true).stringify_keys})
|
319
266
|
execute_command = false
|
320
267
|
end
|
321
268
|
# locking for single execution (only after "per plugin" option, in case lock port is there)
|
322
|
-
lock_port =
|
269
|
+
lock_port = options.get_option(:lock_port)
|
323
270
|
if !lock_port.nil?
|
324
271
|
begin
|
325
272
|
# no need to close later, will be freed on process exit. must save in member else it is garbage collected
|
326
|
-
Log.log.debug{"Opening lock port #{lock_port
|
327
|
-
@tcp_server = TCPServer.new('127.0.0.1', lock_port
|
273
|
+
Log.log.debug{"Opening lock port #{lock_port}"}
|
274
|
+
@tcp_server = TCPServer.new('127.0.0.1', lock_port)
|
328
275
|
rescue StandardError => e
|
329
276
|
execute_command = false
|
330
277
|
Log.log.warn{"Another instance is already running (#{e.message})."}
|
331
278
|
end
|
332
279
|
end
|
280
|
+
pid_file = options.get_option(:pid_file)
|
281
|
+
if !pid_file.nil?
|
282
|
+
File.write(pid_file, Process.pid)
|
283
|
+
Log.log.debug{"Wrote pid #{Process.pid} to #{pid_file}"}
|
284
|
+
at_exit{File.delete(pid_file)}
|
285
|
+
end
|
333
286
|
# execute and display (if not exclusive execution)
|
334
|
-
|
287
|
+
formatter.display_results(command_plugin.execute_action) if execute_command
|
288
|
+
# save config file if command modified it
|
289
|
+
config.save_config_file_if_needed
|
335
290
|
# finish
|
336
|
-
|
291
|
+
transfer.shutdown
|
337
292
|
rescue Net::SSH::AuthenticationFailed => e; exception_info = {e: e, t: 'SSH', security: true}
|
338
293
|
rescue OpenSSL::SSL::SSLError => e; exception_info = {e: e, t: 'SSL'}
|
339
|
-
rescue
|
340
|
-
rescue
|
341
|
-
rescue
|
342
|
-
rescue Fasp::Error => e; exception_info = {e: e, t: '
|
294
|
+
rescue Cli::BadArgument => e; exception_info = {e: e, t: 'Argument', usage: true}
|
295
|
+
rescue Cli::NoSuchIdentifier => e; exception_info = {e: e, t: 'Identifier'}
|
296
|
+
rescue Cli::Error => e; exception_info = {e: e, t: 'Tool', usage: true}
|
297
|
+
rescue Fasp::Error => e; exception_info = {e: e, t: 'Transfer'}
|
343
298
|
rescue Aspera::RestCallError => e; exception_info = {e: e, t: 'Rest'}
|
344
299
|
rescue SocketError => e; exception_info = {e: e, t: 'Network'}
|
345
|
-
rescue StandardError => e; exception_info = {e: e, t:
|
300
|
+
rescue StandardError => e; exception_info = {e: e, t: "Other(#{e.class.name})", debug: true}
|
346
301
|
rescue Interrupt => e; exception_info = {e: e, t: 'Interruption', debug: true}
|
347
302
|
end
|
348
303
|
# cleanup file list files
|
@@ -350,22 +305,15 @@ module Aspera
|
|
350
305
|
# 1- processing of error condition
|
351
306
|
unless exception_info.nil?
|
352
307
|
Log.log.warn(exception_info[:e].message) if Aspera::Log.instance.logger_type.eql?(:syslog) && exception_info[:security]
|
353
|
-
|
354
|
-
|
355
|
-
#
|
356
|
-
|
357
|
-
@formatter.display_message(:error, "For this specific error, refer to:\n"\
|
358
|
-
"#{SRC_URL}#error-remote-host-is-not-who-we-expected\nAdd this to arguments:\n--ts=@json:'{\"sshfp\":null}'")
|
359
|
-
end
|
360
|
-
# Provide hint on SSL errors
|
361
|
-
if exception_info[:e].is_a?(OpenSSL::SSL::SSLError) && ['does not match the server certificate'].any?{|m|exception_info[:e].message.include?(m)}
|
362
|
-
@formatter.display_message(:error, "You can ignore SSL errors with option:\n--insecure=yes")
|
363
|
-
end
|
308
|
+
formatter.display_message(:error, "#{Formatter::ERROR_FLASH} #{exception_info[:t]}: #{exception_info[:e].message}")
|
309
|
+
formatter.display_message(:error, 'Use option -h to get help.') if exception_info[:usage]
|
310
|
+
# Is that a known error condition with proposal for remediation ?
|
311
|
+
Hints.hint_for(exception_info[:e], formatter)
|
364
312
|
end
|
365
313
|
# 2- processing of command not processed (due to exception or bad command line)
|
366
314
|
if execute_command || @option_show_config
|
367
|
-
|
368
|
-
|
315
|
+
options.final_errors.each do |msg|
|
316
|
+
formatter.display_message(:error, "#{Formatter::ERROR_FLASH} Argument: #{msg}")
|
369
317
|
# add code as exception if there is not already an error
|
370
318
|
exception_info = {e: Exception.new(msg), t: 'UnusedArg'} if exception_info.nil?
|
371
319
|
end
|
@@ -373,9 +321,9 @@ module Aspera
|
|
373
321
|
# 3- in case of error, fail the process status
|
374
322
|
unless exception_info.nil?
|
375
323
|
# show stack trace in debug mode
|
376
|
-
raise exception_info[:e] if Log.
|
324
|
+
raise exception_info[:e] if Log.log.debug?
|
377
325
|
# else give hint and exit
|
378
|
-
|
326
|
+
formatter.display_message(:error, 'Use --log-level=debug to get more details.') if exception_info[:debug]
|
379
327
|
Process.exit(1)
|
380
328
|
end
|
381
329
|
return nil
|