aspera-cli 4.19.0 → 4.21.1

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.
Files changed (91) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/CHANGELOG.md +46 -0
  4. data/CONTRIBUTING.md +18 -4
  5. data/README.md +886 -510
  6. data/bin/asession +27 -20
  7. data/examples/build_exec +65 -76
  8. data/examples/build_exec_rubyc +40 -0
  9. data/examples/get_proto_file.rb +7 -0
  10. data/lib/aspera/agent/alpha.rb +18 -24
  11. data/lib/aspera/agent/base.rb +2 -18
  12. data/lib/aspera/agent/connect.rb +34 -15
  13. data/lib/aspera/agent/direct.rb +44 -54
  14. data/lib/aspera/agent/httpgw.rb +2 -3
  15. data/lib/aspera/agent/node.rb +11 -21
  16. data/lib/aspera/agent/{trsdk.rb → transferd.rb} +27 -51
  17. data/lib/aspera/api/alee.rb +15 -0
  18. data/lib/aspera/api/aoc.rb +139 -105
  19. data/lib/aspera/api/ats.rb +1 -1
  20. data/lib/aspera/api/cos_node.rb +1 -1
  21. data/lib/aspera/api/httpgw.rb +15 -10
  22. data/lib/aspera/api/node.rb +70 -32
  23. data/lib/aspera/ascmd.rb +56 -48
  24. data/lib/aspera/ascp/installation.rb +166 -70
  25. data/lib/aspera/ascp/management.rb +30 -8
  26. data/lib/aspera/assert.rb +10 -5
  27. data/lib/aspera/cli/formatter.rb +166 -162
  28. data/lib/aspera/cli/hints.rb +2 -1
  29. data/lib/aspera/cli/info.rb +12 -10
  30. data/lib/aspera/cli/main.rb +28 -13
  31. data/lib/aspera/cli/manager.rb +7 -2
  32. data/lib/aspera/cli/plugin.rb +17 -31
  33. data/lib/aspera/cli/plugins/alee.rb +3 -3
  34. data/lib/aspera/cli/plugins/aoc.rb +246 -208
  35. data/lib/aspera/cli/plugins/ats.rb +16 -14
  36. data/lib/aspera/cli/plugins/config.rb +154 -94
  37. data/lib/aspera/cli/plugins/console.rb +3 -3
  38. data/lib/aspera/cli/plugins/cos.rb +1 -0
  39. data/lib/aspera/cli/plugins/faspex.rb +15 -23
  40. data/lib/aspera/cli/plugins/faspex5.rb +64 -50
  41. data/lib/aspera/cli/plugins/faspio.rb +2 -2
  42. data/lib/aspera/cli/plugins/httpgw.rb +1 -1
  43. data/lib/aspera/cli/plugins/node.rb +174 -109
  44. data/lib/aspera/cli/plugins/orchestrator.rb +14 -13
  45. data/lib/aspera/cli/plugins/preview.rb +8 -9
  46. data/lib/aspera/cli/plugins/server.rb +5 -9
  47. data/lib/aspera/cli/plugins/shares.rb +2 -2
  48. data/lib/aspera/cli/sync_actions.rb +2 -2
  49. data/lib/aspera/cli/transfer_agent.rb +12 -14
  50. data/lib/aspera/cli/transfer_progress.rb +37 -17
  51. data/lib/aspera/cli/version.rb +1 -1
  52. data/lib/aspera/command_line_builder.rb +4 -5
  53. data/lib/aspera/coverage.rb +13 -1
  54. data/lib/aspera/environment.rb +75 -25
  55. data/lib/aspera/faspex_gw.rb +2 -2
  56. data/lib/aspera/json_rpc.rb +1 -1
  57. data/lib/aspera/keychain/macos_security.rb +7 -12
  58. data/lib/aspera/log.rb +3 -4
  59. data/lib/aspera/node_simulator.rb +230 -112
  60. data/lib/aspera/oauth/base.rb +64 -83
  61. data/lib/aspera/oauth/factory.rb +52 -6
  62. data/lib/aspera/oauth/generic.rb +4 -8
  63. data/lib/aspera/oauth/jwt.rb +6 -3
  64. data/lib/aspera/oauth/url_json.rb +1 -2
  65. data/lib/aspera/oauth/web.rb +5 -2
  66. data/lib/aspera/persistency_action_once.rb +16 -8
  67. data/lib/aspera/persistency_folder.rb +20 -2
  68. data/lib/aspera/preview/generator.rb +1 -1
  69. data/lib/aspera/preview/utils.rb +11 -17
  70. data/lib/aspera/products/alpha.rb +30 -0
  71. data/lib/aspera/products/connect.rb +48 -0
  72. data/lib/aspera/products/other.rb +82 -0
  73. data/lib/aspera/products/transferd.rb +54 -0
  74. data/lib/aspera/rest.rb +116 -87
  75. data/lib/aspera/secret_hider.rb +2 -2
  76. data/lib/aspera/ssh.rb +31 -24
  77. data/lib/aspera/transfer/faux_file.rb +4 -4
  78. data/lib/aspera/transfer/parameters.rb +16 -17
  79. data/lib/aspera/transfer/spec.rb +12 -12
  80. data/lib/aspera/transfer/spec.yaml +22 -20
  81. data/lib/aspera/transfer/sync.rb +2 -10
  82. data/lib/aspera/transfer/uri.rb +3 -3
  83. data/lib/aspera/uri_reader.rb +1 -1
  84. data/lib/aspera/web_auth.rb +166 -17
  85. data/lib/aspera/web_server_simple.rb +4 -3
  86. data/lib/transferd_pb.rb +86 -0
  87. data/lib/transferd_services_pb.rb +84 -0
  88. data.tar.gz.sig +0 -0
  89. metadata +58 -22
  90. metadata.gz.sig +0 -0
  91. data/lib/aspera/ascp/products.rb +0 -156
