aspera-cli 4.14.0 → 4.16.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/BUGS.md +29 -3
- data/CHANGELOG.md +300 -185
- data/CONTRIBUTING.md +74 -23
- data/README.md +2346 -1619
- data/bin/ascli +16 -25
- data/bin/asession +15 -15
- data/examples/dascli +2 -2
- data/examples/proxy.pac +1 -1
- data/lib/aspera/aoc.rb +216 -150
- data/lib/aspera/ascmd.rb +25 -18
- data/lib/aspera/assert.rb +45 -0
- data/lib/aspera/cli/basic_auth_plugin.rb +9 -6
- data/lib/aspera/cli/error.rb +17 -0
- data/lib/aspera/cli/extended_value.rb +51 -16
- data/lib/aspera/cli/formatter.rb +276 -174
- data/lib/aspera/cli/hints.rb +81 -0
- data/lib/aspera/cli/main.rb +114 -147
- data/lib/aspera/cli/manager.rb +181 -136
- data/lib/aspera/cli/plugin.rb +82 -64
- data/lib/aspera/cli/plugins/alee.rb +0 -1
- data/lib/aspera/cli/plugins/aoc.rb +327 -331
- data/lib/aspera/cli/plugins/ats.rb +12 -8
- data/lib/aspera/cli/plugins/bss.rb +2 -2
- data/lib/aspera/cli/plugins/config.rb +575 -439
- data/lib/aspera/cli/plugins/console.rb +40 -0
- data/lib/aspera/cli/plugins/cos.rb +4 -5
- data/lib/aspera/cli/plugins/faspex.rb +111 -92
- data/lib/aspera/cli/plugins/faspex5.rb +245 -182
- data/lib/aspera/cli/plugins/node.rb +239 -160
- data/lib/aspera/cli/plugins/orchestrator.rb +56 -19
- data/lib/aspera/cli/plugins/preview.rb +54 -38
- data/lib/aspera/cli/plugins/server.rb +63 -20
- data/lib/aspera/cli/plugins/shares.rb +64 -38
- data/lib/aspera/cli/sync_actions.rb +68 -0
- data/lib/aspera/cli/transfer_agent.rb +64 -67
- data/lib/aspera/cli/transfer_progress.rb +73 -0
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/colors.rb +3 -1
- data/lib/aspera/command_line_builder.rb +27 -22
- data/lib/aspera/cos_node.rb +6 -4
- data/lib/aspera/coverage.rb +22 -0
- data/lib/aspera/data_repository.rb +33 -2
- data/lib/aspera/environment.rb +21 -8
- data/lib/aspera/fasp/agent_alpha.rb +116 -0
- data/lib/aspera/fasp/agent_base.rb +40 -76
- data/lib/aspera/fasp/agent_connect.rb +21 -22
- data/lib/aspera/fasp/agent_direct.rb +169 -179
- data/lib/aspera/fasp/agent_httpgw.rb +200 -195
- data/lib/aspera/fasp/agent_node.rb +43 -35
- data/lib/aspera/fasp/agent_trsdk.rb +124 -41
- data/lib/aspera/fasp/error_info.rb +2 -2
- data/lib/aspera/fasp/faux_file.rb +52 -0
- data/lib/aspera/fasp/installation.rb +89 -191
- data/lib/aspera/fasp/management.rb +249 -0
- data/lib/aspera/fasp/parameters.rb +86 -47
- data/lib/aspera/fasp/parameters.yaml +75 -8
- data/lib/aspera/fasp/products.rb +162 -0
- data/lib/aspera/fasp/resume_policy.rb +7 -5
- data/lib/aspera/fasp/sync.rb +273 -0
- data/lib/aspera/fasp/transfer_spec.rb +10 -8
- data/lib/aspera/fasp/uri.rb +6 -6
- data/lib/aspera/faspex_gw.rb +11 -8
- data/lib/aspera/faspex_postproc.rb +8 -7
- data/lib/aspera/hash_ext.rb +2 -2
- data/lib/aspera/id_generator.rb +3 -1
- data/lib/aspera/json_rpc.rb +51 -0
- data/lib/aspera/keychain/encrypted_hash.rb +46 -11
- data/lib/aspera/keychain/macos_security.rb +15 -13
- data/lib/aspera/line_logger.rb +23 -0
- data/lib/aspera/log.rb +61 -19
- data/lib/aspera/nagios.rb +7 -2
- data/lib/aspera/node.rb +105 -21
- data/lib/aspera/node_simulator.rb +214 -0
- data/lib/aspera/oauth.rb +57 -36
- data/lib/aspera/open_application.rb +4 -4
- data/lib/aspera/persistency_action_once.rb +13 -14
- data/lib/aspera/persistency_folder.rb +5 -4
- data/lib/aspera/preview/file_types.rb +56 -268
- data/lib/aspera/preview/generator.rb +28 -39
- data/lib/aspera/preview/options.rb +2 -0
- data/lib/aspera/preview/terminal.rb +36 -16
- data/lib/aspera/preview/utils.rb +23 -29
- data/lib/aspera/proxy_auto_config.rb +6 -3
- data/lib/aspera/rest.rb +127 -80
- data/lib/aspera/rest_call_error.rb +1 -1
- data/lib/aspera/rest_error_analyzer.rb +16 -14
- data/lib/aspera/rest_errors_aspera.rb +39 -34
- data/lib/aspera/secret_hider.rb +18 -17
- data/lib/aspera/ssh.rb +10 -5
- data/lib/aspera/temp_file_manager.rb +11 -4
- data/lib/aspera/web_auth.rb +10 -7
- data/lib/aspera/web_server_simple.rb +11 -5
- data.tar.gz.sig +0 -0
- metadata +108 -39
- metadata.gz.sig +0 -0
- 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/fasp/listener.rb +0 -13
- data/lib/aspera/sync.rb +0 -213
@@ -1,22 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'aspera/fasp/listener'
|
4
|
-
require 'aspera/log'
|
5
|
-
|
6
|
-
module Aspera
|
7
|
-
module Cli
|
8
|
-
module Listener
|
9
|
-
# listener for FASP transfers (debug)
|
10
|
-
class Logger < Aspera::Fasp::Listener
|
11
|
-
def event_struct(data)
|
12
|
-
Log.log.debug(data.to_s)
|
13
|
-
Log.log.error((data['Description']).to_s) if data['Type'].eql?('FILEERROR')
|
14
|
-
end
|
15
|
-
|
16
|
-
def event_enhanced(data)
|
17
|
-
Log.log.debug(JSON.generate(data))
|
18
|
-
end
|
19
|
-
end
|
20
|
-
end
|
21
|
-
end
|
22
|
-
end
|
@@ -1,50 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'aspera/fasp/listener'
|
4
|
-
require 'aspera/environment'
|
5
|
-
require 'ruby-progressbar'
|
6
|
-
|
7
|
-
module Aspera
|
8
|
-
module Cli
|
9
|
-
module Listener
|
10
|
-
# a listener to FASP event that displays a progress bar
|
11
|
-
class Progress < Aspera::Fasp::Listener
|
12
|
-
def initialize
|
13
|
-
super
|
14
|
-
@progress = nil
|
15
|
-
@cumulative = 0
|
16
|
-
end
|
17
|
-
|
18
|
-
def event_struct(data)
|
19
|
-
case data['Type']
|
20
|
-
when 'NOTIFICATION'
|
21
|
-
if data.key?('PreTransferBytes')
|
22
|
-
@progress = ProgressBar.create(
|
23
|
-
format: '%a %B %p%% %r Mbps %e',
|
24
|
-
rate_scale: lambda{|rate|rate / Environment::BYTES_PER_MEBIBIT},
|
25
|
-
title: 'progress',
|
26
|
-
total: data['PreTransferBytes'].to_i)
|
27
|
-
end
|
28
|
-
when 'STOP'
|
29
|
-
# stop event when one file is completed
|
30
|
-
@cumulative += data['Size'].to_i
|
31
|
-
when 'STATS'
|
32
|
-
if @progress.nil?
|
33
|
-
puts '.'
|
34
|
-
else
|
35
|
-
@progress.progress = data.key?('Bytescont') ? @cumulative + data['Bytescont'].to_i : data['TransferBytes'].to_i
|
36
|
-
end
|
37
|
-
when 'DONE'
|
38
|
-
if @progress.nil?
|
39
|
-
# terminate progress by going to next line
|
40
|
-
puts "\n"
|
41
|
-
else
|
42
|
-
@progress.progress = @progress.total
|
43
|
-
@progress = nil
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|
47
|
-
end
|
48
|
-
end
|
49
|
-
end
|
50
|
-
end
|
@@ -1,84 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'aspera/fasp/listener'
|
4
|
-
require 'aspera/fasp/agent_base'
|
5
|
-
require 'aspera/environment'
|
6
|
-
require 'ruby-progressbar'
|
7
|
-
|
8
|
-
module Aspera
|
9
|
-
module Cli
|
10
|
-
module Listener
|
11
|
-
# a listener to FASP event that displays a progress bar
|
12
|
-
class ProgressMulti < Aspera::Fasp::Listener
|
13
|
-
def initialize
|
14
|
-
super
|
15
|
-
@progress_bar = nil
|
16
|
-
@sessions = {}
|
17
|
-
end
|
18
|
-
|
19
|
-
def reset
|
20
|
-
@progress_bar = nil
|
21
|
-
@sessions = {}
|
22
|
-
end
|
23
|
-
|
24
|
-
def update_total
|
25
|
-
@progress_bar.total = @sessions.values.inject(0){|m, s|m + s[:job_size].to_i}
|
26
|
-
rescue StandardError
|
27
|
-
nil
|
28
|
-
end
|
29
|
-
|
30
|
-
def update_progress
|
31
|
-
@progress_bar.progress = @sessions.values.inject(0){|m, s|m + s[:current].to_i}
|
32
|
-
rescue StandardError
|
33
|
-
nil
|
34
|
-
end
|
35
|
-
|
36
|
-
def event_enhanced(data)
|
37
|
-
if @progress_bar.nil?
|
38
|
-
@progress_bar = ProgressBar.create(
|
39
|
-
format: '%t %a %B %p%% %r Mbps %e',
|
40
|
-
rate_scale: lambda{|rate|rate / Environment::BYTES_PER_MEBIBIT},
|
41
|
-
title: '',
|
42
|
-
total: nil)
|
43
|
-
end
|
44
|
-
if !data.key?(Fasp::AgentBase::LISTENER_SESSION_ID_S)
|
45
|
-
Log.log.error{"Internal error: no #{Fasp::AgentBase::LISTENER_SESSION_ID_S} in event: #{data}"}
|
46
|
-
return
|
47
|
-
end
|
48
|
-
new_title = @sessions.length < 2 ? '' : "multi=#{@sessions.length}"
|
49
|
-
@progress_bar.title = new_title unless @progress_bar.title.eql?(new_title)
|
50
|
-
session = @sessions[data[Fasp::AgentBase::LISTENER_SESSION_ID_S]] ||= {
|
51
|
-
cumulative: 0,
|
52
|
-
job_size: 0,
|
53
|
-
current: 0
|
54
|
-
}
|
55
|
-
case data['type']
|
56
|
-
when 'INIT' # connection to ascp (get id)
|
57
|
-
when 'SESSION' # session information
|
58
|
-
when 'NOTIFICATION' # sent from remote
|
59
|
-
if data.key?('pre_transfer_bytes')
|
60
|
-
session[:job_size] = data['pre_transfer_bytes']
|
61
|
-
update_total
|
62
|
-
end
|
63
|
-
when 'STATS' # during transfer
|
64
|
-
if @progress_bar.total.nil?
|
65
|
-
@progress_bar.increment
|
66
|
-
else
|
67
|
-
session[:current] = data.key?('bytescont') ? session[:cumulative] + data['bytescont'].to_i : data['transfer_bytes'].to_i
|
68
|
-
update_progress
|
69
|
-
end
|
70
|
-
when 'STOP'
|
71
|
-
# stop event when one file is completed
|
72
|
-
session[:cumulative] = session[:cumulative] + data['size'].to_i
|
73
|
-
when 'DONE' # end of session
|
74
|
-
@sessions.delete(data[Fasp::AgentBase::LISTENER_SESSION_ID_S])
|
75
|
-
update_progress
|
76
|
-
update_total
|
77
|
-
else
|
78
|
-
Log.log.debug{"ignore: #{data['type']}"}
|
79
|
-
end
|
80
|
-
end
|
81
|
-
end
|
82
|
-
end
|
83
|
-
end
|
84
|
-
end
|
@@ -1,44 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'English'
|
4
|
-
require 'aspera/cli/plugin'
|
5
|
-
require 'aspera/sync'
|
6
|
-
require 'aspera/log'
|
7
|
-
require 'open3'
|
8
|
-
|
9
|
-
module Aspera
|
10
|
-
module Cli
|
11
|
-
module Plugins
|
12
|
-
# Execute Aspera Sync
|
13
|
-
class Sync < Aspera::Cli::Plugin
|
14
|
-
def initialize(env, sync_spec: nil)
|
15
|
-
super(env)
|
16
|
-
options.declare(:sync_info, 'Information for sync instance and sessions', types: Hash)
|
17
|
-
options.declare(:sync_session, 'Name of session to use for admin commands. default: first in parameters')
|
18
|
-
options.parse_options!
|
19
|
-
return if env[:man_only]
|
20
|
-
@params = options.get_option(:sync_info, mandatory: true)
|
21
|
-
@sync_spec = sync_spec
|
22
|
-
end
|
23
|
-
|
24
|
-
ACTIONS = %i[start admin].freeze
|
25
|
-
|
26
|
-
def execute_action
|
27
|
-
command = options.get_next_command(ACTIONS)
|
28
|
-
case command
|
29
|
-
when :start
|
30
|
-
Aspera::Sync.new(@params, @sync_spec).start
|
31
|
-
return Main.result_success
|
32
|
-
when :admin
|
33
|
-
sync_admin = Aspera::SyncAdmin.new(@params, options.get_option(:sync_session))
|
34
|
-
command2 = options.get_next_command([:status])
|
35
|
-
case command2
|
36
|
-
when :status
|
37
|
-
return {type: :single_object, data: sync_admin.status}
|
38
|
-
end # command2
|
39
|
-
end # command
|
40
|
-
end # execute_action
|
41
|
-
end # Sync
|
42
|
-
end # Plugins
|
43
|
-
end # Cli
|
44
|
-
end # Aspera
|
data/lib/aspera/fasp/listener.rb
DELETED
@@ -1,13 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
module Aspera
|
4
|
-
module Fasp
|
5
|
-
# implement this class to get transfer events
|
6
|
-
class Listener # rubocop:disable Lint/EmptyClass
|
7
|
-
# define one of the following methods:
|
8
|
-
# event_text(text_data)
|
9
|
-
# event_struct(legacy_names)
|
10
|
-
# event_enhanced(snake_names)
|
11
|
-
end
|
12
|
-
end
|
13
|
-
end
|
data/lib/aspera/sync.rb
DELETED
@@ -1,213 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
# cspell:words logdir
|
4
|
-
|
5
|
-
require 'aspera/command_line_builder'
|
6
|
-
require 'aspera/fasp/installation'
|
7
|
-
require 'json'
|
8
|
-
require 'base64'
|
9
|
-
|
10
|
-
module Aspera
|
11
|
-
# builds command line arg for async
|
12
|
-
class Sync
|
13
|
-
# default is push
|
14
|
-
DIRECTIONS = %i[push pull bidi].freeze
|
15
|
-
DIRECTION_TO_REQUEST_TYPE = {
|
16
|
-
push: :sync_upload,
|
17
|
-
pull: :sync_download,
|
18
|
-
bidi: :sync
|
19
|
-
}.freeze
|
20
|
-
PARAMS_VX_INSTANCE =
|
21
|
-
{
|
22
|
-
'alt_logdir' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
23
|
-
'watchd' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
24
|
-
'apply_local_docroot' => { cli: { type: :opt_without_arg}},
|
25
|
-
'quiet' => { cli: { type: :opt_without_arg}},
|
26
|
-
'ws_connect' => { cli: { type: :opt_without_arg}}
|
27
|
-
}.freeze
|
28
|
-
|
29
|
-
# map sync session parameters to transfer spec: sync -> ts, true if same
|
30
|
-
PARAMS_VX_SESSION =
|
31
|
-
{
|
32
|
-
'name' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
33
|
-
'local_dir' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
34
|
-
'remote_dir' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
35
|
-
'local_db_dir' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
36
|
-
'remote_db_dir' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
37
|
-
'host' => { cli: { type: :opt_with_arg}, accepted_types: :string, ts: :remote_host},
|
38
|
-
'user' => { cli: { type: :opt_with_arg}, accepted_types: :string, ts: :remote_user},
|
39
|
-
'private_key_paths' => { cli: { type: :opt_with_arg, switch: '--private-key-path'}, accepted_types: :array},
|
40
|
-
'direction' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
41
|
-
'checksum' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
42
|
-
'tags' => { cli: { type: :opt_with_arg, switch: '--tags64', convert: 'Aspera::Fasp::Parameters.convert_json64'},
|
43
|
-
accepted_types: :hash, ts: true},
|
44
|
-
'tcp_port' => { cli: { type: :opt_with_arg}, accepted_types: :int, ts: :ssh_port},
|
45
|
-
'rate_policy' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
46
|
-
'target_rate' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
47
|
-
'cooloff' => { cli: { type: :opt_with_arg}, accepted_types: :int},
|
48
|
-
'pending_max' => { cli: { type: :opt_with_arg}, accepted_types: :int},
|
49
|
-
'scan_intensity' => { cli: { type: :opt_with_arg}, accepted_types: :string},
|
50
|
-
'cipher' => { cli: { type: :opt_with_arg, convert: 'Aspera::Fasp::Parameters.convert_remove_hyphen'}, accepted_types: :string, ts: true},
|
51
|
-
'transfer_threads' => { cli: { type: :opt_with_arg}, accepted_types: :int},
|
52
|
-
'preserve_time' => { cli: { type: :opt_without_arg}, ts: :preserve_times},
|
53
|
-
'preserve_access_time' => { cli: { type: :opt_without_arg}, ts: nil},
|
54
|
-
'preserve_modification_time' => { cli: { type: :opt_without_arg}, ts: nil},
|
55
|
-
'preserve_uid' => { cli: { type: :opt_without_arg}, ts: :preserve_file_owner_uid},
|
56
|
-
'preserve_gid' => { cli: { type: :opt_without_arg}, ts: :preserve_file_owner_gid},
|
57
|
-
'create_dir' => { cli: { type: :opt_without_arg}, ts: true},
|
58
|
-
'reset' => { cli: { type: :opt_without_arg}},
|
59
|
-
# NOTE: only one env var, but multiple sessions... could be a problem
|
60
|
-
'remote_password' => { cli: { type: :envvar, variable: 'ASPERA_SCP_PASS'}, ts: true},
|
61
|
-
'cookie' => { cli: { type: :envvar, variable: 'ASPERA_SCP_COOKIE'}, ts: true},
|
62
|
-
'token' => { cli: { type: :envvar, variable: 'ASPERA_SCP_TOKEN'}, ts: true},
|
63
|
-
'license' => { cli: { type: :envvar, variable: 'ASPERA_SCP_LICENSE'}}
|
64
|
-
}.freeze
|
65
|
-
|
66
|
-
Aspera::CommandLineBuilder.normalize_description(PARAMS_VX_INSTANCE)
|
67
|
-
Aspera::CommandLineBuilder.normalize_description(PARAMS_VX_SESSION)
|
68
|
-
|
69
|
-
PARAMS_VX_KEYS = %w[instance sessions].freeze
|
70
|
-
|
71
|
-
# new API
|
72
|
-
TS_TO_PARAMS_V2 = {
|
73
|
-
'remote_host' => 'remote.host',
|
74
|
-
'remote_user' => 'remote.user',
|
75
|
-
'remote_password' => 'remote.pass',
|
76
|
-
'sshfp' => 'remote.fingerprint',
|
77
|
-
'ssh_port' => 'remote.port',
|
78
|
-
'wss_port' => 'remote.ws_port',
|
79
|
-
'proxy' => 'remote.proxy',
|
80
|
-
'token' => 'remote.token',
|
81
|
-
'tags' => 'tags'
|
82
|
-
}.freeze
|
83
|
-
|
84
|
-
ASYNC_EXECUTABLE = 'async'
|
85
|
-
|
86
|
-
private_constant :PARAMS_VX_INSTANCE, :PARAMS_VX_SESSION, :PARAMS_VX_KEYS, :ASYNC_EXECUTABLE, :TS_TO_PARAMS_V2
|
87
|
-
|
88
|
-
attr_reader :env_args
|
89
|
-
|
90
|
-
# @param sync_params [Hash] sync parameters, old or new format
|
91
|
-
# @param node_sync [Object|nil]
|
92
|
-
def initialize(sync_params, node_sync)
|
93
|
-
raise StandardError, 'parameter must be Hash' unless sync_params.is_a?(Hash)
|
94
|
-
raise 'node_sync misses method transfer_spec' unless node_sync.nil? || node_sync.respond_to?(:transfer_spec)
|
95
|
-
@env_args = {
|
96
|
-
args: [],
|
97
|
-
env: {}
|
98
|
-
}
|
99
|
-
if sync_params.key?('local')
|
100
|
-
# async native JSON format (v2)
|
101
|
-
raise StandardError, 'remote must be Hash' unless sync_params['remote'].is_a?(Hash)
|
102
|
-
unless node_sync.nil?
|
103
|
-
transfer_spec = node_sync.transfer_spec(sync_params['direction'], sync_params['local']['path'], sync_params['remote']['path'])
|
104
|
-
# async native JSON format
|
105
|
-
raise StandardError, 'local must be Hash' unless sync_params['local'].is_a?(Hash)
|
106
|
-
TS_TO_PARAMS_V2.each do |ts_param, sy_path|
|
107
|
-
next unless transfer_spec.key?(ts_param)
|
108
|
-
sy_dig = sy_path.split('.')
|
109
|
-
param = sy_dig.pop
|
110
|
-
hash = sy_dig.empty? ? sync_params : sync_params[sy_dig.first]
|
111
|
-
hash = sync_params[sy_dig.first] = {} if hash.nil?
|
112
|
-
hash[param] = transfer_spec[ts_param]
|
113
|
-
end
|
114
|
-
# 'remote.path',
|
115
|
-
sync_params['remote']['connect_mode'] ||= sync_params['remote'].key?('ws_port') ? 'ws' : 'ssh'
|
116
|
-
sync_params['remote']['private_key_paths'] ||= Fasp::Installation.instance.bypass_keys if transfer_spec.key?('token')
|
117
|
-
sync_params['remote']['path'] ||= '/' if transfer_spec.dig(*%w[tags aspera node file_id])
|
118
|
-
end
|
119
|
-
@env_args[:args] = ["--conf64=#{Base64.strict_encode64(JSON.generate(sync_params))}"]
|
120
|
-
elsif sync_params.key?('sessions')
|
121
|
-
# ascli JSON format (v1)
|
122
|
-
unless node_sync.nil?
|
123
|
-
sync_params['sessions'].each do |session|
|
124
|
-
transfer_spec = node_sync.transfer_spec(session['direction'], session['local_dir'], session['remote_dir'])
|
125
|
-
PARAMS_VX_SESSION.each do |async_param, behavior|
|
126
|
-
if behavior.key?(:ts)
|
127
|
-
tspec_param = behavior[:ts].is_a?(TrueClass) ? async_param : behavior[:ts].to_s
|
128
|
-
session[async_param] ||= transfer_spec[tspec_param] if transfer_spec.key?(tspec_param)
|
129
|
-
end
|
130
|
-
end
|
131
|
-
session['private_key_paths'] = Fasp::Installation.instance.bypass_keys if transfer_spec.key?('token')
|
132
|
-
session['remote_dir'] = '/' if transfer_spec.dig(*%w[tags aspera node file_id])
|
133
|
-
end
|
134
|
-
end
|
135
|
-
raise StandardError, "Only 'sessions', and optionally 'instance' keys are allowed" unless
|
136
|
-
sync_params.keys.push('instance').uniq.sort.eql?(PARAMS_VX_KEYS)
|
137
|
-
raise StandardError, 'sessions key must be Array' unless sync_params['sessions'].is_a?(Array)
|
138
|
-
raise StandardError, 'sessions key requires at least one Hash' unless sync_params['sessions'].first.is_a?(Hash)
|
139
|
-
|
140
|
-
if sync_params.key?('instance')
|
141
|
-
raise StandardError, 'instance key must be Hash' unless sync_params['instance'].is_a?(Hash)
|
142
|
-
instance_builder = Aspera::CommandLineBuilder.new(sync_params['instance'], PARAMS_VX_INSTANCE)
|
143
|
-
instance_builder.process_params
|
144
|
-
instance_builder.add_env_args(@env_args[:env], @env_args[:args])
|
145
|
-
end
|
146
|
-
|
147
|
-
sync_params['sessions'].each do |session_params|
|
148
|
-
raise StandardError, 'sessions must contain hashes' unless session_params.is_a?(Hash)
|
149
|
-
raise StandardError, 'session must contain at least name' unless session_params.key?('name')
|
150
|
-
session_builder = Aspera::CommandLineBuilder.new(session_params, PARAMS_VX_SESSION)
|
151
|
-
session_builder.process_params
|
152
|
-
session_builder.add_env_args(@env_args[:env], @env_args[:args])
|
153
|
-
end
|
154
|
-
else
|
155
|
-
raise 'At least one of `local` or `sessions` must be present in async parameters'
|
156
|
-
end
|
157
|
-
Log.dump(:sync, sync_params)
|
158
|
-
end
|
159
|
-
|
160
|
-
def start
|
161
|
-
Log.log.debug{"execute: #{@env_args[:env].map{|k, v| "#{k}=\"#{v}\""}.join(' ')} \"#{ASYNC_EXECUTABLE}\" \"#{@env_args[:args].join('" "')}\""}
|
162
|
-
res = system(@env_args[:env], [ASYNC_EXECUTABLE, ASYNC_EXECUTABLE], *@env_args[:args])
|
163
|
-
Log.log.debug{"result=#{res}"}
|
164
|
-
case res
|
165
|
-
when true then return nil
|
166
|
-
when false then raise "failed: #{$CHILD_STATUS}"
|
167
|
-
when nil then raise "not started: #{$CHILD_STATUS}"
|
168
|
-
else raise 'internal error: unspecified case'
|
169
|
-
end
|
170
|
-
end
|
171
|
-
end # end Sync
|
172
|
-
|
173
|
-
class SyncAdmin
|
174
|
-
ASYNC_ADMIN_EXECUTABLE = 'asyncadmin'
|
175
|
-
private_constant :ASYNC_ADMIN_EXECUTABLE
|
176
|
-
def initialize(sync_params, session_name)
|
177
|
-
@cmdline = [ASYNC_ADMIN_EXECUTABLE, '--quiet']
|
178
|
-
if sync_params.key?('local')
|
179
|
-
raise 'Missing session name' if sync_params['name'].nil?
|
180
|
-
raise 'Session not found' unless session_name.nil? || session_name.eql?(sync_params['name'])
|
181
|
-
@cmdline.push("--name=#{sync_params['name']}")
|
182
|
-
if sync_params.key?('local_db_dir')
|
183
|
-
@cmdline.push("--local-db-dir=#{sync_params['local_db_dir']}")
|
184
|
-
elsif sync_params.dig('local', 'path')
|
185
|
-
@cmdline.push("--local-dir=#{sync_params.dig('local', 'path')}")
|
186
|
-
else
|
187
|
-
raise 'Missing either local_db_dir or local.path'
|
188
|
-
end
|
189
|
-
elsif sync_params.key?('sessions')
|
190
|
-
session = session_name.nil? ? sync_params['sessions'].first : sync_params['sessions'].find{|s|s['name'].eql?(session_name)}
|
191
|
-
raise 'Session not found' if session.nil?
|
192
|
-
raise 'Missing session name' if session['name'].nil?
|
193
|
-
@cmdline.push("--name=#{session['name']}")
|
194
|
-
if session.key?('local_db_dir')
|
195
|
-
@cmdline.push("--local-db-dir=#{session['local_db_dir']}")
|
196
|
-
elsif session.key?('local_dir')
|
197
|
-
@cmdline.push("--local-dir=#{session['local_dir']}")
|
198
|
-
else
|
199
|
-
raise 'Missing either local_db_dir or local_dir'
|
200
|
-
end
|
201
|
-
else
|
202
|
-
raise 'At least one of `local` or `sessions` must be present in async parameters'
|
203
|
-
end
|
204
|
-
end
|
205
|
-
|
206
|
-
def status
|
207
|
-
stdout, stderr, status = Open3.capture3(*@cmdline)
|
208
|
-
Log.log.debug{"status=#{status}, stderr=#{stderr}"}
|
209
|
-
raise "Sync failed: #{status.exitstatus} : #{stderr}" unless status.success?
|
210
|
-
return stdout.split("\n").each_with_object({}){|l, m|i = l.split(/: */); m[i.first.lstrip] = i.last.lstrip} # rubocop:disable Style/Semicolon
|
211
|
-
end
|
212
|
-
end
|
213
|
-
end
|