aspera-cli 4.24.1 → 4.25.0.pre
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 +1064 -745
- data/CONTRIBUTING.md +43 -100
- data/README.md +1281 -720
- data/bin/ascli +20 -1
- data/bin/asession +23 -27
- data/lib/aspera/agent/base.rb +10 -21
- data/lib/aspera/agent/connect.rb +2 -3
- data/lib/aspera/agent/desktop.rb +2 -2
- data/lib/aspera/agent/direct.rb +49 -32
- data/lib/aspera/agent/factory.rb +31 -0
- data/lib/aspera/api/aoc.rb +134 -76
- data/lib/aspera/api/cos_node.rb +3 -2
- data/lib/aspera/api/faspex.rb +213 -0
- data/lib/aspera/api/node.rb +107 -94
- data/lib/aspera/ascmd.rb +1 -2
- data/lib/aspera/ascp/installation.rb +73 -58
- data/lib/aspera/ascp/management.rb +119 -23
- data/lib/aspera/assert.rb +39 -11
- data/lib/aspera/cli/error.rb +4 -2
- data/lib/aspera/cli/extended_value.rb +91 -67
- data/lib/aspera/cli/formatter.rb +62 -27
- data/lib/aspera/cli/hints.rb +8 -0
- data/lib/aspera/cli/info.rb +4 -4
- data/lib/aspera/cli/main.rb +76 -84
- data/lib/aspera/cli/manager.rb +352 -248
- data/lib/aspera/cli/plugins/alee.rb +5 -4
- data/lib/aspera/cli/plugins/aoc.rb +175 -195
- data/lib/aspera/cli/plugins/ats.rb +4 -4
- data/lib/aspera/cli/plugins/base.rb +343 -0
- data/lib/aspera/cli/plugins/basic_auth.rb +45 -0
- data/lib/aspera/cli/plugins/config.rb +283 -269
- data/lib/aspera/cli/plugins/console.rb +27 -22
- data/lib/aspera/cli/plugins/cos.rb +3 -3
- data/lib/aspera/cli/plugins/factory.rb +78 -0
- data/lib/aspera/cli/plugins/faspex.rb +49 -46
- data/lib/aspera/cli/plugins/faspex5.rb +113 -225
- data/lib/aspera/cli/plugins/faspio.rb +19 -18
- data/lib/aspera/cli/plugins/httpgw.rb +14 -13
- data/lib/aspera/cli/plugins/node.rb +162 -149
- data/lib/aspera/cli/plugins/oauth.rb +48 -0
- data/lib/aspera/cli/plugins/orchestrator.rb +129 -45
- data/lib/aspera/cli/plugins/preview.rb +30 -50
- data/lib/aspera/cli/plugins/server.rb +21 -21
- data/lib/aspera/cli/plugins/shares.rb +45 -47
- data/lib/aspera/cli/sync_actions.rb +50 -39
- data/lib/aspera/cli/transfer_agent.rb +35 -49
- data/lib/aspera/cli/transfer_progress.rb +6 -6
- data/lib/aspera/cli/version.rb +3 -3
- data/lib/aspera/cli/wizard.rb +70 -55
- data/lib/aspera/colors.rb +6 -0
- data/lib/aspera/command_line_builder.rb +59 -61
- data/lib/aspera/command_line_converter.rb +2 -1
- data/lib/aspera/coverage.rb +2 -2
- data/lib/aspera/data_repository.rb +1 -1
- data/lib/aspera/environment.rb +51 -41
- data/lib/aspera/faspex_gw.rb +7 -5
- data/lib/aspera/faspex_postproc.rb +1 -1
- data/lib/aspera/keychain/factory.rb +1 -2
- data/lib/aspera/keychain/macos_security.rb +1 -1
- data/lib/aspera/log.rb +37 -9
- data/lib/aspera/markdown.rb +31 -0
- data/lib/aspera/nagios.rb +7 -6
- data/lib/aspera/oauth/base.rb +25 -28
- data/lib/aspera/oauth/factory.rb +9 -9
- data/lib/aspera/oauth/url_json.rb +2 -1
- data/lib/aspera/oauth/web.rb +2 -2
- data/lib/aspera/preview/file_types.rb +23 -37
- data/lib/aspera/products/connect.rb +7 -6
- data/lib/aspera/products/desktop.rb +1 -4
- data/lib/aspera/products/other.rb +9 -1
- data/lib/aspera/products/transferd.rb +0 -1
- data/lib/aspera/rest.rb +168 -113
- data/lib/aspera/rest_error_analyzer.rb +4 -4
- data/lib/aspera/ssh.rb +7 -4
- data/lib/aspera/ssl.rb +41 -0
- data/lib/aspera/sync/args.schema.yaml +46 -3
- data/lib/aspera/sync/conf.schema.yaml +307 -123
- data/lib/aspera/sync/database.rb +2 -1
- data/lib/aspera/sync/operations.rb +135 -79
- data/lib/aspera/temp_file_manager.rb +17 -5
- data/lib/aspera/transfer/error.rb +16 -7
- data/lib/aspera/transfer/parameters.rb +35 -22
- data/lib/aspera/transfer/resumer.rb +74 -0
- data/lib/aspera/transfer/spec.rb +5 -5
- data/lib/aspera/transfer/spec.schema.yaml +170 -59
- data/lib/aspera/transfer/spec_doc.rb +49 -43
- data/lib/aspera/uri_reader.rb +2 -2
- data/lib/aspera/web_auth.rb +6 -6
- data/lib/transferd_pb.rb +2 -2
- data.tar.gz.sig +0 -0
- metadata +26 -11
- metadata.gz.sig +0 -0
- data/lib/aspera/cli/basic_auth_plugin.rb +0 -43
- data/lib/aspera/cli/plugin.rb +0 -333
- data/lib/aspera/cli/plugin_factory.rb +0 -81
- data/lib/aspera/resumer.rb +0 -77
- data/lib/aspera/transfer/error_info.rb +0 -91
data/bin/ascli
CHANGED
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
#!/usr/bin/env ruby
|
|
2
2
|
# frozen_string_literal: true
|
|
3
3
|
|
|
4
|
+
# This is the main script to execute the Aspera CLI
|
|
5
|
+
|
|
4
6
|
old_verbose = $VERBOSE
|
|
5
7
|
$VERBOSE = nil
|
|
6
8
|
# internal representation of strings (ruby) is UTF-8
|
|
@@ -9,9 +11,26 @@ Encoding.default_internal = Encoding::UTF_8
|
|
|
9
11
|
Encoding.default_external = Encoding::UTF_8
|
|
10
12
|
$VERBOSE = old_verbose
|
|
11
13
|
|
|
14
|
+
require 'aspera/log'
|
|
15
|
+
require 'aspera/cli/info'
|
|
16
|
+
|
|
17
|
+
# Early debug for parser
|
|
18
|
+
# Note: does not accept short option names, nor extended values
|
|
19
|
+
Aspera::Log.instance.program_name = Aspera::Cli::Info::CMD_NAME
|
|
20
|
+
ARGV.each do |arg|
|
|
21
|
+
case arg
|
|
22
|
+
when '--' then break
|
|
23
|
+
when /^--log-level=(.*)/ then Aspera::Log.instance.level = Regexp.last_match(1).to_sym
|
|
24
|
+
when /^--log-format=(.*)/ then Aspera::Log.instance.formatter = Regexp.last_match(1) unless Regexp.last_match(1).start_with?('@ruby:')
|
|
25
|
+
when /^--logger=(.*)/ then Aspera::Log.instance.logger_type = Regexp.last_match(1).to_sym
|
|
26
|
+
end
|
|
27
|
+
rescue => e
|
|
28
|
+
$stderr.puts("Error: #{e}") # rubocop:disable Style/StderrPuts
|
|
29
|
+
Process.exit(1)
|
|
30
|
+
end
|
|
31
|
+
|
|
12
32
|
require 'aspera/coverage'
|
|
13
33
|
require 'aspera/environment'
|
|
14
34
|
require 'aspera/cli/main'
|
|
15
|
-
Aspera::Cli::Main.early_debug_setup(ARGV)
|
|
16
35
|
Aspera::Environment.instance.fix_home
|
|
17
36
|
Aspera::Cli::Main.new(ARGV).process_command_line
|
data/bin/asession
CHANGED
|
@@ -7,16 +7,16 @@ require 'aspera/cli/extended_value'
|
|
|
7
7
|
require 'aspera/products/transferd'
|
|
8
8
|
require 'aspera/log'
|
|
9
9
|
require 'json'
|
|
10
|
-
#
|
|
10
|
+
# Extended transfer spec parameter (only used in asession)
|
|
11
11
|
PARAM_SPEC = 'spec'
|
|
12
|
-
#
|
|
12
|
+
# Log level
|
|
13
13
|
PARAM_LOG_LEVEL = 'loglevel'
|
|
14
|
-
#
|
|
14
|
+
# Transfer agent options
|
|
15
15
|
PARAM_AGENT = 'agent'
|
|
16
|
-
#
|
|
16
|
+
# By default go to /tmp/username.filelist
|
|
17
17
|
PARAM_TMP_FILE_LIST_FOLDER = 'file_list_folder'
|
|
18
18
|
PARAM_SDK = 'sdk'
|
|
19
|
-
#
|
|
19
|
+
# Place transfer spec in that
|
|
20
20
|
SAMPLE_DEMO = '"remote_host":"demo.asperasoft.com","remote_user":"asperaweb","ssh_port":33001,"remote_password":"demoaspera"'
|
|
21
21
|
SAMPLE_DEMO2 = '"direction":"receive","destination_root":"./test.dir"'
|
|
22
22
|
def assert_usage(assertion, error_message)
|
|
@@ -52,27 +52,27 @@ def assert_usage(assertion, error_message)
|
|
|
52
52
|
Process.exit(0)
|
|
53
53
|
end
|
|
54
54
|
parameter_source_err_msg = ' (argument), did you specify: "@json:" ?'
|
|
55
|
-
#
|
|
55
|
+
# By default assume JSON input on stdin if no argument
|
|
56
56
|
if ARGV.empty?
|
|
57
57
|
ARGV.push('@json:@stdin')
|
|
58
58
|
parameter_source_err_msg = ' (JSON on stdin)'
|
|
59
59
|
end
|
|
60
|
-
#
|
|
60
|
+
# Anyway expect only one argument: session information
|
|
61
61
|
assert_usage(ARGV.length.eql?(1), 'exactly one argument is expected')
|
|
62
62
|
assert_usage(!['-h', '--help'].include?(ARGV.first), nil)
|
|
63
|
-
#
|
|
63
|
+
# Parse transfer spec
|
|
64
64
|
begin
|
|
65
65
|
session_argument = ARGV.pop
|
|
66
66
|
session_spec = Aspera::Cli::ExtendedValue.instance.evaluate(session_argument)
|
|
67
67
|
rescue
|
|
68
68
|
assert_usage(false, "Cannot parse argument: #{session_argument}")
|
|
69
69
|
end
|
|
70
|
-
#
|
|
70
|
+
# Ensure right type for parameter
|
|
71
71
|
assert_usage(session_spec.is_a?(Hash), "The value must be a Hash#{parameter_source_err_msg}")
|
|
72
72
|
assert_usage(session_spec[PARAM_SPEC].is_a?(Hash), "The value must contain key #{PARAM_SPEC} with Hash value")
|
|
73
|
-
#
|
|
74
|
-
Aspera::Log.instance.level = session_spec[PARAM_LOG_LEVEL] if session_spec.key?(PARAM_LOG_LEVEL)
|
|
75
|
-
#
|
|
73
|
+
# Additional debug capability
|
|
74
|
+
Aspera::Log.instance.level = session_spec[PARAM_LOG_LEVEL].to_sym if session_spec.key?(PARAM_LOG_LEVEL)
|
|
75
|
+
# Possibly override temp folder
|
|
76
76
|
Aspera::Transfer::Parameters.file_list_folder = session_spec[PARAM_TMP_FILE_LIST_FOLDER] if session_spec.key?(PARAM_TMP_FILE_LIST_FOLDER)
|
|
77
77
|
session_spec[PARAM_SDK] = File.join(Dir.home, '.aspera', 'sdk') unless session_spec.key?(PARAM_SDK)
|
|
78
78
|
Aspera::Products::Transferd.sdk_directory = session_spec[PARAM_SDK]
|
|
@@ -80,25 +80,21 @@ session_spec[PARAM_AGENT] = {} unless session_spec.key?(PARAM_AGENT)
|
|
|
80
80
|
agent_params = session_spec[PARAM_AGENT]
|
|
81
81
|
agent_params['quiet'] = true
|
|
82
82
|
agent_params['management_cb'] = ->(event) do
|
|
83
|
-
puts JSON.generate(Aspera::Ascp::Management.
|
|
83
|
+
puts JSON.generate(Aspera::Ascp::Management.event_native_to_snake(event))
|
|
84
84
|
end
|
|
85
|
-
#
|
|
85
|
+
# Get local agent (ascp), disable ascp output on stdout to not mix with JSON events
|
|
86
86
|
client = Aspera::Agent::Direct.new(**agent_params.symbolize_keys)
|
|
87
|
-
#
|
|
88
|
-
|
|
89
|
-
#
|
|
87
|
+
# Start transfer (asynchronous)
|
|
88
|
+
client.start_transfer(session_spec[PARAM_SPEC])
|
|
89
|
+
# commands to ascp on mgt port
|
|
90
90
|
Thread.new do
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
loop do
|
|
95
|
-
data = JSON.parse($stdin.gets)
|
|
96
|
-
client.send_command(session_id, data)
|
|
97
|
-
end
|
|
98
|
-
rescue
|
|
99
|
-
Process.exit(1)
|
|
91
|
+
loop do
|
|
92
|
+
data = JSON.parse($stdin.gets)
|
|
93
|
+
client.send_command(data)
|
|
100
94
|
end
|
|
95
|
+
rescue
|
|
96
|
+
Process.exit(1)
|
|
101
97
|
end
|
|
102
|
-
#
|
|
98
|
+
# No exit code: status is success (0)
|
|
103
99
|
client.wait_for_transfers_completion
|
|
104
100
|
client.shutdown
|
data/lib/aspera/agent/base.rb
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require 'aspera/log'
|
|
4
3
|
require 'aspera/assert'
|
|
5
4
|
module Aspera
|
|
6
5
|
module Agent
|
|
@@ -10,25 +9,6 @@ module Aspera
|
|
|
10
9
|
# - `wait_for_transfers_completion` : waits for all transfer sessions to finish
|
|
11
10
|
# - `notify_progress` : called back by transfer agent to notify transfer progress
|
|
12
11
|
class Base
|
|
13
|
-
RUBY_EXT = '.rb'
|
|
14
|
-
private_constant :RUBY_EXT
|
|
15
|
-
class << self
|
|
16
|
-
def factory_create(agent, options)
|
|
17
|
-
# Aspera.assert_values(agent, agent_list)
|
|
18
|
-
require "aspera/agent/#{agent}"
|
|
19
|
-
Aspera::Agent.const_get(agent.to_s.capitalize).new(**options)
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
# discover available agents
|
|
23
|
-
# @return [Array] list of symbols of agents
|
|
24
|
-
def agent_list
|
|
25
|
-
base_class = File.basename(__FILE__)
|
|
26
|
-
Dir.entries(File.dirname(File.expand_path(__FILE__))).select do |file|
|
|
27
|
-
file.end_with?(RUBY_EXT) && !file.eql?(base_class)
|
|
28
|
-
end.map{ |file| file[0..(-1 - RUBY_EXT.length)].to_sym}
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
|
|
32
12
|
# Wait for all sessions to terminate and return the status of each session
|
|
33
13
|
def wait_for_completion
|
|
34
14
|
# list of: :success or "error message string"
|
|
@@ -48,8 +28,17 @@ module Aspera
|
|
|
48
28
|
nil
|
|
49
29
|
end
|
|
50
30
|
|
|
51
|
-
|
|
31
|
+
attr_reader :config_dir
|
|
32
|
+
|
|
33
|
+
# Base transfer agent object
|
|
34
|
+
# @param progress [Object] Progress bar
|
|
35
|
+
# @param config_dir [String] Config folder
|
|
36
|
+
def initialize(
|
|
37
|
+
progress: nil,
|
|
38
|
+
config_dir: nil
|
|
39
|
+
)
|
|
52
40
|
@progress = progress
|
|
41
|
+
@config_dir = config_dir
|
|
53
42
|
end
|
|
54
43
|
|
|
55
44
|
def notify_progress(*pos_args, **kw_args)
|
data/lib/aspera/agent/connect.rb
CHANGED
|
@@ -24,6 +24,7 @@ module Aspera
|
|
|
24
24
|
raise Error, 'Using connect requires a graphical environment' unless Environment.instance.graphical?
|
|
25
25
|
method_index = 0
|
|
26
26
|
begin
|
|
27
|
+
# raise exception if connect not started and file does not exist
|
|
27
28
|
connect_url = connect_api_url
|
|
28
29
|
Log.log.debug{"found: #{connect_url}"}
|
|
29
30
|
@connect_api = Rest.new(
|
|
@@ -135,9 +136,7 @@ module Aspera
|
|
|
135
136
|
|
|
136
137
|
# @return the file path of local connect where API's URI can be read
|
|
137
138
|
def connect_api_url
|
|
138
|
-
|
|
139
|
-
raise "Product: #{name} not found, please install." if connect_locations.nil?
|
|
140
|
-
folder = File.join(connect_locations[:run_root], 'var', 'run')
|
|
139
|
+
folder = File.join(Products::Other.find(Products::Connect.locations).first[:run_root], 'var', 'run')
|
|
141
140
|
['', 's'].each do |ext|
|
|
142
141
|
uri_file = File.join(folder, "http#{ext}.uri")
|
|
143
142
|
Log.log.debug{"checking connect port file: #{uri_file}"}
|
data/lib/aspera/agent/desktop.rb
CHANGED
|
@@ -102,7 +102,7 @@ module Aspera
|
|
|
102
102
|
|
|
103
103
|
# @return [String] the url where transferd is listening
|
|
104
104
|
def aspera_client_api_url
|
|
105
|
-
log_file = Products::Desktop.
|
|
105
|
+
log_file = File.join(Products::Other.find(Products::Desktop.locations).first[:log_root], Products::Desktop::LOG_FILENAME)
|
|
106
106
|
url = 'http://127.0.0.1:33024'
|
|
107
107
|
File.open(log_file, 'r') do |file|
|
|
108
108
|
file.each_line do |line|
|
|
@@ -111,7 +111,7 @@ module Aspera
|
|
|
111
111
|
url = "http://#{m[1]}"
|
|
112
112
|
end
|
|
113
113
|
end
|
|
114
|
-
end
|
|
114
|
+
end if File.exist?(log_file)
|
|
115
115
|
# raise StandardError, "Unable to find the JSON-RPC server URL in #{log_file}" if url.nil?
|
|
116
116
|
return url
|
|
117
117
|
end
|
data/lib/aspera/agent/direct.rb
CHANGED
|
@@ -6,7 +6,7 @@ require 'aspera/ascp/management'
|
|
|
6
6
|
require 'aspera/transfer/parameters'
|
|
7
7
|
require 'aspera/transfer/error'
|
|
8
8
|
require 'aspera/transfer/spec'
|
|
9
|
-
require 'aspera/resumer'
|
|
9
|
+
require 'aspera/transfer/resumer'
|
|
10
10
|
require 'aspera/log'
|
|
11
11
|
require 'aspera/assert'
|
|
12
12
|
require 'socket'
|
|
@@ -24,18 +24,18 @@ module Aspera
|
|
|
24
24
|
SELECT_AVAILABLE_PORT = 0
|
|
25
25
|
private_constant :LISTEN_LOCAL_ADDRESS, :SELECT_AVAILABLE_PORT
|
|
26
26
|
|
|
27
|
-
#
|
|
28
|
-
# @param ascp_args [Array]
|
|
29
|
-
# @param wss [Boolean] true
|
|
30
|
-
# @param quiet [Boolean]
|
|
31
|
-
# @param monitor [Boolean]
|
|
32
|
-
# @param trusted_certs [Array
|
|
33
|
-
# @param client_ssh_key [String]
|
|
34
|
-
# @param check_ignore_cb [Proc]
|
|
35
|
-
# @param spawn_timeout_sec [Integer]
|
|
36
|
-
# @param spawn_delay_sec [Integer]
|
|
37
|
-
# @param multi_incr_udp [Boolean
|
|
38
|
-
# @param resume [Hash
|
|
27
|
+
# Options: same as values in option `transfer_info`
|
|
28
|
+
# @param ascp_args [Array] (Params) Optional Additional arguments to ascp
|
|
29
|
+
# @param wss [Boolean] (Params) `true`: if both SSH and wss in ts: prefer wss
|
|
30
|
+
# @param quiet [Boolean] (Params) By default no native `ascp` progress bar
|
|
31
|
+
# @param monitor [Boolean] (Params) Set to `false` to eliminate management port
|
|
32
|
+
# @param trusted_certs [Array] (Params) Optional list of files with trusted certificates (stores)
|
|
33
|
+
# @param client_ssh_key [String] (Params) Client SSH key option (from CLIENT_SSH_KEY_OPTIONS)
|
|
34
|
+
# @param check_ignore_cb [Proc] (Params) Callback with host,port
|
|
35
|
+
# @param spawn_timeout_sec [Integer] Timeout for ascp spawn
|
|
36
|
+
# @param spawn_delay_sec [Integer] Optional delay to start between sessions
|
|
37
|
+
# @param multi_incr_udp [Boolean] Optional `true`: increment UDP port for each session
|
|
38
|
+
# @param resume [Hash] Optional Resume policy
|
|
39
39
|
# @param management_cb [Proc] callback for management events
|
|
40
40
|
# @param base_options [Hash] other options for base class
|
|
41
41
|
def initialize(
|
|
@@ -54,7 +54,7 @@ module Aspera
|
|
|
54
54
|
**base_options
|
|
55
55
|
)
|
|
56
56
|
super(**base_options)
|
|
57
|
-
#
|
|
57
|
+
# Special transfer parameters provided
|
|
58
58
|
@tr_opts = {
|
|
59
59
|
ascp_args: ascp_args,
|
|
60
60
|
wss: wss,
|
|
@@ -69,19 +69,22 @@ module Aspera
|
|
|
69
69
|
@multi_incr_udp = multi_incr_udp.nil? ? Environment.instance.os.eql?(Environment::OS_WINDOWS) : multi_incr_udp
|
|
70
70
|
@monitor = monitor
|
|
71
71
|
@management_cb = management_cb
|
|
72
|
-
|
|
72
|
+
resume = {} if resume.nil?
|
|
73
|
+
Aspera.assert_type(resume, Hash){'resume'}
|
|
74
|
+
@resume_policy = Transfer::Resumer.new(**resume.symbolize_keys)
|
|
73
75
|
# all transfer jobs, key = SecureRandom.uuid, protected by mutex, cond var on change
|
|
74
76
|
@sessions = []
|
|
75
77
|
# mutex protects global data accessed by threads
|
|
76
78
|
@mutex = Mutex.new
|
|
77
79
|
@pre_calc_sent = false
|
|
78
80
|
@pre_calc_last_size = nil
|
|
81
|
+
@command_file = File.join(config_dir || '.', "send_#{$PROCESS_ID}")
|
|
79
82
|
end
|
|
80
83
|
|
|
81
|
-
#
|
|
82
|
-
#
|
|
83
|
-
# @param transfer_spec
|
|
84
|
-
# @param token_regenerator [Object]
|
|
84
|
+
# Start `ascp` transfer(s) (non blocking), single or multi-session
|
|
85
|
+
# Session information added to @sessions
|
|
86
|
+
# @param transfer_spec [Hash] Aspera transfer specification
|
|
87
|
+
# @param token_regenerator [Object] Object with method refreshed_transfer_token
|
|
85
88
|
def start_transfer(transfer_spec, token_regenerator: nil)
|
|
86
89
|
# clone transfer spec because we modify it (first level keys)
|
|
87
90
|
transfer_spec = transfer_spec.clone
|
|
@@ -188,16 +191,23 @@ module Aspera
|
|
|
188
191
|
@sessions.select{ |session| session[:job_id].eql?(job_id)}
|
|
189
192
|
end
|
|
190
193
|
|
|
191
|
-
#
|
|
192
|
-
#
|
|
193
|
-
# @param session_index index of session (for multi session)
|
|
194
|
-
# @param data command on mgt port, examples:
|
|
194
|
+
# Send command to management port of command (used in `asession).
|
|
195
|
+
# Examples:
|
|
195
196
|
# {'type'=>'START','source'=>_path_,'destination'=>_path_}
|
|
196
197
|
# {'type'=>'DONE'}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
198
|
+
# @param data [Hash] Command on mgt port
|
|
199
|
+
# @param id [String] Optional identifier or transfer session
|
|
200
|
+
def send_command(data, id: nil)
|
|
201
|
+
Log.dump(:command, data)
|
|
202
|
+
sessions = id ? @sessions.select{ |session| session[:job_id].eql?(id)} : @sessions
|
|
203
|
+
if sessions.empty?
|
|
204
|
+
Log.log.warn('No transfer session')
|
|
205
|
+
return
|
|
206
|
+
end
|
|
207
|
+
message = Ascp::Management.command_to_stream(data)
|
|
208
|
+
sessions.each do |session|
|
|
209
|
+
session[:io].puts(message)
|
|
210
|
+
end
|
|
201
211
|
end
|
|
202
212
|
|
|
203
213
|
private
|
|
@@ -301,6 +311,14 @@ module Aspera
|
|
|
301
311
|
session[:id] = event['SessionId'] if event['Type'].eql?('INIT')
|
|
302
312
|
@management_cb&.call(event)
|
|
303
313
|
process_progress(event)
|
|
314
|
+
next unless File.exist?(@command_file)
|
|
315
|
+
begin
|
|
316
|
+
commands = JSON.parse(File.read(@command_file))
|
|
317
|
+
send_command(commands)
|
|
318
|
+
rescue => e
|
|
319
|
+
Log.log.error{e.to_s}
|
|
320
|
+
end
|
|
321
|
+
File.delete(@command_file)
|
|
304
322
|
end
|
|
305
323
|
Log.log.debug('management io closed')
|
|
306
324
|
# check that last status was received before process exit
|
|
@@ -317,7 +335,7 @@ module Aspera
|
|
|
317
335
|
Log.log.warn('Regenerating token for transfer')
|
|
318
336
|
env['ASPERA_SCP_TOKEN'] = session[:token_regenerator].refreshed_transfer_token
|
|
319
337
|
end
|
|
320
|
-
raise Transfer::Error.new(last_event['Description'], last_event['Code'].to_i)
|
|
338
|
+
raise Transfer::Error.new(last_event['Description'], code: last_event['Code'].to_i)
|
|
321
339
|
else Aspera.error_unexpected_value(last_event['Type'], :error){'last event type'}
|
|
322
340
|
end
|
|
323
341
|
rescue SystemCallError => e
|
|
@@ -347,7 +365,7 @@ module Aspera
|
|
|
347
365
|
# status is nil if an exception occurred before starting command
|
|
348
366
|
if !status&.success?
|
|
349
367
|
message = "#{name} failed (#{status})"
|
|
350
|
-
# raise error only if there was not already an exception (ERROR_INFO)
|
|
368
|
+
# raise error only if there was not already an exception (`$ERROR_INFO`)
|
|
351
369
|
raise Transfer::Error, message unless $ERROR_INFO
|
|
352
370
|
# else display this message also, as main exception is already here
|
|
353
371
|
Log.log.error(message)
|
|
@@ -361,9 +379,8 @@ module Aspera
|
|
|
361
379
|
|
|
362
380
|
attr_reader :sessions
|
|
363
381
|
|
|
364
|
-
#
|
|
365
|
-
# @param event management port event
|
|
366
|
-
# @param session sessin object
|
|
382
|
+
# Notify progress to callback
|
|
383
|
+
# @param event [Hash] management port event
|
|
367
384
|
def process_progress(event)
|
|
368
385
|
session_id = event['SessionId']
|
|
369
386
|
case event['Type']
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'singleton'
|
|
4
|
+
require 'aspera/log'
|
|
5
|
+
require 'aspera/environment'
|
|
6
|
+
module Aspera
|
|
7
|
+
module Agent
|
|
8
|
+
# Factory for Agents
|
|
9
|
+
class Factory
|
|
10
|
+
include Singleton
|
|
11
|
+
|
|
12
|
+
# Create new agent
|
|
13
|
+
def create(agent, options)
|
|
14
|
+
Log.dump(:options, options)
|
|
15
|
+
require "aspera/agent/#{agent}"
|
|
16
|
+
Aspera::Agent.const_get(agent.to_s.capitalize).new(**options)
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Discover available agents
|
|
20
|
+
# @return [Array] list of symbols of agents
|
|
21
|
+
def list
|
|
22
|
+
Dir.children(File.dirname(File.expand_path(__FILE__)))
|
|
23
|
+
.select{ |file| file.end_with?(Environment::RB_EXT)}
|
|
24
|
+
.map{ |file| File.basename(file, Environment::RB_EXT).to_sym}
|
|
25
|
+
.reject{ |item| IGNORED_ITEMS.include?(item)}
|
|
26
|
+
end
|
|
27
|
+
IGNORED_ITEMS = %i[factory base]
|
|
28
|
+
private_constant :IGNORED_ITEMS
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
end
|