data/bin/asession CHANGED
@@ -1,20 +1,24 @@
1
1
  #!/usr/bin/env ruby
2
2
  # frozen_string_literal: true
3
3
 
4
- # Laurent Martin/2017
5
- $LOAD_PATH.unshift("#{File.dirname(__FILE__)}/../lib")
4
+ gem_lib_folder = File.join(File.dirname(File.dirname(File.realpath(__FILE__))), 'lib')
5
+ Kernel.load(File.join(gem_lib_folder, 'aspera/coverage.rb'))
6
+ $LOAD_PATH.unshift(gem_lib_folder)
6
7
  require 'aspera/agent/direct'
7
8
  require 'aspera/cli/extended_value'
8
- require 'aspera/ascp/installation'
9
+ require 'aspera/products/transferd'
9
10
  require 'aspera/log'
10
11
  require 'json'
11
12
  # extended transfer spec parameter (only used in asession)
12
- # Change log level
13
+ PARAM_SPEC = 'spec'
14
+ # log level
13
15
  PARAM_LOG_LEVEL = 'loglevel'
16
+ # transfer agent options
17
+ PARAM_AGENT = 'agent'
14
18
  # by default go to /tmp/username.filelist
15
19
  PARAM_TMP_FILE_LIST_FOLDER = 'file_list_folder'
20
+ PARAM_SDK = 'sdk'
16
21
  # place transfer spec in that
17
- PARAM_SPEC = 'spec'
18
22
  SAMPLE_DEMO = '"remote_host":"demo.asperasoft.com","remote_user":"asperaweb","ssh_port":33001,"remote_password":"demoaspera"'
19
23
  SAMPLE_DEMO2 = '"direction":"receive","destination_root":"./test.dir"'
20
24
  def assert_usage(assertion, error_message)
@@ -23,28 +27,30 @@ def assert_usage(assertion, error_message)
23
27
  $stderr.puts('USAGE')
24
28
  $stderr.puts(' asession')
25
29
  $stderr.puts(' asession -h|--help')
26
- $stderr.puts(' asession <session spec extended value>')
30
+ $stderr.puts(' asession [<session spec extended value>]')
27
31
  $stderr.puts(' ')
28
32
  $stderr.puts(' If no argument is provided, default will be used: @json:@stdin')
29
33
  $stderr.puts(' -h, --help display this message')
30
- $stderr.puts(' <session spec extended value> a dictionary value (Hash)')
34
+ $stderr.puts(' <session spec extended value> a dictionary (Hash)')
31
35
  $stderr.puts(' The value can be either:')
32
36
  $stderr.puts(" the JSON description itself, e.g. @json:'{\"xx\":\"yy\",...}'")
33
37
  $stderr.puts(' @json:@stdin, if the JSON is provided from stdin')
34
38
  $stderr.puts(' @json:@file:<path>, if the JSON is provided from a file')
35
- $stderr.puts(" Parameter #{PARAM_SPEC} is mandatory, it contains the transfer spec")
39
+ $stderr.puts(' The following keys are recognized in session spec:')
40
+ $stderr.puts(" #{PARAM_SPEC} : mandatory, contains the transfer spec")
41
+ $stderr.puts(" #{PARAM_LOG_LEVEL} : modify log level (to stderr)")
42
+ $stderr.puts(" #{PARAM_AGENT} : modify transfer agent parameters, e.g. ascp_args")
43
+ $stderr.puts(" #{PARAM_TMP_FILE_LIST_FOLDER} : location of temporary files")
44
+ $stderr.puts(" #{PARAM_SDK} : location of SDK (ascp)")
36
45
  $stderr.puts(' Asynchronous commands can be provided on STDIN, examples:')
37
46
  $stderr.puts(' {"type":"START","source":"/aspera-test-dir-tiny/200KB.2"}')
