aspera-cli 4.1.0 → 4.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +455 -229
- data/docs/Makefile +4 -4
- data/docs/README.erb.md +457 -126
- data/docs/test_env.conf +19 -2
- data/examples/aoc.rb +14 -3
- data/examples/faspex4.rb +89 -0
- data/lib/aspera/aoc.rb +38 -40
- data/lib/aspera/cli/main.rb +65 -33
- data/lib/aspera/cli/plugins/aoc.rb +54 -65
- data/lib/aspera/cli/plugins/ats.rb +2 -2
- data/lib/aspera/cli/plugins/config.rb +158 -137
- data/lib/aspera/cli/plugins/faspex.rb +111 -64
- data/lib/aspera/cli/plugins/faspex5.rb +35 -48
- data/lib/aspera/cli/plugins/node.rb +3 -2
- data/lib/aspera/cli/plugins/preview.rb +88 -55
- data/lib/aspera/cli/transfer_agent.rb +98 -62
- data/lib/aspera/cli/version.rb +1 -1
- data/lib/aspera/command_line_builder.rb +48 -31
- data/lib/aspera/cos_node.rb +34 -28
- data/lib/aspera/environment.rb +2 -2
- data/lib/aspera/fasp/aoc.rb +1 -1
- data/lib/aspera/fasp/installation.rb +68 -45
- data/lib/aspera/fasp/local.rb +89 -45
- data/lib/aspera/fasp/manager.rb +3 -0
- data/lib/aspera/fasp/node.rb +23 -1
- data/lib/aspera/fasp/parameters.rb +57 -86
- data/lib/aspera/fasp/parameters.yaml +531 -0
- data/lib/aspera/fasp/resume_policy.rb +13 -12
- data/lib/aspera/fasp/uri.rb +1 -1
- data/lib/aspera/id_generator.rb +22 -0
- data/lib/aspera/node.rb +14 -3
- data/lib/aspera/oauth.rb +135 -129
- data/lib/aspera/persistency_action_once.rb +11 -7
- data/lib/aspera/persistency_folder.rb +6 -26
- data/lib/aspera/rest.rb +3 -12
- data/lib/aspera/secrets.rb +20 -0
- data/lib/aspera/sync.rb +40 -35
- data/lib/aspera/timer_limiter.rb +22 -0
- data/lib/aspera/web_auth.rb +105 -0
- metadata +22 -3
- data/docs/transfer_spec.html +0 -99
|
@@ -4,21 +4,45 @@ module Aspera
|
|
|
4
4
|
# process_param is called repeatedly with all known parameters
|
|
5
5
|
# add_env_args is called to get resulting param list and env var (also checks that all params were used)
|
|
6
6
|
class CommandLineBuilder
|
|
7
|
+
# transform yes/no to trye/false
|
|
8
|
+
def self.yes_to_true(value)
|
|
9
|
+
case value
|
|
10
|
+
when 'yes'; return true
|
|
11
|
+
when 'no'; return false
|
|
12
|
+
end
|
|
13
|
+
raise "unsupported value: #{value}"
|
|
14
|
+
end
|
|
7
15
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
16
|
+
# Called by provider of definition before constructor of this class so that params_definition has all mandatory fields
|
|
17
|
+
def self.normalize_description(d)
|
|
18
|
+
d.each do |param_name,options|
|
|
19
|
+
raise "Expecting Hash, but have #{options.class} in #{param_name}" unless options.is_a?(Hash)
|
|
20
|
+
#options[:accepted_types]=:bool if options[:cltype].eql?(:envvar) and !options.has_key?(:accepted_types)
|
|
21
|
+
# by default : not mandatory
|
|
22
|
+
options[:mandatory]||=false
|
|
23
|
+
options[:desc]||=''
|
|
24
|
+
# by default : string, unless it's without arg
|
|
25
|
+
if ! options.has_key?(:accepted_types)
|
|
26
|
+
options[:accepted_types]=options[:cltype].eql?(:opt_without_arg) ? :bool : :string
|
|
27
|
+
end
|
|
28
|
+
# single type is placed in array
|
|
29
|
+
options[:accepted_types]=[options[:accepted_types]] unless options[:accepted_types].is_a?(Array)
|
|
30
|
+
if !options.has_key?(:option_switch) and options.has_key?(:cltype) and [:opt_without_arg,:opt_with_arg].include?(options[:cltype])
|
|
31
|
+
options[:option_switch]='--'+param_name.to_s.gsub('_','-')
|
|
32
|
+
end
|
|
33
|
+
end
|
|
13
34
|
end
|
|
14
35
|
|
|
36
|
+
private
|
|
37
|
+
|
|
38
|
+
# clvarname : command line variable name
|
|
15
39
|
def env_name(param_name,options)
|
|
16
|
-
return options[:
|
|
40
|
+
return options[:clvarname]
|
|
17
41
|
end
|
|
18
42
|
|
|
19
43
|
public
|
|
20
44
|
|
|
21
|
-
|
|
45
|
+
attr_reader :params_definition
|
|
22
46
|
|
|
23
47
|
# @param param_hash
|
|
24
48
|
def initialize(param_hash,params_definition)
|
|
@@ -44,15 +68,6 @@ module Aspera
|
|
|
44
68
|
return nil
|
|
45
69
|
end
|
|
46
70
|
|
|
47
|
-
# transform yes/no to trye/false
|
|
48
|
-
def self.yes_to_true(value)
|
|
49
|
-
case value
|
|
50
|
-
when 'yes'; return true
|
|
51
|
-
when 'no'; return false
|
|
52
|
-
end
|
|
53
|
-
raise "unsupported value: #{value}"
|
|
54
|
-
end
|
|
55
|
-
|
|
56
71
|
# add options directly to ascp command line
|
|
57
72
|
def add_command_line_options(options)
|
|
58
73
|
return if options.nil?
|
|
@@ -71,24 +86,25 @@ module Aspera
|
|
|
71
86
|
# @param options : options for type
|
|
72
87
|
def process_param(param_name,action=nil)
|
|
73
88
|
options=@params_definition[param_name]
|
|
74
|
-
action=options[:
|
|
89
|
+
action=options[:cltype] if action.nil?
|
|
75
90
|
# should not happen
|
|
76
91
|
raise "Internal error: ask processing of param #{param_name}" if options.nil?
|
|
77
|
-
# by default : not mandatory
|
|
78
|
-
options[:mandatory]||=false
|
|
79
|
-
if options.has_key?(:accepted_types)
|
|
80
|
-
# single type is placed in array
|
|
81
|
-
options[:accepted_types]=[options[:accepted_types]] unless options[:accepted_types].is_a?(Array)
|
|
82
|
-
else
|
|
83
|
-
# by default : string, unless it's without arg
|
|
84
|
-
options[:accepted_types]=action.eql?(:opt_without_arg) ? BOOLEAN_CLASSES : [String]
|
|
85
|
-
end
|
|
86
92
|
# check mandatory parameter (nil is valid value)
|
|
87
93
|
raise Fasp::Error.new("mandatory parameter: #{param_name}") if options[:mandatory] and !@param_hash.has_key?(param_name)
|
|
88
94
|
parameter_value=@param_hash[param_name]
|
|
89
|
-
parameter_value=options[:default] if parameter_value.nil? and options.has_key?(:default)
|
|
95
|
+
#parameter_value=options[:default] if parameter_value.nil? and options.has_key?(:default)
|
|
96
|
+
expected_classes=options[:accepted_types].map do |s|
|
|
97
|
+
case s
|
|
98
|
+
when :string; String
|
|
99
|
+
when :array; Array
|
|
100
|
+
when :hash; Hash
|
|
101
|
+
when :int; Integer
|
|
102
|
+
when :bool; [TrueClass,FalseClass]
|
|
103
|
+
else raise "INTERNAL: unexpected value: #{s}"
|
|
104
|
+
end
|
|
105
|
+
end.flatten
|
|
90
106
|
# check provided type
|
|
91
|
-
raise Fasp::Error.new("#{param_name} is : #{parameter_value.class} (#{parameter_value}), shall be #{options[:accepted_types]}, ") unless parameter_value.nil? or
|
|
107
|
+
raise Fasp::Error.new("#{param_name} is : #{parameter_value.class} (#{parameter_value}), shall be #{options[:accepted_types]}, ") unless parameter_value.nil? or expected_classes.include?(parameter_value.class)
|
|
92
108
|
@used_param_names.push(param_name) unless action.eql?(:defer)
|
|
93
109
|
|
|
94
110
|
# process only non-nil values
|
|
@@ -102,7 +118,8 @@ module Aspera
|
|
|
102
118
|
end
|
|
103
119
|
raise "unsupported value: #{parameter_value}" unless options[:accepted_values].nil? or options[:accepted_values].include?(parameter_value)
|
|
104
120
|
if options[:encode]
|
|
105
|
-
|
|
121
|
+
# :encode has name of class with encoding method
|
|
122
|
+
newvalue=Kernel.const_get(options[:encode]).send("encode_#{param_name}",parameter_value)
|
|
106
123
|
raise Fasp::Error.new("unsupported #{param_name}: #{parameter_value}") if newvalue.nil?
|
|
107
124
|
parameter_value=newvalue
|
|
108
125
|
end
|
|
@@ -123,12 +140,12 @@ module Aspera
|
|
|
123
140
|
else raise Fasp::Error.new("unsupported #{param_name}: #{parameter_value}")
|
|
124
141
|
end
|
|
125
142
|
add_param=!add_param if options[:add_on_false]
|
|
126
|
-
add_command_line_options([
|
|
143
|
+
add_command_line_options([options[:option_switch]]) if add_param
|
|
127
144
|
when :opt_with_arg # transform into command line option with value
|
|
128
145
|
#parameter_value=parameter_value.to_s if parameter_value.is_a?(Integer)
|
|
129
146
|
parameter_value=[parameter_value] unless parameter_value.is_a?(Array)
|
|
130
147
|
# if transfer_spec value is an array, applies option many times
|
|
131
|
-
parameter_value.each{|v|add_command_line_options([
|
|
148
|
+
parameter_value.each{|v|add_command_line_options([options[:option_switch],v])}
|
|
132
149
|
else
|
|
133
150
|
raise "Error"
|
|
134
151
|
end
|
data/lib/aspera/cos_node.rb
CHANGED
|
@@ -5,46 +5,52 @@ require 'xmlsimple'
|
|
|
5
5
|
module Aspera
|
|
6
6
|
class CosNode < Rest
|
|
7
7
|
attr_reader :add_ts
|
|
8
|
-
|
|
8
|
+
IBM_CLOUD_TOKEN_URL='https://iam.cloud.ibm.com/identity'
|
|
9
|
+
TOKEN_FIELD='delegated_refresh_token'
|
|
10
|
+
def initialize(bucket_name,storage_endpoint,instance_id,api_key,auth_url=IBM_CLOUD_TOKEN_URL)
|
|
11
|
+
@auth_url=auth_url
|
|
12
|
+
@api_key=api_key
|
|
9
13
|
s3_api=Aspera::Rest.new({
|
|
10
|
-
:base_url
|
|
11
|
-
:not_auth_codes => ['401','403'],
|
|
12
|
-
:headers
|
|
13
|
-
:auth
|
|
14
|
-
:type
|
|
15
|
-
:base_url
|
|
16
|
-
:grant
|
|
17
|
-
:api_key
|
|
14
|
+
:base_url => storage_endpoint,
|
|
15
|
+
:not_auth_codes => ['401','403'], # error codes when not authorized
|
|
16
|
+
:headers => {'ibm-service-instance-id' => instance_id},
|
|
17
|
+
:auth => {
|
|
18
|
+
:type => :oauth2,
|
|
19
|
+
:base_url => @auth_url,
|
|
20
|
+
:grant => :ibm_apikey,
|
|
21
|
+
:api_key => @api_key
|
|
18
22
|
}})
|
|
19
23
|
# read FASP connection information for bucket
|
|
20
24
|
xml_result_text=s3_api.call({:operation=>'GET',:subpath=>bucket_name,:headers=>{'Accept'=>'application/xml'},:url_params=>{'faspConnectionInfo'=>nil}})[:http].body
|
|
21
25
|
ats_info=XmlSimple.xml_in(xml_result_text, {'ForceArray' => false})
|
|
22
26
|
Aspera::Log.dump('ats_info',ats_info)
|
|
23
|
-
# get delegated token
|
|
24
|
-
delegated_oauth=Oauth.new({
|
|
25
|
-
:type => :oauth2,
|
|
26
|
-
:base_url => auth_url,
|
|
27
|
-
:grant => :delegated_refresh,
|
|
28
|
-
:api_key => api_key,
|
|
29
|
-
:token_field=> 'delegated_refresh_token'
|
|
30
|
-
})
|
|
31
|
-
# to be placed in rest call header and in transfer tags
|
|
32
|
-
aspera_storage_credentials={
|
|
33
|
-
'type' => 'token',
|
|
34
|
-
'token' => {'delegated_refresh_token'=>delegated_oauth.get_authorization().gsub(/^Bearer /,'')}
|
|
35
|
-
}
|
|
36
|
-
# transfer spec addition
|
|
37
|
-
@add_ts={'tags'=>{'aspera'=>{'node'=>{'storage_credentials'=>aspera_storage_credentials}}}}
|
|
38
|
-
# set a general addon to transfer spec
|
|
39
|
-
# here we choose to use the add_request_param
|
|
40
|
-
#self.transfer.option_transfer_spec_deep_merge(@add_ts)
|
|
41
27
|
super({
|
|
42
28
|
:base_url => ats_info['ATSEndpoint'],
|
|
43
|
-
:headers => {'X-Aspera-Storage-Credentials'=>JSON.generate(aspera_storage_credentials)},
|
|
44
29
|
:auth => {
|
|
45
30
|
:type => :basic,
|
|
46
31
|
:username => ats_info['AccessKey']['Id'],
|
|
47
32
|
:password => ats_info['AccessKey']['Secret']}})
|
|
33
|
+
# prepare transfer spec addition
|
|
34
|
+
@add_ts={'tags'=>{'aspera'=>{'node'=>{'storage_credentials'=>{
|
|
35
|
+
'type' => 'token',
|
|
36
|
+
'token' => {TOKEN_FIELD=>nil}
|
|
37
|
+
}}}}}
|
|
38
|
+
generate_token
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
# potentially call this if delegated token is expired
|
|
42
|
+
def generate_token
|
|
43
|
+
# OAuth API to get delegated token
|
|
44
|
+
delegated_oauth=Oauth.new({
|
|
45
|
+
:type => :oauth2,
|
|
46
|
+
:base_url => @auth_url,
|
|
47
|
+
:grant => :delegated_refresh,
|
|
48
|
+
:api_key => @api_key,
|
|
49
|
+
:token_field=> TOKEN_FIELD
|
|
50
|
+
})
|
|
51
|
+
# get delagated token to be placed in rest call header and in transfer tags
|
|
52
|
+
@add_ts['tags']['aspera']['node']['storage_credentials']['token'][TOKEN_FIELD]=delegated_oauth.get_authorization().gsub(/^Bearer /,'')
|
|
53
|
+
@params[:headers]={'X-Aspera-Storage-Credentials'=>JSON.generate(@add_ts['tags']['aspera']['node']['storage_credentials'])}
|
|
48
54
|
end
|
|
49
55
|
end
|
|
50
56
|
end
|
data/lib/aspera/environment.rb
CHANGED
|
@@ -2,7 +2,7 @@ require 'aspera/log'
|
|
|
2
2
|
require 'rbconfig'
|
|
3
3
|
|
|
4
4
|
module Aspera
|
|
5
|
-
#
|
|
5
|
+
# detect OS, architecture, and OS specific stuff
|
|
6
6
|
class Environment
|
|
7
7
|
OS_WINDOWS = :windows
|
|
8
8
|
OS_X = :osx
|
|
@@ -53,7 +53,7 @@ module Aspera
|
|
|
53
53
|
return ''
|
|
54
54
|
end
|
|
55
55
|
|
|
56
|
-
# on Windows, the env var %USERPROFILE% provides the path to user's home more reliably
|
|
56
|
+
# on Windows, the env var %USERPROFILE% provides the path to user's home more reliably than %HOMEDRIVE%%HOMEPATH%
|
|
57
57
|
def self.fix_home
|
|
58
58
|
if os.eql?(OS_WINDOWS)
|
|
59
59
|
if ENV.has_key?('USERPROFILE') and Dir.exist?(ENV['USERPROFILE'])
|
data/lib/aspera/fasp/aoc.rb
CHANGED
|
@@ -11,7 +11,7 @@ module Aspera
|
|
|
11
11
|
Log.log.warn("Under Development")
|
|
12
12
|
server_node_file = @api_aoc.resolve_node_file(server_home_node_file,server_folder)
|
|
13
13
|
# force node as transfer agent
|
|
14
|
-
node_api=Fasp::Node.new(@api_aoc.get_node_api(client_node_file[:node_info],AoC::SCOPE_NODE_USER))
|
|
14
|
+
node_api=Fasp::Node.new(@api_aoc.get_node_api(client_node_file[:node_info],scope: AoC::SCOPE_NODE_USER))
|
|
15
15
|
super(node_api)
|
|
16
16
|
# additional node to node TS info
|
|
17
17
|
@add_ts={
|
|
@@ -22,11 +22,18 @@ module Aspera
|
|
|
22
22
|
PRODUCT_CLI_V1='Aspera CLI'
|
|
23
23
|
PRODUCT_DRIVE='Aspera Drive'
|
|
24
24
|
PRODUCT_ENTSRV='Enterprise Server'
|
|
25
|
-
|
|
25
|
+
MAX_REDIRECT_SDK=2
|
|
26
|
+
private_constant :MAX_REDIRECT_SDK
|
|
27
|
+
# set ascp executable path
|
|
26
28
|
def ascp_path=(v)
|
|
27
29
|
@path_to_ascp=v
|
|
28
30
|
end
|
|
29
31
|
|
|
32
|
+
# filename for ascp with optional extension (Windows)
|
|
33
|
+
def ascp_filename
|
|
34
|
+
return 'ascp'+Environment.exe_extension
|
|
35
|
+
end
|
|
36
|
+
|
|
30
37
|
# location of SDK files
|
|
31
38
|
def folder=(v)
|
|
32
39
|
@sdk_folder=v
|
|
@@ -50,26 +57,30 @@ module Aspera
|
|
|
50
57
|
# @return the list of installed products in format of product_locations
|
|
51
58
|
def installed_products
|
|
52
59
|
if @found_products.nil?
|
|
53
|
-
|
|
54
|
-
# add
|
|
55
|
-
|
|
60
|
+
scan_locations=product_locations.clone
|
|
61
|
+
# add SDK as first search path
|
|
62
|
+
scan_locations.unshift({
|
|
56
63
|
:expected =>'SDK',
|
|
57
64
|
:app_root =>folder_path,
|
|
58
65
|
:sub_bin =>''
|
|
59
66
|
})
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
+
# search installed products: with ascp
|
|
68
|
+
@found_products=scan_locations.select! do |item|
|
|
69
|
+
# skip if not main folder
|
|
70
|
+
next false unless Dir.exist?(item[:app_root])
|
|
71
|
+
Log.log.debug("Found #{item[:app_root]}")
|
|
72
|
+
sub_bin = item[:sub_bin] || BIN_SUBFOLDER
|
|
73
|
+
item[:ascp_path]=File.join(item[:app_root],sub_bin,ascp_filename)
|
|
74
|
+
# skip if no ascp
|
|
75
|
+
next false unless File.exist?(item[:ascp_path])
|
|
76
|
+
# read info from product info file if present
|
|
77
|
+
product_info_file="#{item[:app_root]}/#{PRODUCT_INFO}"
|
|
67
78
|
if File.exist?(product_info_file)
|
|
68
|
-
res_s=XmlSimple.xml_in(File.read(product_info_file),{
|
|
69
|
-
|
|
70
|
-
|
|
79
|
+
res_s=XmlSimple.xml_in(File.read(product_info_file),{'ForceArray'=>false})
|
|
80
|
+
item[:name]=res_s['name']
|
|
81
|
+
item[:version]=res_s['version']
|
|
71
82
|
else
|
|
72
|
-
|
|
83
|
+
item[:name]=item[:expected]
|
|
73
84
|
end
|
|
74
85
|
true # select this version
|
|
75
86
|
end
|
|
@@ -77,6 +88,7 @@ module Aspera
|
|
|
77
88
|
return @found_products
|
|
78
89
|
end
|
|
79
90
|
|
|
91
|
+
# all ascp files (in SDK)
|
|
80
92
|
FILES=[:ascp,:ascp4,:ssh_bypass_key_dsa,:ssh_bypass_key_rsa,:aspera_license,:aspera_conf,:fallback_cert,:fallback_key]
|
|
81
93
|
|
|
82
94
|
# get path of one resource file of currently activated product
|
|
@@ -106,14 +118,8 @@ module Aspera
|
|
|
106
118
|
<CONF version="2">
|
|
107
119
|
<default>
|
|
108
120
|
<file_system>
|
|
109
|
-
<storage_rc>
|
|
110
|
-
<adaptive>
|
|
111
|
-
true
|
|
112
|
-
</adaptive>
|
|
113
|
-
</storage_rc>
|
|
114
121
|
<resume_suffix>.aspera-ckpt</resume_suffix>
|
|
115
122
|
<partial_file_suffix>.partial</partial_file_suffix>
|
|
116
|
-
<replace_illegal_chars>_</replace_illegal_chars>
|
|
117
123
|
</file_system>
|
|
118
124
|
</default>
|
|
119
125
|
</CONF>
|
|
@@ -147,7 +153,7 @@ module Aspera
|
|
|
147
153
|
return file
|
|
148
154
|
end
|
|
149
155
|
|
|
150
|
-
# @
|
|
156
|
+
# @return the file path of local connect where API's URI can be read
|
|
151
157
|
def connect_uri
|
|
152
158
|
connect=get_product_folders(PRODUCT_CONNECT)
|
|
153
159
|
folder=File.join(connect[:run_root],VARRUN_SUBFOLDER)
|
|
@@ -176,8 +182,21 @@ module Aspera
|
|
|
176
182
|
return [:ssh_bypass_key_dsa,:ssh_bypass_key_rsa].map{|i|Installation.instance.path(i)}
|
|
177
183
|
end
|
|
178
184
|
|
|
185
|
+
# Check that specified path is ascp and get version
|
|
186
|
+
def get_ascp_version(ascp_path)
|
|
187
|
+
raise "File basename of #{ascp_path} must be #{ascp_filename}" unless File.basename(ascp_path).eql?(ascp_filename)
|
|
188
|
+
ascp_version='n/a'
|
|
189
|
+
raise "error in sdk: no ascp included" if ascp_path.nil?
|
|
190
|
+
cmd_out=%x{"#{ascp_path}" -A}
|
|
191
|
+
raise "An error occured when testing #{ascp_filename}: #{cmd_out}" unless $? == 0
|
|
192
|
+
# get version from ascp, only after full extract, as windows requires DLLs (SSL/TLS/etc...)
|
|
193
|
+
m=cmd_out.match(/ascp version (.*)/)
|
|
194
|
+
ascp_version=m[1] unless m.nil?
|
|
195
|
+
end
|
|
196
|
+
|
|
179
197
|
# download aspera SDK or use local file
|
|
180
|
-
#
|
|
198
|
+
# extracts ascp binary for current system architecture
|
|
199
|
+
# @return ascp version (from execution)
|
|
181
200
|
def install_sdk(sdk_url)
|
|
182
201
|
require 'zip'
|
|
183
202
|
sdk_zip_path=File.join(Dir.tmpdir,'sdk.zip')
|
|
@@ -186,7 +205,7 @@ module Aspera
|
|
|
186
205
|
raise 'use format: file:///<path>' unless sdk_url.start_with?('file:///')
|
|
187
206
|
sdk_zip_path=sdk_url.gsub(%r{^file:///},'')
|
|
188
207
|
else
|
|
189
|
-
redirect_remain=
|
|
208
|
+
redirect_remain=MAX_REDIRECT_SDK
|
|
190
209
|
begin
|
|
191
210
|
Aspera::Rest.new(base_url: sdk_url).call(operation: 'GET',save_to_file: sdk_zip_path)
|
|
192
211
|
rescue Aspera::RestCallError => e
|
|
@@ -196,7 +215,7 @@ module Aspera
|
|
|
196
215
|
sdk_url=e.response['location']
|
|
197
216
|
retry
|
|
198
217
|
else
|
|
199
|
-
raise "
|
|
218
|
+
raise "Too many redirect"
|
|
200
219
|
end
|
|
201
220
|
else
|
|
202
221
|
raise e
|
|
@@ -206,6 +225,12 @@ module Aspera
|
|
|
206
225
|
# SDK is organized by architecture
|
|
207
226
|
filter="/#{Environment.architecture}/"
|
|
208
227
|
ascp_path=nil
|
|
228
|
+
sdk_path=folder_path
|
|
229
|
+
# rename old install
|
|
230
|
+
if File.exist?(File.join(sdk_path,ascp_filename))
|
|
231
|
+
Log.log.warn("Previous install exists, renaming.")
|
|
232
|
+
File.rename(sdk_path,"#{sdk_path}.#{Time.now.strftime("%Y%m%d%H%M%S")}")
|
|
233
|
+
end
|
|
209
234
|
# first ensure license file is here so that ascp invokation for version works
|
|
210
235
|
self.path(:aspera_license)
|
|
211
236
|
self.path(:aspera_conf)
|
|
@@ -213,11 +238,11 @@ module Aspera
|
|
|
213
238
|
zip_file.each do |entry|
|
|
214
239
|
# get only specified arch, but not folder, only files
|
|
215
240
|
if entry.name.include?(filter) and !entry.name.end_with?('/')
|
|
216
|
-
archive_file=File.join(
|
|
241
|
+
archive_file=File.join(sdk_path,File.basename(entry.name))
|
|
217
242
|
File.open(archive_file, 'wb') do |output_stream|
|
|
218
243
|
IO.copy_stream(entry.get_input_stream, output_stream)
|
|
219
244
|
end
|
|
220
|
-
if entry.name.
|
|
245
|
+
if File.basename(entry.name).eql?(ascp_filename)
|
|
221
246
|
FileUtils.chmod(0755,archive_file)
|
|
222
247
|
ascp_path=archive_file
|
|
223
248
|
end
|
|
@@ -225,13 +250,7 @@ module Aspera
|
|
|
225
250
|
end
|
|
226
251
|
end
|
|
227
252
|
File.unlink(sdk_zip_path) rescue nil # Windows may give error
|
|
228
|
-
ascp_version=
|
|
229
|
-
raise "error in sdk: no ascp included" if ascp_path.nil?
|
|
230
|
-
cmd_out=%x{#{ascp_path} -A}
|
|
231
|
-
raise "An error occured when testing ascp: #{cmd_out}" unless $? == 0
|
|
232
|
-
# get version from ascp, only after full extract, as windows requires DLLs (SSL/TLS/etc...)
|
|
233
|
-
m=cmd_out.match(/ascp version (.*)/)
|
|
234
|
-
ascp_version=m[1] unless m.nil?
|
|
253
|
+
ascp_version=get_ascp_version(ascp_path)
|
|
235
254
|
File.write(File.join(folder_path,PRODUCT_INFO),"<product><name>IBM Aspera SDK</name><version>#{ascp_version}</version></product>")
|
|
236
255
|
return ascp_version
|
|
237
256
|
end
|
|
@@ -248,27 +267,28 @@ module Aspera
|
|
|
248
267
|
|
|
249
268
|
private_constant :BIN_SUBFOLDER,:ETC_SUBFOLDER,:VARRUN_SUBFOLDER,:PRODUCT_INFO
|
|
250
269
|
|
|
251
|
-
# get some specific folder from specific applications: Connect or CLI
|
|
252
|
-
def get_product_folders(name)
|
|
253
|
-
found=installed_products.select{|i|i[:expected].eql?(name) or i[:name].eql?(name)}
|
|
254
|
-
raise "Product: #{name} not found, please install." if found.empty?
|
|
255
|
-
return found.first
|
|
256
|
-
end
|
|
257
|
-
|
|
258
270
|
def initialize
|
|
259
271
|
@path_to_ascp=nil
|
|
260
272
|
@sdk_folder=nil
|
|
261
273
|
@found_products=nil
|
|
262
274
|
end
|
|
263
275
|
|
|
276
|
+
# @return folder paths for specified applications
|
|
277
|
+
# @param name Connect or CLI
|
|
278
|
+
def get_product_folders(name)
|
|
279
|
+
found=installed_products.select{|i|i[:expected].eql?(name) or i[:name].eql?(name)}
|
|
280
|
+
raise "Product: #{name} not found, please install." if found.empty?
|
|
281
|
+
return found.first
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
# @return the path to folder where SDK is installed
|
|
264
285
|
def folder_path
|
|
265
|
-
raise "
|
|
286
|
+
raise "Undefined path to SDK" if @sdk_folder.nil?
|
|
266
287
|
FileUtils.mkdir_p(@sdk_folder) unless Dir.exist?(@sdk_folder)
|
|
267
288
|
@sdk_folder
|
|
268
289
|
end
|
|
269
290
|
|
|
270
|
-
#
|
|
271
|
-
# fields
|
|
291
|
+
# @return product folders depending on OS fields
|
|
272
292
|
# :expected M app name is taken from the manifest if present, else defaults to this value
|
|
273
293
|
# :app_root M main folder for the application
|
|
274
294
|
# :log_root O location of log files (Linux uses syslog)
|
|
@@ -310,7 +330,7 @@ module Aspera
|
|
|
310
330
|
:log_root =>File.join(Dir.home,'Library','Logs','Aspera_Drive'),
|
|
311
331
|
:sub_bin =>File.join('Contents','Resources'),
|
|
312
332
|
}]
|
|
313
|
-
else; return [{ # other: Linux and
|
|
333
|
+
else; return [{ # other: Linux and Unix family
|
|
314
334
|
:expected =>PRODUCT_CONNECT,
|
|
315
335
|
:app_root =>File.join(Dir.home,'.aspera','connect'),
|
|
316
336
|
:run_root =>File.join(Dir.home,'.aspera','connect')
|
|
@@ -324,6 +344,9 @@ module Aspera
|
|
|
324
344
|
end
|
|
325
345
|
end
|
|
326
346
|
|
|
347
|
+
# @return a standard bypass key
|
|
348
|
+
# @param type rsa or dsa
|
|
349
|
+
# @param id in repository 1 for dsa, 2 for rsa
|
|
327
350
|
def get_key(type,id)
|
|
328
351
|
hf=['begin','end'].map{|t|"-----#{t} #{type} private key-----".upcase}
|
|
329
352
|
bin=Base64.strict_encode64(DataRepository.instance.get_bin(id))
|