aspera-cli 4.4.0 → 4.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +2095 -1503
- data/bin/ascli +2 -1
- data/bin/asession +4 -5
- data/docs/test_env.conf +3 -0
- data/examples/aoc.rb +4 -3
- data/examples/faspex4.rb +25 -25
- data/examples/proxy.pac +1 -1
- data/examples/transfer.rb +17 -17
- data/lib/aspera/aoc.rb +238 -185
- data/lib/aspera/ascmd.rb +93 -83
- data/lib/aspera/ats_api.rb +11 -10
- data/lib/aspera/cli/basic_auth_plugin.rb +13 -14
- data/lib/aspera/cli/extended_value.rb +42 -33
- data/lib/aspera/cli/formater.rb +142 -108
- data/lib/aspera/cli/info.rb +17 -0
- data/lib/aspera/cli/listener/line_dump.rb +3 -2
- data/lib/aspera/cli/listener/logger.rb +2 -1
- data/lib/aspera/cli/listener/progress.rb +16 -18
- data/lib/aspera/cli/listener/progress_multi.rb +18 -21
- data/lib/aspera/cli/main.rb +173 -149
- data/lib/aspera/cli/manager.rb +163 -168
- data/lib/aspera/cli/plugin.rb +43 -31
- data/lib/aspera/cli/plugins/alee.rb +6 -6
- data/lib/aspera/cli/plugins/aoc.rb +405 -370
- data/lib/aspera/cli/plugins/ats.rb +86 -79
- data/lib/aspera/cli/plugins/bss.rb +14 -16
- data/lib/aspera/cli/plugins/config.rb +580 -362
- data/lib/aspera/cli/plugins/console.rb +23 -19
- data/lib/aspera/cli/plugins/cos.rb +18 -18
- data/lib/aspera/cli/plugins/faspex.rb +201 -158
- data/lib/aspera/cli/plugins/faspex5.rb +80 -57
- data/lib/aspera/cli/plugins/node.rb +183 -166
- data/lib/aspera/cli/plugins/orchestrator.rb +71 -67
- data/lib/aspera/cli/plugins/preview.rb +92 -96
- data/lib/aspera/cli/plugins/server.rb +79 -75
- data/lib/aspera/cli/plugins/shares.rb +35 -19
- data/lib/aspera/cli/plugins/sync.rb +20 -22
- data/lib/aspera/cli/transfer_agent.rb +76 -113
- data/lib/aspera/cli/version.rb +2 -1
- data/lib/aspera/colors.rb +35 -27
- data/lib/aspera/command_line_builder.rb +48 -34
- data/lib/aspera/cos_node.rb +29 -21
- data/lib/aspera/data_repository.rb +3 -2
- data/lib/aspera/environment.rb +50 -45
- data/lib/aspera/fasp/{manager.rb → agent_base.rb} +28 -25
- data/lib/aspera/fasp/{connect.rb → agent_connect.rb} +52 -43
- data/lib/aspera/fasp/{local.rb → agent_direct.rb} +58 -72
- data/lib/aspera/fasp/{http_gw.rb → agent_httpgw.rb} +37 -43
- data/lib/aspera/fasp/{node.rb → agent_node.rb} +35 -16
- data/lib/aspera/fasp/agent_trsdk.rb +104 -0
- data/lib/aspera/fasp/error.rb +2 -1
- data/lib/aspera/fasp/error_info.rb +68 -52
- data/lib/aspera/fasp/installation.rb +152 -124
- data/lib/aspera/fasp/listener.rb +1 -0
- data/lib/aspera/fasp/parameters.rb +87 -92
- data/lib/aspera/fasp/parameters.yaml +305 -249
- data/lib/aspera/fasp/resume_policy.rb +11 -14
- data/lib/aspera/fasp/transfer_spec.rb +26 -0
- data/lib/aspera/fasp/uri.rb +22 -21
- data/lib/aspera/faspex_gw.rb +55 -89
- data/lib/aspera/hash_ext.rb +4 -3
- data/lib/aspera/id_generator.rb +8 -7
- data/lib/aspera/keychain/encrypted_hash.rb +121 -0
- data/lib/aspera/keychain/macos_security.rb +90 -0
- data/lib/aspera/log.rb +55 -37
- data/lib/aspera/nagios.rb +13 -12
- data/lib/aspera/node.rb +30 -25
- data/lib/aspera/oauth.rb +175 -226
- data/lib/aspera/open_application.rb +4 -3
- data/lib/aspera/persistency_action_once.rb +6 -6
- data/lib/aspera/persistency_folder.rb +5 -9
- data/lib/aspera/preview/file_types.rb +6 -5
- data/lib/aspera/preview/generator.rb +25 -24
- data/lib/aspera/preview/options.rb +16 -14
- data/lib/aspera/preview/utils.rb +98 -98
- data/lib/aspera/{proxy_auto_config.erb.js → proxy_auto_config.js} +23 -31
- data/lib/aspera/proxy_auto_config.rb +111 -20
- data/lib/aspera/rest.rb +154 -135
- data/lib/aspera/rest_call_error.rb +2 -2
- data/lib/aspera/rest_error_analyzer.rb +23 -25
- data/lib/aspera/rest_errors_aspera.rb +15 -14
- data/lib/aspera/ssh.rb +12 -10
- data/lib/aspera/sync.rb +42 -41
- data/lib/aspera/temp_file_manager.rb +18 -14
- data/lib/aspera/timer_limiter.rb +2 -1
- data/lib/aspera/uri_reader.rb +7 -5
- data/lib/aspera/web_auth.rb +79 -76
- metadata +116 -29
- data/docs/Makefile +0 -66
- data/docs/README.erb.md +0 -3973
- data/docs/README.md +0 -13
- data/docs/diagrams.txt +0 -49
- data/docs/doc_tools.rb +0 -58
- data/lib/aspera/api_detector.rb +0 -60
- data/lib/aspera/cli/plugins/shares2.rb +0 -114
- data/lib/aspera/secrets.rb +0 -20
data/lib/aspera/cli/main.rb
CHANGED
@@ -1,119 +1,179 @@
|
|
1
|
+
# frozen_string_literal: true
|
1
2
|
require 'aspera/cli/manager'
|
2
3
|
require 'aspera/cli/formater'
|
3
4
|
require 'aspera/cli/plugins/config'
|
4
5
|
require 'aspera/cli/extended_value'
|
5
6
|
require 'aspera/cli/transfer_agent'
|
6
7
|
require 'aspera/cli/version'
|
8
|
+
require 'aspera/cli/info'
|
9
|
+
require 'aspera/fasp/error'
|
7
10
|
require 'aspera/open_application'
|
8
11
|
require 'aspera/temp_file_manager'
|
9
12
|
require 'aspera/persistency_folder'
|
10
13
|
require 'aspera/log'
|
11
14
|
require 'aspera/rest'
|
12
15
|
require 'aspera/nagios'
|
13
|
-
require 'aspera/
|
16
|
+
require 'aspera/colors'
|
14
17
|
|
15
18
|
module Aspera
|
16
19
|
module Cli
|
17
20
|
# The main CLI class
|
18
21
|
class Main
|
22
|
+
# prefix to display error messages
|
23
|
+
ERROR_FLASH='ERROR:'.bg_red.gray.blink.freeze
|
24
|
+
private_constant :ERROR_FLASH
|
19
25
|
|
20
|
-
|
21
|
-
private
|
22
|
-
# name of application, also foldername where config is stored
|
23
|
-
PROGRAM_NAME = 'ascli'
|
24
|
-
# name of the containing gem, same as in <gem name>.gemspec
|
25
|
-
GEM_NAME = 'aspera-cli'
|
26
|
-
HELP_URL = "http://www.rubydoc.info/gems/#{GEM_NAME}"
|
27
|
-
GEM_URL = "https://rubygems.org/gems/#{GEM_NAME}"
|
28
|
-
SRC_URL = "https://github.com/IBM/aspera-cli"
|
26
|
+
# store transfer result using this key and use result_transfer_multiple
|
29
27
|
STATUS_FIELD = 'status'
|
30
28
|
|
31
|
-
|
29
|
+
class << self
|
30
|
+
# expect some list, but nothing to display
|
31
|
+
def result_empty; return {type: :empty, data: :nil}; end
|
32
|
+
|
33
|
+
# nothing expected
|
34
|
+
def result_nothing; return {type: :nothing, data: :nil}; end
|
35
|
+
|
36
|
+
def result_status(status); return {type: :status, data: status}; end
|
37
|
+
|
38
|
+
def result_success; return result_status('complete'); end
|
39
|
+
|
40
|
+
# Process statuses of finished transfer sessions
|
41
|
+
# raise exception if there is one error
|
42
|
+
# else returns an empty status
|
43
|
+
def result_transfer(statuses)
|
44
|
+
worst=TransferAgent.session_status(statuses)
|
45
|
+
raise worst unless worst.eql?(:success)
|
46
|
+
return Main.result_nothing
|
47
|
+
end
|
48
|
+
|
49
|
+
# used when one command executes several transfer jobs (each job being possibly multi session)
|
50
|
+
# @param status_table [Array] [{STATUS_FIELD=>[status array],...},...]
|
51
|
+
# @return a status object suitable as command result
|
52
|
+
# each element has a key STATUS_FIELD which contains the result of possibly multiple sessions
|
53
|
+
def result_transfer_multiple(status_table)
|
54
|
+
global_status=:success
|
55
|
+
# transform status array into string and find if there was problem
|
56
|
+
status_table.each do |item|
|
57
|
+
worst=TransferAgent.session_status(item[STATUS_FIELD])
|
58
|
+
global_status=worst unless worst.eql?(:success)
|
59
|
+
item[STATUS_FIELD]=item[STATUS_FIELD].map(&:to_s).join(',')
|
60
|
+
end
|
61
|
+
raise global_status unless global_status.eql?(:success)
|
62
|
+
return {type: :object_list,data: status_table}
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
private
|
67
|
+
|
32
68
|
# =============================================================
|
33
69
|
# Parameter handlers
|
34
70
|
#
|
35
|
-
|
36
|
-
|
37
|
-
def option_insecure=(value); Rest.insecure = value; end
|
71
|
+
attr_accessor :option_insecure, :option_http_options, :option_cache_tokens
|
38
72
|
|
39
73
|
def option_ui; OpenApplication.instance.url_method; end
|
40
74
|
|
41
75
|
def option_ui=(value); OpenApplication.instance.url_method=value; end
|
42
76
|
|
77
|
+
# called everytime a new REST HTTP session is opened
|
78
|
+
# @param http [Net::HTTP] the newly created http session object
|
79
|
+
def http_parameters=(http)
|
80
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE if @option_insecure
|
81
|
+
http.set_debug_output($stdout) if @option_rest_debug
|
82
|
+
raise 'http_options expects Hash' unless @option_http_options.is_a?(Hash)
|
83
|
+
|
84
|
+
@option_http_options.each do |k,v|
|
85
|
+
method="#{k}=".to_sym
|
86
|
+
# check if accessor is a method of Net::HTTP
|
87
|
+
# continue_timeout= read_timeout= write_timeout=
|
88
|
+
if http.respond_to?(method)
|
89
|
+
http.send(method,v)
|
90
|
+
else
|
91
|
+
Log.log.error("no such attribute: #{k}")
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
43
96
|
# minimum initialization
|
44
97
|
def initialize(argv)
|
45
98
|
# first thing : manage debug level (allows debugging of option parser)
|
46
99
|
early_debug_setup(argv)
|
47
100
|
# compare $0 with expected name
|
48
101
|
current_prog_name=File.basename($PROGRAM_NAME)
|
49
|
-
unless current_prog_name.eql?(PROGRAM_NAME)
|
50
|
-
@plugin_env[:formater].display_message(:error,"#{"WARNING".bg_red.blink.gray} Please use '#{PROGRAM_NAME}' instead of '#{current_prog_name}', '#{current_prog_name}' will be removed in a future version")
|
51
|
-
end
|
102
|
+
@plugin_env[:formater].display_message(:error,"#{'WARNING'.bg_red.blink.gray} Please use '#{PROGRAM_NAME}' instead of '#{current_prog_name}'") unless current_prog_name.eql?(PROGRAM_NAME)
|
52
103
|
@option_help=false
|
53
104
|
@bash_completion=false
|
54
105
|
@option_show_config=false
|
106
|
+
@option_insecure=false
|
107
|
+
@option_rest_debug=false
|
108
|
+
@option_cache_tokens=true
|
109
|
+
@option_http_options={}
|
55
110
|
# environment provided to plugin for various capabilities
|
56
111
|
@plugin_env={}
|
57
|
-
#
|
58
|
-
|
59
|
-
#
|
60
|
-
if app_main_folder.nil? or app_main_folder.empty?
|
61
|
-
user_home_folder=Dir.home
|
62
|
-
raise CliError,"Home folder does not exist: #{user_home_folder}. Check your user environment or use #{conf_dir_env_var}." unless Dir.exist?(user_home_folder)
|
63
|
-
app_main_folder=File.join(user_home_folder,Plugins::Config::ASPERA_HOME_FOLDER_NAME,PROGRAM_NAME)
|
64
|
-
end
|
65
|
-
# give command line arguments to option manager (no parsing)
|
66
|
-
@plugin_env[:options]=@opt_mgr=Manager.new(PROGRAM_NAME,argv,app_banner())
|
112
|
+
# give command line arguments to option manager
|
113
|
+
@plugin_env[:options]=@opt_mgr=Manager.new(PROGRAM_NAME,argv)
|
114
|
+
# formatter adds options
|
67
115
|
@plugin_env[:formater]=Formater.new(@plugin_env[:options])
|
68
116
|
Rest.user_agent=PROGRAM_NAME
|
117
|
+
Rest.session_cb=lambda{|http|self.http_parameters=http}
|
69
118
|
# declare and parse global options
|
70
119
|
init_global_options()
|
71
|
-
#
|
72
|
-
@plugin_env[:
|
73
|
-
# the Config plugin adds the @preset parser
|
74
|
-
@plugin_env[:config]=Plugins::Config.new(@plugin_env,PROGRAM_NAME,HELP_URL,Aspera::Cli::VERSION,app_main_folder)
|
120
|
+
# the Config plugin adds the @preset parser, so declare before TransferAgent which may use it
|
121
|
+
@plugin_env[:config]=Plugins::Config.new(@plugin_env, gem: GEM_NAME, name: PROGRAM_NAME, help: DOC_URL, version: Aspera::Cli::VERSION)
|
75
122
|
# the TransferAgent plugin may use the @preset parser
|
76
|
-
@plugin_env[:transfer]=TransferAgent.new(@plugin_env)
|
77
|
-
#
|
123
|
+
@plugin_env[:transfer]=TransferAgent.new(@plugin_env[:options],@plugin_env[:config])
|
124
|
+
# data persistency
|
78
125
|
@plugin_env[:persistency]=PersistencyFolder.new(File.join(@plugin_env[:config].main_folder,'persist_store'))
|
79
126
|
Log.log.debug('plugin env created'.red)
|
80
|
-
Oauth.persist_mgr=@plugin_env[:persistency]
|
127
|
+
Oauth.persist_mgr=@plugin_env[:persistency] if @option_cache_tokens
|
81
128
|
Fasp::Parameters.file_list_folder=File.join(@plugin_env[:config].main_folder,'filelists')
|
82
129
|
Aspera::RestErrorAnalyzer.instance.log_file=File.join(@plugin_env[:config].main_folder,'rest_exceptions.log')
|
83
130
|
# register aspera REST call error handlers
|
84
|
-
Aspera::RestErrorsAspera.
|
131
|
+
Aspera::RestErrorsAspera.register_handlers
|
132
|
+
# set banner when all environment is created so that additional extended value modifiers are known, e.g. @preset
|
133
|
+
@opt_mgr.parser.banner=app_banner
|
85
134
|
end
|
86
135
|
|
87
136
|
def app_banner
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
137
|
+
return <<~END_OF_BANNER
|
138
|
+
NAME
|
139
|
+
\t#{PROGRAM_NAME} -- a command line tool for Aspera Applications (v#{Aspera::Cli::VERSION})
|
140
|
+
|
141
|
+
SYNOPSIS
|
142
|
+
\t#{PROGRAM_NAME} COMMANDS [OPTIONS] [ARGS]
|
143
|
+
|
144
|
+
DESCRIPTION
|
145
|
+
\tUse Aspera application to perform operations on command line.
|
146
|
+
\tDocumentation and examples: #{GEM_URL}
|
147
|
+
\texecute: #{PROGRAM_NAME} conf doc
|
148
|
+
\tor visit: #{DOC_URL}
|
149
|
+
\tsource repo: #{SRC_URL}
|
150
|
+
|
151
|
+
ENVIRONMENT VARIABLES
|
152
|
+
\t#{@plugin_env[:config].conf_dir_env_var} config folder, default: $HOME/#{Plugins::Config::ASPERA_HOME_FOLDER_NAME}/#{PROGRAM_NAME}
|
153
|
+
\tAny option can be set as an environment variable, refer to the manual
|
154
|
+
|
155
|
+
COMMANDS
|
156
|
+
\tTo list first level commands, execute: #{PROGRAM_NAME}
|
157
|
+
\tNote that commands can be written shortened (provided it is unique).
|
158
|
+
|
159
|
+
OPTIONS
|
160
|
+
\tOptions begin with a '-' (minus), and value is provided on command line.
|
161
|
+
\tSpecial values are supported beginning with special prefix @pfx:, where pfx is one of:
|
162
|
+
\t#{ExtendedValue.instance.modifiers.map(&:to_s).join(', ')}
|
163
|
+
\tDates format is 'DD-MM-YY HH:MM:SS', or 'now' or '-<num>h'
|
164
|
+
|
165
|
+
ARGS
|
166
|
+
\tSome commands require mandatory arguments, e.g. a path.
|
167
|
+
END_OF_BANNER
|
108
168
|
end
|
109
169
|
|
110
170
|
# define header for manual
|
111
171
|
def init_global_options
|
112
|
-
Log.log.debug(
|
113
|
-
@opt_mgr.add_opt_switch(:help,
|
114
|
-
@opt_mgr.add_opt_switch(:bash_comp,
|
115
|
-
@opt_mgr.add_opt_switch(:show_config,
|
116
|
-
@opt_mgr.add_opt_switch(:rest_debug,
|
172
|
+
Log.log.debug('init_global_options')
|
173
|
+
@opt_mgr.add_opt_switch(:help,'-h','Show this message.') { @option_help=true }
|
174
|
+
@opt_mgr.add_opt_switch(:bash_comp,'generate bash completion for command') { @bash_completion=true }
|
175
|
+
@opt_mgr.add_opt_switch(:show_config, 'Display parameters used for the provided action.') { @option_show_config=true }
|
176
|
+
@opt_mgr.add_opt_switch(:rest_debug,'-r','more debug for HTTP calls') { @option_rest_debug=true }
|
117
177
|
@opt_mgr.add_opt_switch(:version,'-v','display version') { @plugin_env[:formater].display_message(:data,Aspera::Cli::VERSION);Process.exit(0) }
|
118
178
|
@opt_mgr.add_opt_switch(:warnings,'-w','check for language warnings') { $VERBOSE=true }
|
119
179
|
# handler must be set before declaration
|
@@ -121,15 +181,21 @@ module Aspera
|
|
121
181
|
@opt_mgr.set_obj_attr(:logger,Log.instance,:logger_type)
|
122
182
|
@opt_mgr.set_obj_attr(:insecure,self,:option_insecure,:no)
|
123
183
|
@opt_mgr.set_obj_attr(:ui,self,:option_ui)
|
184
|
+
@opt_mgr.set_obj_attr(:http_options,self,:option_http_options)
|
185
|
+
@opt_mgr.set_obj_attr(:log_secrets,Log.instance,:log_secrets)
|
186
|
+
@opt_mgr.set_obj_attr(:cache_tokens,self,:option_cache_tokens)
|
124
187
|
@opt_mgr.add_opt_list(:ui,OpenApplication.user_interfaces,'method to start browser')
|
125
|
-
@opt_mgr.add_opt_list(:log_level,Log.levels,
|
126
|
-
@opt_mgr.add_opt_list(:logger,Log.logtypes,
|
127
|
-
@opt_mgr.add_opt_simple(:lock_port,
|
128
|
-
@opt_mgr.add_opt_simple(:query,
|
129
|
-
@opt_mgr.
|
130
|
-
@opt_mgr.add_opt_boolean(:
|
188
|
+
@opt_mgr.add_opt_list(:log_level,Log.levels,'Log level')
|
189
|
+
@opt_mgr.add_opt_list(:logger,Log.logtypes,'log method')
|
190
|
+
@opt_mgr.add_opt_simple(:lock_port,'prevent dual execution of a command, e.g. in cron')
|
191
|
+
@opt_mgr.add_opt_simple(:query,'additional filter for API calls (extended value) (some commands)')
|
192
|
+
@opt_mgr.add_opt_simple(:http_options,'options for http socket (extended value)')
|
193
|
+
@opt_mgr.add_opt_boolean(:insecure,'do not validate HTTPS certificate')
|
194
|
+
@opt_mgr.add_opt_boolean(:once_only,'process only new items (some commands)')
|
195
|
+
@opt_mgr.add_opt_boolean(:log_secrets,'show passwords in logs')
|
196
|
+
@opt_mgr.add_opt_boolean(:cache_tokens,'save and reuse Oauth tokens')
|
131
197
|
@opt_mgr.set_option(:ui,OpenApplication.default_gui_mode)
|
132
|
-
@opt_mgr.set_option(:once_only
|
198
|
+
@opt_mgr.set_option(:once_only,false)
|
133
199
|
# parse declared options
|
134
200
|
@opt_mgr.parse_options!
|
135
201
|
end
|
@@ -143,33 +209,23 @@ module Aspera
|
|
143
209
|
require @plugin_env[:config].plugins[plugin_name_sym][:require_stanza]
|
144
210
|
# load default params only if no param already loaded before plugin instanciation
|
145
211
|
env[:config].add_plugin_default_preset(plugin_name_sym)
|
146
|
-
command_plugin=Plugins::Config.
|
212
|
+
command_plugin=Plugins::Config.plugin_class(plugin_name_sym).new(env)
|
147
213
|
Log.log.debug("got #{command_plugin.class}")
|
148
214
|
# TODO: check that ancestor is Plugin?
|
149
215
|
return command_plugin
|
150
216
|
end
|
151
217
|
|
152
218
|
def generate_bash_completion
|
153
|
-
if @opt_mgr.get_next_argument(
|
219
|
+
if @opt_mgr.get_next_argument('',:multiple,:optional).nil?
|
154
220
|
@plugin_env[:config].plugins.keys.each{|p|puts p.to_s}
|
155
221
|
else
|
156
|
-
Log.log.warn(
|
222
|
+
Log.log.warn('only first level completion so far')
|
157
223
|
end
|
158
224
|
Process.exit(0)
|
159
225
|
end
|
160
226
|
|
161
|
-
# expect some list, but nothing to display
|
162
|
-
def self.result_empty; return {:type => :empty, :data => :nil }; end
|
163
|
-
|
164
|
-
# nothing expected
|
165
|
-
def self.result_nothing; return {:type => :nothing, :data => :nil }; end
|
166
|
-
|
167
|
-
def self.result_status(status); return {:type => :status, :data => status }; end
|
168
|
-
|
169
|
-
def self.result_success; return result_status('complete'); end
|
170
|
-
|
171
227
|
def exit_with_usage(all_plugins)
|
172
|
-
Log.log.debug(
|
228
|
+
Log.log.debug('exit_with_usage'.bg_red)
|
173
229
|
# display main plugin options
|
174
230
|
@plugin_env[:formater].display_message(:error,@opt_mgr.parser)
|
175
231
|
if all_plugins
|
@@ -179,10 +235,11 @@ module Aspera
|
|
179
235
|
# override main option parser with a brand new, to avoid having global options
|
180
236
|
plugin_env=@plugin_env.clone
|
181
237
|
plugin_env[:man_only]=true
|
182
|
-
plugin_env[:options]=Manager.new(PROGRAM_NAME
|
238
|
+
plugin_env[:options]=Manager.new(PROGRAM_NAME)
|
239
|
+
plugin_env[:options].parser.banner='' # remove default banner
|
183
240
|
get_plugin_instance_with_options(plugin_name_sym,plugin_env)
|
184
241
|
# display generated help for plugin options
|
185
|
-
@plugin_env[:formater].display_message(:error,plugin_env[:options].parser.
|
242
|
+
@plugin_env[:formater].display_message(:error,plugin_env[:options].parser.help)
|
186
243
|
end
|
187
244
|
end
|
188
245
|
Process.exit(0)
|
@@ -190,54 +247,21 @@ module Aspera
|
|
190
247
|
|
191
248
|
protected
|
192
249
|
|
193
|
-
# env var name to override the app's main folder
|
194
|
-
# default main folder is $HOME/<vendor main app folder>/<program name>
|
195
|
-
def conf_dir_env_var
|
196
|
-
return "#{PROGRAM_NAME}_home".upcase
|
197
|
-
end
|
198
|
-
|
199
250
|
# early debug for parser
|
200
251
|
# Note: does not accept shortcuts
|
201
252
|
def early_debug_setup(argv)
|
202
253
|
Log.instance.program_name=PROGRAM_NAME
|
203
254
|
argv.each do |arg|
|
204
255
|
case arg
|
205
|
-
when '--'
|
206
|
-
|
207
|
-
when /^--
|
208
|
-
Log.instance.level = $1.to_sym
|
209
|
-
when /^--logger=(.*)/
|
210
|
-
Log.instance.logger_type=$1.to_sym
|
256
|
+
when '--' then break
|
257
|
+
when /^--log-level=(.*)/ then Log.instance.level = Regexp.last_match(1).to_sym
|
258
|
+
when /^--logger=(.*)/ then Log.instance.logger_type=Regexp.last_match(1).to_sym
|
211
259
|
end
|
212
260
|
end
|
213
261
|
end
|
214
262
|
|
215
263
|
public
|
216
264
|
|
217
|
-
# Process statuses of finished transfer sessions
|
218
|
-
# raise exception if there is one error
|
219
|
-
# else returns an empty status
|
220
|
-
def self.result_transfer(statuses)
|
221
|
-
worst=TransferAgent.session_status(statuses)
|
222
|
-
raise worst unless worst.eql?(:success)
|
223
|
-
return Main.result_nothing
|
224
|
-
end
|
225
|
-
|
226
|
-
# used when one command executes several transfer jobs (each job being possibly multi session)
|
227
|
-
# @param status_table [Array] [{STATUS_FIELD=>[status array],...},...]
|
228
|
-
# each element has a key STATUS_FIELD which contains the result of possibly mulmtiple sessions
|
229
|
-
def self.result_transfer_multiple(status_table)
|
230
|
-
global_status=:success
|
231
|
-
# transform status into string and find if there was problem
|
232
|
-
status_table.each do |item|
|
233
|
-
worst=TransferAgent.session_status(item[STATUS_FIELD])
|
234
|
-
global_status=worst unless worst.eql?(:success)
|
235
|
-
item[STATUS_FIELD]=item[STATUS_FIELD].map{|i|i.to_s}.join(',')
|
236
|
-
end
|
237
|
-
raise global_status unless global_status.eql?(:success)
|
238
|
-
return {:type=>:object_list,:data=>status_table}
|
239
|
-
end
|
240
|
-
|
241
265
|
# this is the main function called by initial script just after constructor
|
242
266
|
def process_command_line
|
243
267
|
Log.log.debug('process_command_line')
|
@@ -249,17 +273,17 @@ module Aspera
|
|
249
273
|
# find plugins, shall be after parse! ?
|
250
274
|
@plugin_env[:config].add_plugins_from_lookup_folders
|
251
275
|
# help requested without command ? (plugins must be known here)
|
252
|
-
exit_with_usage(true) if @option_help
|
276
|
+
exit_with_usage(true) if @option_help && @opt_mgr.command_or_arg_empty?
|
253
277
|
generate_bash_completion if @bash_completion
|
254
|
-
# load global default options and process
|
255
|
-
@plugin_env[:config].add_plugin_default_preset(Plugins::Config::CONF_GLOBAL_SYM)
|
256
|
-
@opt_mgr.parse_options!
|
257
278
|
@plugin_env[:config].periodic_check_newer_gem_version
|
258
|
-
|
259
|
-
|
279
|
+
command_sym=
|
280
|
+
if @option_show_config && @opt_mgr.command_or_arg_empty?
|
281
|
+
Plugins::Config::CONF_PLUGIN_SYM
|
260
282
|
else
|
261
|
-
|
283
|
+
@opt_mgr.get_next_command(@plugin_env[:config].plugins.keys.dup.unshift(:help))
|
262
284
|
end
|
285
|
+
# command will not be executed, but we need manual
|
286
|
+
@opt_mgr.fail_on_missing_mandatory=false if @option_help || @option_show_config
|
263
287
|
# main plugin is not dynamically instanciated
|
264
288
|
case command_sym
|
265
289
|
when :help
|
@@ -275,8 +299,8 @@ module Aspera
|
|
275
299
|
# help requested for current plugin
|
276
300
|
exit_with_usage(false) if @option_help
|
277
301
|
if @option_show_config
|
278
|
-
@plugin_env[:formater].display_results({:
|
279
|
-
|
302
|
+
@plugin_env[:formater].display_results({type: :single_object,data: @opt_mgr.declared_options(only_defined: true)})
|
303
|
+
execute_command=false
|
280
304
|
end
|
281
305
|
# locking for single execution (only after "per plugin" option, in case lock port is there)
|
282
306
|
lock_port=@opt_mgr.get_option(:lock_port,:optional)
|
@@ -285,7 +309,7 @@ module Aspera
|
|
285
309
|
# no need to close later, will be freed on process exit. must save in member else it is garbage collected
|
286
310
|
Log.log.debug("Opening lock port #{lock_port.to_i}")
|
287
311
|
@tcp_server=TCPServer.new('127.0.0.1',lock_port.to_i)
|
288
|
-
rescue => e
|
312
|
+
rescue StandardError => e
|
289
313
|
execute_command=false
|
290
314
|
Log.log.warn("Another instance is already running (#{e.message}).")
|
291
315
|
end
|
@@ -294,40 +318,40 @@ module Aspera
|
|
294
318
|
@plugin_env[:formater].display_results(command_plugin.execute_action) if execute_command
|
295
319
|
# finish
|
296
320
|
@plugin_env[:transfer].shutdown
|
297
|
-
rescue CliBadArgument => e; exception_info=
|
298
|
-
rescue CliNoSuchId => e; exception_info=
|
299
|
-
rescue CliError => e; exception_info=
|
300
|
-
rescue Fasp::Error => e; exception_info=
|
301
|
-
rescue Aspera::RestCallError => e; exception_info=
|
302
|
-
rescue SocketError => e; exception_info=
|
303
|
-
rescue StandardError => e; exception_info=
|
304
|
-
rescue Interrupt => e; exception_info=
|
321
|
+
rescue CliBadArgument => e; exception_info={e: e,t: 'Argument',usage: true}
|
322
|
+
rescue CliNoSuchId => e; exception_info={e: e,t: 'Identifier'}
|
323
|
+
rescue CliError => e; exception_info={e: e,t: 'Tool',usage: true}
|
324
|
+
rescue Fasp::Error => e; exception_info={e: e,t: 'FASP(ascp)'}
|
325
|
+
rescue Aspera::RestCallError => e; exception_info={e: e,t: 'Rest'}
|
326
|
+
rescue SocketError => e; exception_info={e: e,t: 'Network'}
|
327
|
+
rescue StandardError => e; exception_info={e: e,t: 'Other',debug: true}
|
328
|
+
rescue Interrupt => e; exception_info={e: e,t: 'Interruption',debug: true}
|
305
329
|
end
|
306
330
|
# cleanup file list files
|
307
331
|
TempFileManager.instance.cleanup
|
308
332
|
# 1- processing of error condition
|
309
333
|
unless exception_info.nil?
|
310
|
-
@plugin_env[:formater].display_message(:error,"
|
311
|
-
@plugin_env[:formater].display_message(:error,
|
312
|
-
if exception_info.
|
334
|
+
@plugin_env[:formater].display_message(:error,"#{ERROR_FLASH} #{exception_info[:t]}: #{exception_info[:e].message}")
|
335
|
+
@plugin_env[:formater].display_message(:error,'Use option -h to get help.') if exception_info[:usage]
|
336
|
+
if exception_info[:e].is_a?(Fasp::Error) && exception_info[:e].message.eql?('Remote host is not who we expected')
|
313
337
|
@plugin_env[:formater].display_message(:error,"For this specific error, refer to:\n#{SRC_URL}#error-remote-host-is-not-who-we-expected\nAdd this to arguments:\n--ts=@json:'{\"sshfp\":null}'")
|
314
338
|
end
|
315
339
|
end
|
316
340
|
# 2- processing of command not processed (due to exception or bad command line)
|
317
|
-
if execute_command
|
341
|
+
if execute_command || @option_show_config
|
318
342
|
@opt_mgr.final_errors.each do |msg|
|
319
|
-
@plugin_env[:formater].display_message(:error,"
|
343
|
+
@plugin_env[:formater].display_message(:error,"#{ERROR_FLASH} Argument: #{msg}")
|
344
|
+
# add code as exception if there is not already an error
|
345
|
+
exception_info={e: Exception.new(msg),t: 'UnusedArg'} if exception_info.nil?
|
320
346
|
end
|
321
347
|
end
|
322
348
|
# 3- in case of error, fail the process status
|
323
349
|
unless exception_info.nil?
|
324
|
-
|
325
|
-
|
326
|
-
|
327
|
-
|
328
|
-
|
329
|
-
Process.exit(1)
|
330
|
-
end
|
350
|
+
# show stack trace in debug mode
|
351
|
+
raise exception_info[:e] if Log.instance.level.eql?(:debug)
|
352
|
+
# else give hint and exit
|
353
|
+
@plugin_env[:formater].display_message(:error,'Use --log-level=debug to get more details.') if exception_info[:debug]
|
354
|
+
Process.exit(1)
|
331
355
|
end
|
332
356
|
return nil
|
333
357
|
end # process_command_line
|