38
47
  $stderr.puts(' {"type":"START","source":"xx","destination":"yy"}')
39
48
  $stderr.puts(' {"type":"DONE"}')
40
- $stderr.puts(%Q(Note: debug information can be placed on STDERR, using the "#{PARAM_LOG_LEVEL}" parameter in session spec (debug=0)))
41
49
  $stderr.puts('EXAMPLES')
42
50
  $stderr.puts(%Q( asession @json:'{"#{PARAM_SPEC}":{#{SAMPLE_DEMO},#{SAMPLE_DEMO2},"paths":[{"source":"/aspera-test-dir-tiny/200KB.1"}]}}'))
43
51
  $stderr.puts(%Q( echo '{"#{PARAM_SPEC}":{"remote_host":...}}'|asession @json:@stdin))
44
52
  Process.exit(0)
45
53
  end
46
- Aspera::Ascp::Installation.instance.sdk_folder = File.join(Dir.home, '.aspera', 'sdk')
47
-
48
54
  parameter_source_err_msg = ' (argument), did you specify: "@json:" ?'
49
55
  # by default assume JSON input on stdin if no argument
50
56
  if ARGV.empty?
@@ -62,23 +68,24 @@ rescue
62
68
  assert_usage(false, "Cannot parse argument: #{session_argument}")
63
69
  end
64
70
  # ensure right type
65
- assert_usage(session_spec.is_a?(Hash), "The value must be a hash table#{parameter_source_err_msg}")
66
- assert_usage(session_spec[PARAM_SPEC].is_a?(Hash), "the value must contain key #{PARAM_SPEC}")
71
+ assert_usage(session_spec.is_a?(Hash), "The value must be a Hash#{parameter_source_err_msg}")
72
+ assert_usage(session_spec[PARAM_SPEC].is_a?(Hash), "The value must contain key #{PARAM_SPEC} with Hash value")
67
73
  # additional debug capability
68
- if session_spec.key?(PARAM_LOG_LEVEL)
69
- Aspera::Log.instance.level = session_spec[PARAM_LOG_LEVEL]
70
- end
74
+ Aspera::Log.instance.level = session_spec[PARAM_LOG_LEVEL] if session_spec.key?(PARAM_LOG_LEVEL)
71
75
  # possibly override temp folder
72
76
  if session_spec.key?(PARAM_TMP_FILE_LIST_FOLDER)
73
77
  Aspera::Transfer::Parameters.file_list_folder = session_spec[PARAM_TMP_FILE_LIST_FOLDER]
74
78
  end
75
- session_spec['agent'] = {} unless session_spec.key?('agent')
76
- session_spec['agent']['quiet'] = true
77
- session_spec['agent']['management_cb'] = ->(event) do
79
+ session_spec[PARAM_SDK] = File.join(Dir.home, '.aspera', 'sdk') unless session_spec.key?(PARAM_SDK)
80
+ Aspera::Products::Transferd.sdk_directory = session_spec[PARAM_SDK]
81
+ session_spec[PARAM_AGENT] = {} unless session_spec.key?(PARAM_AGENT)
82
+ agent_params = session_spec[PARAM_AGENT]
83
+ agent_params['quiet'] = true
84
+ agent_params['management_cb'] = ->(event) do
78
85
  puts JSON.generate(Aspera::Ascp::Management.enhanced_event_format(event))
79
86
  end
80
87
  # get local agent (ascp), disable ascp output on stdout to not mix with JSON events
81
- client = Aspera::Agent::Direct.new(**session_spec['agent'].symbolize_keys)
88
+ client = Aspera::Agent::Direct.new(**agent_params.symbolize_keys)
82
89
  # start transfer (asynchronous)
83
90
  job_id = client.start_transfer(session_spec[PARAM_SPEC])
84
91
  # async commands
data/examples/build_exec CHANGED
@@ -1,85 +1,74 @@
1
1
  #!/bin/bash
2
-
2
+ # Glibc for various OS: https://gist.github.com/wagenet/35adca1a032cec2999d47b6c40aa45b1
3
+ # https://distrowatch.com/table.php?distribution=redhat
4
+ # RHEL 8 : glibc 2.28
5
+ # RHEL 9 : glibc 2.34
6
+ # https://distrowatch.com/table.php?distribution=ubuntu
7
+ # Ubuntu 18.10 cosmic : glibc 2.28
8
+ # Ubuntu 21.10 impish : gblic 2.34
9
+ # https://www.ibm.com/docs/en/ahts/4.4.x?topic=release-notes
10
+ # ascp 4.4.5 : gblic 2.28
11
+ # dwarfs requires boost >= 1.65
12
+ # boost requires cmake >= 3.30
3
13
  set -e
4
14
 
