Class: Aspera::Fasp::Installation
- Inherits:
-
Object
- Object
- Aspera::Fasp::Installation
- Includes:
- Singleton
- Defined in:
- lib/aspera/fasp/installation.rb
Overview
Singleton that tells where to find ascp and other local resources (keys..) , using the “path(symb)” method. It is used by object : AgentDirect to find necessary resources By default it takes the first Aspera product found specified in product_locations but the user can specify ascp location by calling: Installation.instance.use_ascp_from_product(product_name) or Installation.instance.ascp_path=“”
Constant Summary collapse
- FILES =
all ascp files (in SDK)
i[ascp ascp4 ssh_bypass_dsa_privkey ssh_bypass_rsa_privkey aspera_license aspera_conf fallback_certificate fallback_cert_privkey].freeze
Instance Method Summary collapse
- #ascp_path ⇒ Object
-
#ascp_path=(v) ⇒ Object
set ascp executable path.
- #bypass_keys ⇒ Object
-
#bypass_pass ⇒ Object
default bypass key phrase.
- #check_or_create_sdk_file(filename, force: false, &block) ⇒ Object
-
#cli_conf_file ⇒ Object
@ return path to configuration file of aspera CLI.
-
#connect_uri ⇒ Object
The file path of local connect where API’s URI can be read.
-
#get_ascp_version(exe_path) ⇒ Object
use in plugin
config. -
#get_exe_version(exe_path, vers_arg) ⇒ Object
Check that specified path is ascp and get version.
-
#install_sdk(sdk_url) ⇒ Object
download aspera SDK or use local file extracts ascp binary for current system architecture.
-
#installed_products ⇒ Object
The list of installed products in format of product_locations.
-
#path(k) ⇒ Object
get path of one resource file of currently activated product keys and certs are generated locally…
-
#sdk_folder ⇒ Object
The path to folder where SDK is installed.
-
#sdk_folder=(v) ⇒ Object
(also: #folder=)
location of SDK files.
- #sdk_ruby_folder ⇒ Object
-
#use_ascp_from_product(product_name) ⇒ Object
find ascp in named product (use value : FIRST_FOUND=‘FIRST’ to just use first one) or select one from installed_products().
Instance Method Details
#ascp_path ⇒ Object
53 54 55 |
# File 'lib/aspera/fasp/installation.rb', line 53 def ascp_path path(:ascp) end |
#ascp_path=(v) ⇒ Object
set ascp executable path
49 50 51 |
# File 'lib/aspera/fasp/installation.rb', line 49 def ascp_path=(v) @path_to_ascp = v end |
#bypass_keys ⇒ Object
207 208 209 |
# File 'lib/aspera/fasp/installation.rb', line 207 def bypass_keys return i[ssh_bypass_dsa_privkey ssh_bypass_rsa_privkey].map{|i|Installation.instance.path(i)} end |
#bypass_pass ⇒ Object
default bypass key phrase
203 204 205 |
# File 'lib/aspera/fasp/installation.rb', line 203 def bypass_pass return format('%08x-%04x-%04x-%04x-%04x%08x', *DataRepository.instance.data(3).unpack('NnnnnN')) end |
#check_or_create_sdk_file(filename, force: false, &block) ⇒ Object
131 132 133 |
# File 'lib/aspera/fasp/installation.rb', line 131 def check_or_create_sdk_file(filename, force: false, &block) return Environment.write_file_restricted(File.join(sdk_folder, filename), force: force, mode: 0o644, &block) end |
#cli_conf_file ⇒ Object
@ return path to configuration file of aspera CLI
197 198 199 200 |
# File 'lib/aspera/fasp/installation.rb', line 197 def cli_conf_file connect = get_product_folders(PRODUCT_CLI_V1) return File.join(connect[:app_root], BIN_SUBFOLDER, '.aspera_cli_conf') end |
#connect_uri ⇒ Object
Returns the file path of local connect where API’s URI can be read.
183 184 185 186 187 188 189 190 191 192 193 194 |
# File 'lib/aspera/fasp/installation.rb', line 183 def connect_uri connect = get_product_folders(PRODUCT_CONNECT) folder = File.join(connect[:run_root], VAR_RUN_SUBFOLDER) ['', 's'].each do |ext| uri_file = File.join(folder, "http#{ext}.uri") Log.log.debug{"checking connect port file: #{uri_file}"} if File.exist?(uri_file) return File.open(uri_file, &:gets).strip end end raise "no connect uri file found in #{folder}" end |
#get_ascp_version(exe_path) ⇒ Object
use in plugin config
212 213 214 |
# File 'lib/aspera/fasp/installation.rb', line 212 def get_ascp_version(exe_path) return get_exe_version(exe_path, '-A') end |
#get_exe_version(exe_path, vers_arg) ⇒ Object
Check that specified path is ascp and get version
217 218 219 220 221 222 223 224 225 226 227 |
# File 'lib/aspera/fasp/installation.rb', line 217 def get_exe_version(exe_path, vers_arg) raise 'ERROR: nil arg' if exe_path.nil? return nil unless File.exist?(exe_path) exe_version = nil cmd_out = %x("#{exe_path}" #{vers_arg}) raise "An error occurred when testing #{ascp_filename}: #{cmd_out}" unless $CHILD_STATUS == 0 # get version from ascp, only after full extract, as windows requires DLLs (SSL/TLS/etc...) m = cmd_out.match(/ version ([0-9.]+)/) exe_version = m[1] unless m.nil? return exe_version end |
#install_sdk(sdk_url) ⇒ Object
download aspera SDK or use local file extracts ascp binary for current system architecture
232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 |
# File 'lib/aspera/fasp/installation.rb', line 232 def install_sdk(sdk_url) # SDK is organized by architecture, check this first, in case architecture is not supported arch_filter = "#{Environment.architecture}/" require 'zip' sdk_zip_path = File.join(Dir.tmpdir, 'sdk.zip') if sdk_url.start_with?('file:') # require specific file scheme: the path part is "relative", or absolute if there are 4 slash raise 'use format: file:///<path>' unless sdk_url.start_with?('file:///') sdk_zip_path = sdk_url.gsub(%r{^file:///}, '') else Aspera::Rest.new(base_url: sdk_url, redirect_max: 3).call(operation: 'GET', save_to_file: sdk_zip_path) end # rename old install if !Dir.empty?(sdk_folder) Log.log.warn('Previous install exists, renaming folder.') File.rename(sdk_folder, "#{sdk_folder}.#{Time.now.strftime('%Y%m%d%H%M%S')}") # TODO: delete old archives ? end # extract files from archive Zip::File.open(sdk_zip_path) do |zip_file| zip_file.each do |entry| # skip folder entries next if entry.name.end_with?('/') dest_folder = nil # binaries dest_folder = sdk_folder if entry.name.include?(arch_filter) # ruby adapters dest_folder = sdk_ruby_folder if entry.name.end_with?(EXT_RUBY_PROTOBUF) next if dest_folder.nil? File.open(File.join(dest_folder, File.basename(entry.name)), 'wb') do |output_stream| IO.copy_stream(entry.get_input_stream, output_stream) end end end File.unlink(sdk_zip_path) rescue nil # Windows may give error # ensure license file are generated so that ascp invocation for version works path(:aspera_license) path(:aspera_conf) ascp_path = File.join(sdk_folder, ascp_filename) raise "No #{ascp_filename} found in SDK archive" unless File.exist?(ascp_path) Environment.restrict_file_access(ascp_path, mode: 0o755) Environment.restrict_file_access(ascp_path.gsub('ascp', 'ascp4'), mode: 0o755) ascp_version = get_ascp_version(File.join(sdk_folder, ascp_filename)) trd_path = transferd_filepath Log.log.warn{"No #{trd_path} in SDK archive"} unless File.exist?(trd_path) Environment.restrict_file_access(trd_path, mode: 0o755) if File.exist?(trd_path) transferd_version = get_exe_version(trd_path, 'version') sdk_version = transferd_version || ascp_version File.write(File.join(sdk_folder, PRODUCT_INFO), "<product><name>IBM Aspera SDK</name><version>#{sdk_version}</version></product>") return sdk_version end |
#installed_products ⇒ Object
Returns the list of installed products in format of product_locations.
95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
# File 'lib/aspera/fasp/installation.rb', line 95 def installed_products if @found_products.nil? scan_locations = product_locations.clone # add SDK as first search path scan_locations.unshift({ expected: 'SDK', app_root: sdk_folder, sub_bin: '' }) # search installed products: with ascp @found_products = scan_locations.select! do |item| # skip if not main folder next false unless Dir.exist?(item[:app_root]) Log.log.debug{"Found #{item[:app_root]}"} sub_bin = item[:sub_bin] || BIN_SUBFOLDER item[:ascp_path] = File.join(item[:app_root], sub_bin, ascp_filename) # skip if no ascp next false unless File.exist?(item[:ascp_path]) # read info from product info file if present product_info_file = "#{item[:app_root]}/#{PRODUCT_INFO}" if File.exist?(product_info_file) res_s = XmlSimple.xml_in(File.read(product_info_file), {'ForceArray' => false}) item[:name] = res_s['name'] item[:version] = res_s['version'] else item[:name] = item[:expected] end true # select this version end end return @found_products end |
#path(k) ⇒ Object
get path of one resource file of currently activated product keys and certs are generated locally… (they are well known values, arch. independent)
137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 |
# File 'lib/aspera/fasp/installation.rb', line 137 def path(k) case k when :ascp, :ascp4 use_ascp_from_product(FIRST_FOUND) if @path_to_ascp.nil? file = @path_to_ascp # NOTE: that there might be a .exe at the end file = file.gsub('ascp', 'ascp4') if k.eql?(:ascp4) when :transferd file = transferd_filepath when :ssh_bypass_dsa_privkey file = check_or_create_sdk_file('aspera_bypass_dsa.pem') {get_key('dsa', 1)} when :ssh_bypass_rsa_privkey file = check_or_create_sdk_file('aspera_bypass_rsa.pem') {get_key('rsa', 2)} when :aspera_license file = check_or_create_sdk_file('aspera-license') do Zlib::Inflate.inflate(DataRepository.instance.data(6)) end when :aspera_conf file = check_or_create_sdk_file('aspera.conf') {DEFAULT_ASPERA_CONF} when :fallback_certificate, :fallback_cert_privkey file_key = File.join(sdk_folder, 'aspera_fallback_cert_private_key.pem') file_cert = File.join(sdk_folder, 'aspera_fallback_cert.pem') if !File.exist?(file_key) || !File.exist?(file_cert) require 'openssl' # create new self signed certificate for http fallback private_key = OpenSSL::PKey::RSA.new(1024) cert = OpenSSL::X509::Certificate.new cert.subject = cert.issuer = OpenSSL::X509::Name.parse(DUMMY_CERT_INFO) cert.not_before = Time.now cert.not_after = Time.now + ONE_YEAR_SECONDS cert.public_key = private_key.public_key cert.serial = 0x0 cert.version = 2 cert.sign(private_key, OpenSSL::Digest.new('SHA1')) check_or_create_sdk_file('aspera_fallback_cert_private_key.pem', force: true) {private_key.to_pem} check_or_create_sdk_file('aspera_fallback_cert.pem', force: true) {cert.to_pem} end file = k.eql?(:fallback_certificate) ? file_cert : file_key else raise "INTERNAL ERROR: #{k}" end raise "no such file: #{file}" unless File.exist?(file) return file end |
#sdk_folder ⇒ Object
Returns the path to folder where SDK is installed.
74 75 76 77 78 |
# File 'lib/aspera/fasp/installation.rb', line 74 def sdk_folder raise 'SDK path was ot initialized' if @sdk_dir.nil? FileUtils.mkdir_p(@sdk_dir) unless Dir.exist?(@sdk_dir) @sdk_dir end |
#sdk_folder=(v) ⇒ Object Also known as: folder=
location of SDK files
64 65 66 67 68 |
# File 'lib/aspera/fasp/installation.rb', line 64 def sdk_folder=(v) Log.log.debug{"sdk_folder=#{v}"} @sdk_dir = v sdk_folder end |
#sdk_ruby_folder ⇒ Object
57 58 59 60 61 |
# File 'lib/aspera/fasp/installation.rb', line 57 def sdk_ruby_folder ruby_pb_folder = File.join(sdk_folder, RB_SDK_FOLDER) FileUtils.mkdir_p(ruby_pb_folder) unless Dir.exist?(ruby_pb_folder) return ruby_pb_folder end |
#use_ascp_from_product(product_name) ⇒ Object
find ascp in named product (use value : FIRST_FOUND=‘FIRST’ to just use first one) or select one from installed_products()
82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/aspera/fasp/installation.rb', line 82 def use_ascp_from_product(product_name) if product_name.eql?(FIRST_FOUND) pl = installed_products.first raise "no FASP installation found\nPlease check manual on how to install FASP." if pl.nil? else pl = installed_products.find{|i|i[:name].eql?(product_name)} raise "no such product installed: #{product_name}" if pl.nil? end self.ascp_path = pl[:ascp_path] Log.log.debug{"ascp_path=#{@path_to_ascp}"} end |