5
- if test $# -ne 2; then
6
- echo "Usage: $0 <CLI_TARGET_EXECUTABLE> <CLI_ENTRY_SCRIPT>" 1>&2
15
+ if test $# -ne 5; then
16
+ echo "Usage: $0 <CLI_EXECUTABLE> <CLI_PATH> <GEM_NAME> <GEM_VERSION> <DIR_TMP>" 1>&2
7
17
  exit 1
8
18
  fi
9
19
 
10
- CLI_TARGET_EXECUTABLE=$1
11
- CLI_ENTRY_SCRIPT=$(realpath $2)
12
- CLI_EXEC_NAME=$(basename $CLI_TARGET_EXECUTABLE)
13
- CLI_ROOT=$(dirname $(dirname $CLI_ENTRY_SCRIPT))
20
+ CLI_EXECUTABLE=$1
21
+ CLI_PATH=$(realpath $2)
22
+ GEM_NAME=$3
23
+ GEM_VERSION=$4
24
+ DIR_TMP=$(realpath $5)
14
25
 
15
- echo "Project folder: $CLI_ROOT"
16
- echo "Executable: $CLI_TARGET_EXECUTABLE"
17
- echo "Exec Name: $CLI_EXEC_NAME"
18
- echo "Entry: $CLI_ENTRY_SCRIPT"
26
+ echo "Building: $(basename $CLI_EXECUTABLE)"
19
27
 
20
- # tebako press --root=$(TB_WORK_DIR) --entry-point=ascli --output=$(TB_WORK_DIR)/$(CLI_TARGET_EXECUTABLE) --Ruby=3.2.4
28
+ # tebako compilation
29
+ tebako_env=$DIR_TMP/tebako-env
30
+ # project files (gem)
31
+ tebako_root=$DIR_TMP/tebako-root
32
+ # only provide the name, not path
33
+ tebako_entry=$(basename $CLI_PATH)
34
+ tebako_output=$CLI_EXECUTABLE
21
35
 
22
- if true;then
23
- tebako_command=tebako
24
- tebako_args="--root=$CLI_ROOT --entry-point=ascli --output=$CLI_TARGET_EXECUTABLE --Ruby=3.3.3"
25
- case $(uname -s) in
26
- Darwin)
27
- brew update
28
- brew install gnu-sed bash pkg-config bison flex binutils libffi gdbm zlib \
29
- ncurses double-conversion boost jemalloc glog libevent libsodium lz4 xz \
30
- libyaml openssl@3
31
- # brew install m4
32
- # boost fmt
33
- #export PATH=$(dirname $(brew ls m4|grep '/m4$'|head -n 1)):$PATH
34
- #export PATH=$(dirname $(brew ls binutils|grep '/ar$'|head -n 1)):$PATH
35
- #tebako_bin=$CLI_ROOT/tmp/tbkbin
36
- tebako_root=$CLI_ROOT/../tebako-tmp
37
- #export PATH=$tebako_bin:$PATH
38
- mkdir -p $tebako_root
39
- #mkdir -p $tebako_bin
40
- # need ar from apple
41
- #rm -f $tebako_bin/ar
42
- #ln -s /usr/bin/ar $tebako_bin
43
- export PATH=$(echo $PATH|tr : \\n|grep -v /binutils/|tr \\n :)
44
- #tebako setup --Ruby=3.3.4 --prefix=$tebako_root
45
- tebako press --Ruby=3.3.4 --prefix=$tebako_root --root=$CLI_ROOT/examples/tebako --entry-point=ascli --output=$CLI_TARGET_EXECUTABLE
46
- #tebako press --Ruby=3.3.4 --prefix=$tebako_root --root=$CLI_ROOT --entry-point=$CLI_ENTRY_SCRIPT --output=$CLI_TARGET_EXECUTABLE
47
- exit 0
48
- ;;
49
- Linux)
50
- work_dir=/mnt/w
51
- tebako press --root=$work_dir --entry-point=ascli --output=$work_dir/ascli.exe --Ruby=3.3.3
52
- tebako_prefix="podman run -it --rm -v $PWD:$work_dir ghcr.io/tamatebako/tebako-ubuntu-20.04:0.8.6"
53
- tebako_opts=--patchelf
54
- ;;
55
- *)
56
- echo "This OS is not supported." >&2
57
- exit 1
58
- ;;
59
- esac
60
- command $tebako_command $tebako_args
61
- else
62
- # https://github.com/you54f/ruby-packer
63
- # https://github.com/YOU54F/ruby-packer/releases
64
- set -e
65
- FOLDER="$(dirname $0)/../tmp"
66
- RUBYC="$FOLDER/rubyc"
67
- if test ! -e "$RUBYC"; then
68
- mkdir -p "$FOLDER"
69
- case $(uname -sm|tr ' ' -) in
70
- Darwin-arm64)
71
- curl -L https://github.com/YOU54F/ruby-packer/releases/download/rel-20230812/rubyc-Darwin-arm64.tar.gz | tar -xz -C "$FOLDER"
72
- mv "$FOLDER/rubyc-Darwin-arm64" "$RUBYC"
73
- ;;
74
- Linux-x86_64)
75
- curl -L https://github.com/YOU54F/ruby-packer/releases/download/rel-20230812/rubyc-Linux-x86_64.tar.gz | tar -xz -C "$FOLDER"
76
- mv "$FOLDER/rubyc-Linux-x86_64" "$RUBYC"
77
- ;;
78
- *)
79
- echo "This architecture is not supported." >&2
80
- exit 1
81
- ;;
82
- esac
83
- fi
84
- exec "$RUBYC" -o "$CLI_TARGET_EXECUTABLE" "$CLI_ENTRY_SCRIPT"
85
- fi
36
+ container_tag=alpine-3.17
37
+ #container_tag=ubuntu-20.04
38
+
39
+ gem install tebako
40
+ mkdir -p $tebako_env $tebako_root
41
+ (cd $tebako_root && gem fetch $GEM_NAME:$GEM_VERSION)
42
+ case $(uname -s) in
43
+ Darwin)
44
+ brew update
45
+ # install tools
46
+ brew install bash binutils bison flex gnu-sed lz4 pkg-config xz
47
+ # install libs
48
+ brew install boost double-conversion fmt gdbm glog jemalloc libevent libffi libsodium libyaml ncurses openssl@3 zlib
49
+ # make sure tools are reachable
50
+ export PATH=/opt/homebrew/opt/flex/bin:/opt/homebrew/opt/bison/bin:$PATH
51
+ # remove binutils from path so that macos `ar` is used
52
+ export PATH=$(echo $PATH|tr : \\n|grep -v /binutils/|tr \\n :)
53
+ ;;
54
+ Linux)
55
+ tebako_root=/mnt/w
56
+ tebako_prefix="podman run -it --rm -v $PWD:$tebako_root ghcr.io/tamatebako/tebako-${container_tag}:0.8.6"
57
+ tebako_opts=--patchelf
58
+ tebako_output=$tebako_root/$(basename $CLI_EXECUTABLE)
59
+ ;;
60
+ LinuxLocal)
61
+ dnf module reset ruby
62
+ dnf module install ruby:3.3
63
+ dnf install -y cmake git bash sudo autoconf boost-devel flex bison make clang binutils-devel libevent-devel libacl-devel sed python3 pkgconfig curl lz4-devel openssl-devel zlib-devel xz zip unzip tar xz-devel elfutils-devel libffi-devel gdbm-devel ncurses-devel readline-devel ruby-devel gettext-devel brotli-devel clang libxslt-devel
64
+ echo TODO
65
+ exit 1
66
+ dnf install
67
+ ;;
68
+ *)
69
+ echo "This OS is not supported." >&2
70
+ exit 1
71
+ ;;
72
+ esac
73
+ set -x
74
+ exec $tebako_prefix tebako press --root=$tebako_root --entry-point=$tebako_entry --output=$tebako_output --prefix=$tebako_env $tebako_opts
@@ -0,0 +1,40 @@
1
+ #!/bin/bash
2
+
3
+ set -e
4
+
5
+ if test $# -ne 5; then
6
+ echo "Usage: $0 <CLI_EXECUTABLE> <CLI_PATH> <GEM_NAME> <GEM_VERSION> <DIR_TMP>" 1>&2
7
+ exit 1
8
+ fi
9
+
10
+ CLI_EXECUTABLE=$1
11
+ CLI_PATH=$(realpath $2)
12
+ GEM_NAME=$3
13
+ GEM_VERSION=$4
14
+ DIR_TMP=$(realpath $5)
15
+
16
+ echo "Building: $(basename $CLI_EXECUTABLE)"
17
+
18
+ # https://github.com/you54f/ruby-packer
19
+ # https://github.com/you54f/ruby-packer/releases
20
+ set -e
21
+ FOLDER="$(dirname $0)/../tmp"
22
+ RUBYC="$FOLDER/rubyc"
23
+ if test ! -e "$RUBYC"; then
24
+ mkdir -p "$FOLDER"
25
+ case $(uname -sm|tr ' ' -) in
26
+ Darwin-arm64)
27
+ curl -L https://github.com/YOU54F/ruby-packer/releases/download/rel-20230812/rubyc-Darwin-arm64.tar.gz | tar -xz -C "$FOLDER"
28
+ mv "$FOLDER/rubyc-Darwin-arm64" "$RUBYC"
29
+ ;;
30
+ Linux-x86_64)
31
+ curl -L https://github.com/YOU54F/ruby-packer/releases/download/rel-20230812/rubyc-Linux-x86_64.tar.gz | tar -xz -C "$FOLDER"
32
+ mv "$FOLDER/rubyc-Linux-x86_64" "$RUBYC"
33
+ ;;
34
+ *)
35
+ echo "This architecture is not supported." >&2
36
+ exit 1
37
+ ;;
38
+ esac
39
+ fi
40
+ exec "$RUBYC" -o "$CLI_EXECUTABLE" "$CLI_PATH"
@@ -0,0 +1,7 @@
1
+ #!/usr/bin/env ruby
2
+ # frozen_string_literal: true
3
+
4
+ # Retrieve `transfer.proto` from the web
5
+ $LOAD_PATH.unshift(File.join(File.dirname(File.dirname(File.realpath(__FILE__))), 'lib'))
6
+ require 'aspera/ascp/installation'
7
+ Aspera::Ascp::Installation.instance.install_sdk(folder: ARGV.first, backup: false, with_exe: false) {|name| '/' if name.end_with?('transferd.proto')}
@@ -2,9 +2,9 @@
2
2
 
3
3
  require 'aspera/agent/base'
4
4
  require 'aspera/rest'
5
- require 'aspera/log'
6
- require 'aspera/json_rpc'
7
5
  require 'aspera/environment'
6
+ require 'aspera/json_rpc'
7
+ require 'aspera/products/alpha'
8
8
  require 'securerandom'
9
9
 
10
10
  module Aspera
@@ -15,13 +15,12 @@ module Aspera
15
15
  START_URIS = ['aspera://', 'aspera://', 'aspera://']
16
16
  # delay between each try to start the app
17
17
  SLEEP_SEC_BETWEEN_RETRY = 5
18
- APP_IDENTIFIER = 'com.ibm.software.aspera.desktop'
19
- APP_NAME = 'Aspera Desktop Alpha Client'
20
18
  private_constant :START_URIS, :SLEEP_SEC_BETWEEN_RETRY
19
+
21
20
  def initialize(**base_options)
22
21
  @application_id = SecureRandom.uuid
23
22
  @xfer_id = nil
24
- super(**base_options)
23
+ super
25
24
  raise 'Using client requires a graphical environment' if !Environment.default_gui_mode.eql?(:graphical)
26
25
  method_index = 0
27
26
  begin
@@ -34,24 +33,20 @@ module Aspera
34
33
  rescue Errno::ECONNREFUSED => e
35
34
  start_url = START_URIS[method_index]
36
35
  method_index += 1
37
- raise StandardError, "Unable to start #{APP_NAME} #{method_index} times" if start_url.nil?
38
- Log.log.warn{"#{APP_NAME} is not started (#{e}). Trying to start it ##{method_index}..."}
36
+ raise StandardError, "Unable to start #{Products::Alpha::APP_NAME} #{method_index} times" if start_url.nil?
37
+ Log.log.warn{"#{Products::Alpha::APP_NAME} is not started (#{e}). Trying to start it ##{method_index}..."}
39
38
  if !Environment.open_uri_graphical(start_url)
40
39
  Environment.open_uri_graphical('https://www.ibm.com/aspera/connect/')
41
- raise StandardError, "#{APP_NAME} is not installed"
40
+ raise StandardError, "#{Products::Alpha::APP_NAME} is not installed"
42
41
  end
43
42
  sleep(SLEEP_SEC_BETWEEN_RETRY)
44
43
  retry
45
44
  end
46
45
  end
47
46
 
48
- def sdk_log_file
49
- File.join(Dir.home, 'Library', 'Logs', APP_IDENTIFIER, 'ibm-aspera-desktop.log')
50
- end
51
-
52
47
  def aspera_client_api_url
53
- log_file = sdk_log_file
54
- url = nil
48
+ log_file = Products::Alpha.log_file
49
+ url = 'http://127.0.0.1:33024'
55
50
  File.open(log_file, 'r') do |file|
56
51
  file.each_line do |line|
57
52
  line = line.chomp
@@ -60,8 +55,7 @@ module Aspera
60
55
  end
61
56
  end
62
57
  end
63
- url = 'http://127.0.0.1:33024' if url.nil?
64
- raise StandardError, "Unable to find the JSON-RPC server URL in #{log_file}" if url.nil?
58
+ # raise StandardError, "Unable to find the JSON-RPC server URL in #{log_file}" if url.nil?
65
59
  return url
66
60
  end
67
61
 
@@ -82,29 +76,29 @@ module Aspera
82
76
  transfer = @client_app_api.get_transfer(app_id: @application_id, transfer_id: @xfer_id)
83
77
  case transfer['status']
84
78
  when 'initiating', 'queued'
85
- notify_progress(session_id: nil, type: :pre_start, info: transfer['status'])
79
+ notify_progress(:pre_start, session_id: nil, info: transfer['status'])
86
80
  when 'running'
87
81
  if !started
88
- notify_progress(session_id: @xfer_id, type: :session_start)
82
+ notify_progress(:session_start, session_id: @xfer_id)
89
83
  started = true
90
84
  end
91
85
  if !pre_calc && (transfer['bytes_expected'] != 0)
92
- notify_progress(type: :session_size, session_id: @xfer_id, info: transfer['bytes_expected'])
86
+ notify_progress(:session_size, session_id: @xfer_id, info: transfer['bytes_expected'])
93
87
  pre_calc = true
94
88
  else
95
- notify_progress(type: :transfer, session_id: @xfer_id, info: transfer['bytes_written'])
89
+ notify_progress(:transfer, session_id: @xfer_id, info: transfer['bytes_written'])
96
90
  end
97
91
  when 'completed'
98
- notify_progress(type: :end, session_id: @xfer_id)
92
+ notify_progress(:end, session_id: @xfer_id)
99
93
  break
100
94
  when 'failed'
101
- notify_progress(type: :end, session_id: @xfer_id)
95
+ notify_progress(:end, session_id: @xfer_id)
102
96
  raise Transfer::Error, transfer['error_desc']
103
97
  when 'cancelled'
104
- notify_progress(type: :end, session_id: @xfer_id)
98
+ notify_progress(:end, session_id: @xfer_id)
105
99
  raise Transfer::Error, 'Transfer cancelled by user'
106
100
  else
107
- notify_progress(type: :end, session_id: @xfer_id)
101
+ notify_progress(:end, session_id: @xfer_id)
108
102
  raise Transfer::Error, "unknown status: #{transfer['status']}: #{transfer['error_desc']}"
109
103
  end
110
104
  sleep(1)
@@ -14,22 +14,6 @@ module Aspera
14
14
  Aspera::Agent.const_get(agent.to_s.capitalize).new(**options)
15
15
  end
16
16
 
17
- # compute options from user provided and default options
18
- def to_move_options(default:, options:)
19
- result = options.symbolize_keys
20
- available = default.map{|k, v|"#{k}(#{v})"}.join(', ')
21
- result.each_key do |k|
22
- Aspera.assert_values(k, default.keys){"transfer agent parameter: #{k}"}
23
- # check it is the expected type: too limiting, as we can have an Integer or Float, or symbol and string
24
- # raise "Invalid value for transfer agent parameter: #{k}, expect #{default[k].class.name}" unless default[k].nil? || v.is_a?(default[k].class)
25
- end
26
- default.each do |k, v|
27
- raise "Missing required agent parameter: #{k}. Parameters: #{available}" if v.eql?(:required) && !result.key?(k)
28
- result[k] = v unless result.key?(k)
29
- end
30
- return result
31
- end
32
-
33
17
  # discover available agents
34
18
  def agent_list
35
19
  base_class = File.basename(__FILE__)
@@ -58,8 +42,8 @@ module Aspera
58
42
  @progress = progress
59
43
  end
60
44
 
61
- def notify_progress(**parameters)
62
- @progress&.event(**parameters)
45
+ def notify_progress(*pos_args, **kw_args)
46
+ @progress&.event(*pos_args, **kw_args)
63
47
  end
64
48
  end
65
49
  end
@@ -1,7 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  require 'aspera/agent/base'
4
+ require 'aspera/products/connect'
5
+ require 'aspera/products/other'
4
6
  require 'aspera/rest'
7
+ require 'aspera/environment'
5
8
  require 'securerandom'
6
9
 
7
10
  module Aspera
@@ -13,22 +16,23 @@ module Aspera
13
16
  SLEEP_SEC_BETWEEN_RETRY = 5
14
17
  private_constant :CONNECT_START_URIS, :SLEEP_SEC_BETWEEN_RETRY
15
18
  def initialize(**base_options)
16
- super(**base_options)
19
+ super
17
20
  @connect_settings = {
18
21
  'app_id' => SecureRandom.uuid
19
22
  }
20
23
  raise 'Using connect requires a graphical environment' if !Environment.default_gui_mode.eql?(:graphical)
21
24
  method_index = 0
22
25
  begin
23
- connect_url = Ascp::Products.connect_uri
26
+ connect_url = connect_api_url
24
27
  Log.log.debug{"found: #{connect_url}"}
25
28
  @connect_api = Rest.new(
26
29
  base_url: "#{connect_url}/v5/connect", # could use v6 also now
27
- headers: {'Origin' => Rest.user_agent})
28
- connect_info = @connect_api.read('info/version')[:data]
30
+ headers: {'Origin' => RestParameters.instance.user_agent})
31
+ connect_info = @connect_api.read('info/version')
29
32
  Log.log.info('Connect was reached') if method_index > 0
30
33
  Log.log.debug{Log.dump(:connect_version, connect_info)}
31
34
  rescue StandardError => e # Errno::ECONNREFUSED
35
+ Log.log.debug{"Exception: #{e}"}
32
36
  start_url = CONNECT_START_URIS[method_index]
33
37
  method_index += 1
34
38
  raise StandardError, "Unable to start connect #{method_index} times" if start_url.nil?
@@ -42,6 +46,21 @@ module Aspera
42
46
  end
43
47
  end
44
48
 
49
+ # @return the file path of local connect where API's URI can be read
50
+ def connect_api_url
51
+ connect_locations = Products::Other.find(Products::Connect.locations).first
52
+ raise "Product: #{name} not found, please install." if connect_locations.nil?
53
+ folder = File.join(connect_locations[:run_root], 'var', 'run')
54
+ ['', 's'].each do |ext|
55
+ uri_file = File.join(folder, "http#{ext}.uri")
56
+ Log.log.debug{"checking connect port file: #{uri_file}"}
57
+ if File.exist?(uri_file)
58
+ return File.open(uri_file, &:gets).strip
59
+ end
60
+ end
61
+ raise "no connect uri file found in #{folder}"
62
+ end
63
+
45
64
  def start_transfer(transfer_spec, token_regenerator: nil)
46
65
  if transfer_spec['direction'] == 'send'
47
66
  Log.log.warn{"Connect requires upload selection using GUI, ignoring #{transfer_spec['paths']}".red}
@@ -51,7 +70,7 @@ module Aspera
51
70
  'title' => 'Select Files',
52
71
  'suggestedName' => '',
53
72
  'allowMultipleSelection' => true,
54
- 'allowedFileTypes' => ''})[:data]
73
+ 'allowedFileTypes' => ''})
55
74
  transfer_spec['paths'] = selection['dataTransfer']['files'].map { |i| {'source' => i['name']}}
56
75
  end
57
76
  @request_id = SecureRandom.uuid
@@ -67,7 +86,7 @@ module Aspera
67
86
  'transfer_spec' => transfer_spec
68
87
  }]}
69
88
  # asynchronous anyway
70
- res = @connect_api.create('transfers/start', connect_transfer_args)[:data]
89
+ res = @connect_api.create('transfers/start', connect_transfer_args)
71
90
  @xfer_id = res['transfer_specs'].first['transfer_spec']['tags'][Transfer::Spec::TAG_RESERVED]['xfer_id']
72
91
  end
73
92
 
@@ -78,7 +97,7 @@ module Aspera
78
97
  session_id = @xfer_id
79
98
  begin
80
99
  loop do
81
- tr_info = @connect_api.create("transfers/info/#{@xfer_id}", connect_activity_args)[:data]
100
+ tr_info = @connect_api.create("transfers/info/#{@xfer_id}", connect_activity_args)
82
101
  Log.log.trace1{Log.dump(:tr_info, tr_info)}
83
102
  if tr_info['transfer_info'].is_a?(Hash)
84
103
  transfer = tr_info['transfer_info']
@@ -89,29 +108,29 @@ module Aspera
89
108
  # TODO: get session id
90
109
  case transfer['status']
91
110
  when 'initiating', 'queued'
92
- notify_progress(session_id: nil, type: :pre_start, info: transfer['status'])
111
+ notify_progress(:pre_start, session_id: nil, info: transfer['status'])
93
112
  when 'running'
94
113
  if !started
95
- notify_progress(session_id: session_id, type: :session_start)
114
+ notify_progress(:session_start, session_id: session_id)
96
115
  started = true
97
116
  end
98
117
  if !pre_calc && (transfer['bytes_expected'] != 0)
99
- notify_progress(type: :session_size, session_id: session_id, info: transfer['bytes_expected'])
118
+ notify_progress(:session_size, session_id: session_id, info: transfer['bytes_expected'])
100
119
  pre_calc = true
101
120
  else
102
- notify_progress(type: :transfer, session_id: session_id, info: transfer['bytes_written'])
121
+ notify_progress(:transfer, session_id: session_id, info: transfer['bytes_written'])
103
122
  end
104
123
  when 'completed'
105
- notify_progress(type: :end, session_id: session_id)
124
+ notify_progress(:end, session_id: session_id)
106
125
  break
107
126
  when 'failed'
108
- notify_progress(type: :end, session_id: session_id)
127
+ notify_progress(:end, session_id: session_id)
109
128
  raise Transfer::Error, transfer['error_desc']
110
129
  when 'cancelled'
111
- notify_progress(type: :end, session_id: session_id)
130
+ notify_progress(:end, session_id: session_id)
112
131
  raise Transfer::Error, 'Transfer cancelled by user'
113
132
  else
114
- notify_progress(type: :end, session_id: session_id)
133
+ notify_progress(:end, session_id: session_id)
115
134
  raise Transfer::Error, "unknown status: #{transfer['status']}: #{transfer['error_desc']}"
116
135
  end
117
136
  end