aspera-cli 4.0.0.pre1

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 (88) hide show
  1. checksums.yaml +7 -0
  2. data/README.md +3592 -0
  3. data/bin/ascli +7 -0
  4. data/bin/asession +89 -0
  5. data/docs/Makefile +59 -0
  6. data/docs/README.erb.md +3012 -0
  7. data/docs/README.md +13 -0
  8. data/docs/diagrams.txt +49 -0
  9. data/docs/secrets.make +38 -0
  10. data/docs/test_env.conf +117 -0
  11. data/docs/transfer_spec.html +99 -0
  12. data/examples/aoc.rb +17 -0
  13. data/examples/proxy.pac +60 -0
  14. data/examples/transfer.rb +115 -0
  15. data/lib/aspera/api_detector.rb +60 -0
  16. data/lib/aspera/ascmd.rb +151 -0
  17. data/lib/aspera/ats_api.rb +43 -0
  18. data/lib/aspera/cli/basic_auth_plugin.rb +38 -0
  19. data/lib/aspera/cli/extended_value.rb +88 -0
  20. data/lib/aspera/cli/formater.rb +238 -0
  21. data/lib/aspera/cli/listener/line_dump.rb +17 -0
  22. data/lib/aspera/cli/listener/logger.rb +20 -0
  23. data/lib/aspera/cli/listener/progress.rb +52 -0
  24. data/lib/aspera/cli/listener/progress_multi.rb +91 -0
  25. data/lib/aspera/cli/main.rb +304 -0
  26. data/lib/aspera/cli/manager.rb +440 -0
  27. data/lib/aspera/cli/plugin.rb +90 -0
  28. data/lib/aspera/cli/plugins/alee.rb +24 -0
  29. data/lib/aspera/cli/plugins/ats.rb +231 -0
  30. data/lib/aspera/cli/plugins/bss.rb +71 -0
  31. data/lib/aspera/cli/plugins/config.rb +806 -0
  32. data/lib/aspera/cli/plugins/console.rb +62 -0
  33. data/lib/aspera/cli/plugins/cos.rb +106 -0
  34. data/lib/aspera/cli/plugins/faspex.rb +377 -0
  35. data/lib/aspera/cli/plugins/faspex5.rb +93 -0
  36. data/lib/aspera/cli/plugins/node.rb +438 -0
  37. data/lib/aspera/cli/plugins/oncloud.rb +937 -0
  38. data/lib/aspera/cli/plugins/orchestrator.rb +169 -0
  39. data/lib/aspera/cli/plugins/preview.rb +464 -0
  40. data/lib/aspera/cli/plugins/server.rb +216 -0
  41. data/lib/aspera/cli/plugins/shares.rb +63 -0
  42. data/lib/aspera/cli/plugins/shares2.rb +114 -0
  43. data/lib/aspera/cli/plugins/sync.rb +65 -0
  44. data/lib/aspera/cli/plugins/xnode.rb +115 -0
  45. data/lib/aspera/cli/transfer_agent.rb +251 -0
  46. data/lib/aspera/cli/version.rb +5 -0
  47. data/lib/aspera/colors.rb +39 -0
  48. data/lib/aspera/command_line_builder.rb +137 -0
  49. data/lib/aspera/fasp/aoc.rb +24 -0
  50. data/lib/aspera/fasp/connect.rb +99 -0
  51. data/lib/aspera/fasp/error.rb +21 -0
  52. data/lib/aspera/fasp/error_info.rb +60 -0
  53. data/lib/aspera/fasp/http_gw.rb +81 -0
  54. data/lib/aspera/fasp/installation.rb +240 -0
  55. data/lib/aspera/fasp/listener.rb +11 -0
  56. data/lib/aspera/fasp/local.rb +377 -0
  57. data/lib/aspera/fasp/manager.rb +69 -0
  58. data/lib/aspera/fasp/node.rb +88 -0
  59. data/lib/aspera/fasp/parameters.rb +235 -0
  60. data/lib/aspera/fasp/resume_policy.rb +76 -0
  61. data/lib/aspera/fasp/uri.rb +51 -0
  62. data/lib/aspera/faspex_gw.rb +196 -0
  63. data/lib/aspera/hash_ext.rb +28 -0
  64. data/lib/aspera/log.rb +80 -0
  65. data/lib/aspera/nagios.rb +71 -0
  66. data/lib/aspera/node.rb +14 -0
  67. data/lib/aspera/oauth.rb +319 -0
  68. data/lib/aspera/on_cloud.rb +421 -0
  69. data/lib/aspera/open_application.rb +72 -0
  70. data/lib/aspera/persistency_action_once.rb +42 -0
  71. data/lib/aspera/persistency_folder.rb +91 -0
  72. data/lib/aspera/preview/file_types.rb +300 -0
  73. data/lib/aspera/preview/generator.rb +258 -0
  74. data/lib/aspera/preview/image_error.png +0 -0
  75. data/lib/aspera/preview/options.rb +35 -0
  76. data/lib/aspera/preview/utils.rb +131 -0
  77. data/lib/aspera/preview/video_error.png +0 -0
  78. data/lib/aspera/proxy_auto_config.erb.js +287 -0
  79. data/lib/aspera/proxy_auto_config.rb +34 -0
  80. data/lib/aspera/rest.rb +296 -0
  81. data/lib/aspera/rest_call_error.rb +13 -0
  82. data/lib/aspera/rest_error_analyzer.rb +98 -0
  83. data/lib/aspera/rest_errors_aspera.rb +58 -0
  84. data/lib/aspera/ssh.rb +53 -0
  85. data/lib/aspera/sync.rb +82 -0
  86. data/lib/aspera/temp_file_manager.rb +37 -0
  87. data/lib/aspera/uri_reader.rb +25 -0
  88. metadata +288 -0
@@ -0,0 +1,216 @@
1
+ require 'aspera/cli/basic_auth_plugin'
2
+ require 'aspera/ascmd'
3
+ require 'aspera/ssh'
4
+ require 'aspera/nagios'
5
+ require 'tempfile'
6
+
7
+ module Aspera
8
+ module Cli
9
+ module Plugins
10
+ # implement basic remote access with FASP/SSH
11
+ class Server < BasicAuthPlugin
12
+ class LocalExecutor
13
+ def execute(cmd,input=nil)
14
+ `#{cmd}`
15
+ end
16
+ end
17
+
18
+ def initialize(env)
19
+ super(env)
20
+ self.options.add_opt_simple(:ssh_keys,'ssh key path list (Array or single)')
21
+ self.options.add_opt_simple(:ssh_options,'ssh options (Hash)')
22
+ self.options.add_opt_simple(:cmd_prefix,'prefix to add for as cmd execution, e.g. sudo or /opt/aspera/bin ')
23
+ self.options.set_option(:ssh_keys,[])
24
+ self.options.set_option(:ssh_options,{})
25
+ self.options.parse_options!
26
+ end
27
+
28
+ def key_symb_to_str_single(source)
29
+ return source.inject({}){|memo,(k,v)| memo[k.to_s] = v; memo}
30
+ end
31
+
32
+ def key_symb_to_str_list(source)
33
+ return source.map{|o| key_symb_to_str_single(o)}
34
+ end
35
+
36
+ def asctl_parse(text)
37
+ r=/:\s*/
38
+ return text.split("\n").map do |line|
39
+ # console
40
+ line.gsub!(/(SessionDataCollector)/,'\1 ')
41
+ # orchestrator
42
+ line.gsub!(/ with pid:.*/,'')
43
+ line.gsub!(/ is /,': ')
44
+ x=line.split(r)
45
+ next unless x.length.eql?(2)
46
+ y={'process'=>x.first,'state'=>x.last}
47
+ # console
48
+ y['state'].gsub!(/\.+$/,'')
49
+ # console
50
+ y['process'].gsub!(/^.+::/,'')
51
+ # faspex
52
+ y['process'].gsub!(/^Faspex /,'')
53
+ # faspex
54
+ y['process'].gsub!(/ Background/,'')
55
+ y['process'].gsub!(/serving orchestrator on port /,'')
56
+ # console
57
+ r=/\s+/ if y['process'].eql?('Console')
58
+ # orchestrator
59
+ y['process'].gsub!(/^ -> /,'')
60
+ y['process'].gsub!(/ Process/,'')
61
+ y
62
+ end.select{|i|!i.nil?}
63
+ end
64
+
65
+ ACTIONS=[:nagios,:nodeadmin,:userdata,:configurator,:ctl,:download,:upload,:browse,:delete,:rename].concat(Aspera::AsCmd::OPERATIONS)
66
+
67
+ def execute_action
68
+ server_uri=URI.parse(self.options.get_option(:url,:mandatory))
69
+ Log.log.debug("URI : #{server_uri}, port=#{server_uri.port}, scheme:#{server_uri.scheme}")
70
+ shell_executor=nil
71
+ case server_uri.scheme
72
+ when 'ssh'
73
+ server_transfer_spec={
74
+ 'remote_host'=>server_uri.hostname,
75
+ 'remote_user'=>self.options.get_option(:username,:mandatory),
76
+ }
77
+ ssh_options=self.options.get_option(:ssh_options,:optional)
78
+ raise 'expecting a Hash for ssh_options' unless ssh_options.is_a?(Hash)
79
+ if !server_uri.port.nil?
80
+ ssh_options[:port]=server_uri.port
81
+ server_transfer_spec['ssh_port']=server_uri.port
82
+ end
83
+ cred_set=false
84
+ password=self.options.get_option(:password,:optional)
85
+ if !password.nil?
86
+ ssh_options[:password]=password
87
+ server_transfer_spec['remote_password']=password
88
+ cred_set=true
89
+ end
90
+ ssh_keys=self.options.get_option(:ssh_keys,:optional)
91
+ if !ssh_keys.nil?
92
+ raise 'expecting single value or array for ssh_keys' unless ssh_keys.is_a?(Array) or ssh_keys.is_a?(String)
93
+ ssh_keys=[ssh_keys] if ssh_keys.is_a?(String)
94
+ ssh_keys.map!{|p|File.expand_path(p)}
95
+ Log.log.debug("ssh keys=#{ssh_keys}")
96
+ ssh_options[:keys]=ssh_keys
97
+ server_transfer_spec['EX_ssh_key_paths']=ssh_keys
98
+ ssh_keys.each do |k|
99
+ Log.log.warn("no such key file: #{k}") unless File.exist?(k)
100
+ end
101
+ cred_set=true
102
+ end
103
+ raise 'either password or key must be provided' if !cred_set
104
+ shell_executor=Ssh.new(server_transfer_spec['remote_host'],server_transfer_spec['remote_user'],ssh_options)
105
+ when 'local'
106
+ shell_executor=LocalExecutor.new
107
+ else
108
+ raise CliError,'Only ssh scheme is supported in url' if !server_uri.scheme.eql?('ssh')
109
+ end
110
+
111
+ # get command and set aliases
112
+ command=self.options.get_next_command(ACTIONS)
113
+ command=:ls if command.eql?(:browse)
114
+ command=:rm if command.eql?(:delete)
115
+ command=:mv if command.eql?(:rename)
116
+ case command
117
+ when :nagios
118
+ nagios=Nagios.new
119
+ command_nagios=self.options.get_next_command([ :app_services, :transfer ])
120
+ case command_nagios
121
+ when :app_services
122
+ # will not work with aspshell, requires Linux/bash
123
+ procs=shell_executor.execute('ps -A -o comm').split("\n")
124
+ Log.log.debug("found: #{procs}")
125
+ ['asperanoded','asperaredisd'].each do |name|
126
+ nagios.add_critical('general',"missing process #{name}") unless procs.include?(name)
127
+ end
128
+ nagios.add_ok('daemons','ok') if nagios.data.empty?
129
+ return nagios.result
130
+ when :transfer
131
+ file = Tempfile.new('transfer_test')
132
+ filepath=file.path
133
+ file.write("This is a test file for transfer test")
134
+ file.close
135
+ probe_ts=server_transfer_spec.merge({
136
+ 'direction' => 'send',
137
+ 'cookie' => 'aspera.sync', # hide in console
138
+ 'resume_policy' => 'none',
139
+ 'paths' => [{'source'=>filepath,'destination'=>'.fasping'}]
140
+ })
141
+ statuses=self.transfer.start(probe_ts,{:src=>:direct})
142
+ file.unlink
143
+ if TransferAgent.session_status(statuses).eql?(:success)
144
+ nagios.add_ok('transfer','ok')
145
+ else
146
+ nagios.add_critical('transfer',statuses.select{|i|!i.eql?(:success)}.first.to_s)
147
+ end
148
+ else raise "ERROR"
149
+ end
150
+ return nagios.result
151
+ when :nodeadmin,:userdata,:configurator,:ctl
152
+ realcmd='as'+command.to_s
153
+ prefix=self.options.get_option(:cmd_prefix,:optional)
154
+ if !prefix.nil?
155
+ realcmd="#{prefix}#{realcmd}"
156
+ end
157
+ args = self.options.get_next_argument("#{realcmd} arguments",:multiple)
158
+ result=shell_executor.execute(args.unshift(realcmd))
159
+ case command
160
+ when :ctl
161
+ return {:type=>:object_list,:data=>asctl_parse(result)}#
162
+ when :configurator
163
+ lines=result.split("\n")
164
+ Log.log.debug(`type asconfigurator`)
165
+ result=lines
166
+ if lines.first.eql?('success')
167
+ lines.shift
168
+ result={}
169
+ lines.each do |line|
170
+ Log.log.debug("#{line}")
171
+ data=line.split(',').map{|i|i.gsub(/^"/,'').gsub(/"$/,'')}.map{|i|case i;when'AS_NULL';nil;when'true';true;when'false';false;else i;end}
172
+ Log.log.debug("#{data}")
173
+ section=data.shift
174
+ datapart=result[section]||={}
175
+ if section.eql?('user')
176
+ name=data.shift
177
+ datapart=datapart[name]||={}
178
+ end
179
+ datapart=datapart[data.shift]={}
180
+ datapart['default']=data.pop
181
+ datapart['value']=data.pop
182
+ end
183
+ return {:type=>:single_object,:data=>result,:fields=>['section','name','value','default'],:option_expand_last=>true}
184
+ end
185
+ end
186
+ return Main.result_status(result)
187
+ when :upload
188
+ return Main.result_transfer(self.transfer.start(server_transfer_spec.merge('direction'=>'send'),{:src=>:direct}))
189
+ when :download
190
+ return Main.result_transfer(self.transfer.start(server_transfer_spec.merge('direction'=>'receive'),{:src=>:direct}))
191
+ when *Aspera::AsCmd::OPERATIONS
192
+ args=self.options.get_next_argument('ascmd command arguments',:multiple,:optional)
193
+ ascmd=Aspera::AsCmd.new(shell_executor)
194
+ begin
195
+ result=ascmd.send(:execute_single,command,args)
196
+ case command
197
+ when :mkdir; return Main.result_success
198
+ when :mv; return Main.result_success
199
+ when :cp; return Main.result_success
200
+ when :rm; return Main.result_success
201
+ when :ls; return {:type=>:object_list,:data=>key_symb_to_str_list(result),:fields=>['zmode','zuid','zgid','size','mtime','name']}
202
+ when :info; return {:type=>:single_object,:data=>key_symb_to_str_single(result)}
203
+ when :df; return {:type=>:object_list,:data=>key_symb_to_str_list(result)}
204
+ when :du; return {:type=>:single_object,:data=>key_symb_to_str_single(result)}
205
+ when :md5sum; return {:type=>:single_object,:data=>key_symb_to_str_single(result)}
206
+ end
207
+ rescue Aspera::AsCmd::Error => e
208
+ raise CliBadArgument,e.extended_message
209
+ end
210
+ else raise "internal error: unexpected action"
211
+ end
212
+ end # execute_action
213
+ end # Server
214
+ end # Plugins
215
+ end # Cli
216
+ end # Aspera
@@ -0,0 +1,63 @@
1
+ require 'aspera/cli/plugins/node'
2
+
3
+ module Aspera
4
+ module Cli
5
+ module Plugins
6
+ class Shares < BasicAuthPlugin
7
+ def initialize(env)
8
+ super(env)
9
+ #self.options.parse_options!
10
+ end
11
+
12
+ ACTIONS=[ :repository,:admin ]
13
+
14
+ def execute_action
15
+ command=self.options.get_next_command(ACTIONS)
16
+ case command
17
+ when :repository
18
+ api_shares_node=basic_auth_api('node_api')
19
+ command=self.options.get_next_command(Node::COMMON_ACTIONS)
20
+ case command
21
+ when *Node::COMMON_ACTIONS; Node.new(@agents.merge(skip_basic_auth_options: true,node_api: api_shares_node)).execute_action(command)
22
+ else raise "INTERNAL ERROR, unknown command: [#{command}]"
23
+ end
24
+ when :admin
25
+ api_shares_admin=basic_auth_api('api/v1')
26
+ command=self.options.get_next_command([:user,:share])
27
+ case command
28
+ when :user
29
+ command=self.options.get_next_command([:list,:id])
30
+ case command
31
+ when :list
32
+ return {:type=>:object_list,:data=>api_shares_admin.read('data/users')[:data],:fields=>['username','email','directory_user','urn']}
33
+ when :id
34
+ res_id=self.options.get_next_argument('user id')
35
+ command=self.options.get_next_command([:app_authorizations,:authorize_share])
36
+ case command
37
+ when :app_authorizations
38
+ return {:type=>:single_object,:data=>api_shares_admin.read("data/users/#{res_id}/app_authorizations")[:data]}
39
+ when :share
40
+ share_name=self.options.get_next_argument('share name')
41
+ all_shares=api_shares_admin.read('data/shares')[:data]
42
+ share_id=all_shares.select{|s| s['name'].eql?(share_name)}.first['id']
43
+ return {:type=>:single_object,:data=>api_shares_admin.create("data/shares/#{share_id}/user_permissions")[:data]}
44
+ end
45
+ end
46
+ when :share
47
+ command=self.options.get_next_command([:list,:name])
48
+ all_shares=api_shares_admin.read('data/shares')[:data]
49
+ case command
50
+ when :list
51
+ return {:type=>:object_list,:data=>all_shares,:fields=>['id','name','status','status_message']}
52
+ when :name
53
+ share_name=self.options.get_next_argument('share name')
54
+ share_id=all_shares.select{|s| s['name'].eql?(share_name)}.first['id']
55
+ raise "TODO"
56
+ end
57
+ end
58
+ end
59
+ end # execute action
60
+ end # Shares
61
+ end # Plugins
62
+ end # Cli
63
+ end # Aspera
@@ -0,0 +1,114 @@
1
+ require 'aspera/cli/plugins/node'
2
+ require 'uri'
3
+
4
+ module Aspera
5
+ module Cli
6
+ module Plugins
7
+ class Shares2 < BasicAuthPlugin
8
+ def initialize(env)
9
+ super(env)
10
+ self.options.add_opt_simple(:organization,"organization")
11
+ self.options.add_opt_simple(:project,"project")
12
+ self.options.add_opt_simple(:share,"share")
13
+ self.options.parse_options!
14
+ return if env[:man_only]
15
+ unless env[:man_only]
16
+ # get parameters
17
+ shares2_api_base_url=self.options.get_option(:url,:mandatory)
18
+ shares2_username=self.options.get_option(:username,:mandatory)
19
+ shares2_password=self.options.get_option(:password,:mandatory)
20
+
21
+ # create object for REST calls to Shares2
22
+ @api_shares2_oauth=Rest.new({
23
+ :base_url => shares2_api_base_url,
24
+ :auth => {
25
+ :type => :oauth2,
26
+ :base_url => shares2_api_base_url+'/oauth2',
27
+ :grant => :header_userpass,
28
+ :user_name => shares2_username,
29
+ :user_pass => shares2_password
30
+ }})
31
+
32
+ @api_node=Rest.new({
33
+ :base_url => shares2_api_base_url+'/node_api',
34
+ :auth => {
35
+ :type => :basic,
36
+ :username => shares2_username,
37
+ :password => shares2_password}})
38
+ end
39
+ end
40
+
41
+ # path_prefix is either "" or "res/id/"
42
+ # adds : prefix+"res/id/"
43
+ # modify parameter string
44
+ def set_resource_path_by_id_or_name(resource_path,resource_sym)
45
+ res_id=self.options.get_option(resource_sym,:mandatory)
46
+ # lets get the class path
47
+ resource_path<<resource_sym.to_s+'s'
48
+ # is this an integer ? or a name
49
+ if res_id.to_i.to_s != res_id
50
+ all=@api_shares2_oauth.read(resource_path)[:data]
51
+ one=all.select{|i|i['name'].start_with?(res_id)}
52
+ Log.log.debug(one)
53
+ raise CliBadArgument,"No matching name for #{res_id} in #{all}" if one.empty?
54
+ raise CliBadArgument,"More than one match: #{one}" if one.length > 1
55
+ res_id=one.first['id'].to_s
56
+ end
57
+ Log.log.debug("res_id=#{res_id}")
58
+ resource_path<<'/'+res_id+'/'
59
+ return resource_path
60
+ end
61
+
62
+ # path_prefix is empty or ends with slash
63
+ def process_entity_action(resource_sym,path_prefix)
64
+ resource_path=path_prefix+resource_sym.to_s+'s'
65
+ operations=[:list,:create,:delete]
66
+ command=self.options.get_next_command(operations)
67
+ case command
68
+ when :create
69
+ params=self.options.get_next_argument("creation data (json structure)")
70
+ resp=@api_shares2_oauth.create(resource_path,params)
71
+ return {:data=>resp[:data],:type => :other_struct}
72
+ when :list
73
+ default_fields=['id','name']
74
+ query=self.options.get_option(:query,:optional)
75
+ args=query.nil? ? nil : {'json_query'=>query}
76
+ Log.log.debug("#{args}".bg_red)
77
+ return {:data=>@api_shares2_oauth.read(resource_path,args)[:data],:fields=>default_fields,:type=>:object_list}
78
+ when :delete
79
+ @api_shares2_oauth.delete(set_resource_path_by_id_or_name(path_prefix,resource_sym))
80
+ return Main.result_status('deleted')
81
+ when :info
82
+ return {:type=>:other_struct,:data=>@api_shares2_oauth.read(set_resource_path_by_id_or_name(path_prefix,resource_sym),args)[:data]}
83
+ else raise :ERROR
84
+ end
85
+ end
86
+
87
+ ACTIONS=[ :repository,:organization,:project,:team,:share,:appinfo,:userinfo,:admin]
88
+
89
+ def execute_action
90
+ command=self.options.get_next_command(ACTIONS)
91
+ case command
92
+ when :repository
93
+ command=self.options.get_next_command(Node::COMMON_ACTIONS)
94
+ return Node.new(@agents.merge(skip_basic_auth_options: true, node_api: @api_node)).execute_action(command)
95
+ when :appinfo
96
+ node_info=@api_node.call({:operation=>'GET',:subpath=>'app',:headers=>{'Accept'=>'application/json','Content-Type'=>'application/json'}})[:data]
97
+ return { :type=>:single_object ,:data => node_info }
98
+ when :userinfo
99
+ node_info=@api_node.call({:operation=>'GET',:subpath=>'current_user',:headers=>{'Accept'=>'application/json','Content-Type'=>'application/json'}})[:data]
100
+ return { :type=>:single_object ,:data => node_info }
101
+ when :organization,:project,:share,:team
102
+ prefix=''
103
+ set_resource_path_by_id_or_name(prefix,:organization) if [:project,:team,:share].include?(command)
104
+ set_resource_path_by_id_or_name(prefix,:project) if [:share].include?(command)
105
+ process_entity_action(command,prefix)
106
+ when :admin
107
+ command=self.options.get_next_command([:users,:groups,:nodes])
108
+ return self.entity_action(@api_shares2_oauth,"system/#{command}",nil,:id)
109
+ end # command
110
+ end # execute_action
111
+ end # Files
112
+ end # Plugins
113
+ end # Cli
114
+ end # Aspera
@@ -0,0 +1,65 @@
1
+ require 'aspera/cli/plugin'
2
+ require 'aspera/sync'
3
+ require 'aspera/log'
4
+ require 'open3'
5
+
6
+ module Aspera
7
+ module Cli
8
+ module Plugins
9
+ # list and download connect client versions, select FASP implementation
10
+ class Sync < Plugin
11
+ def initialize(env)
12
+ super(env)
13
+ self.options.add_opt_simple(:parameters,"extended value for session set definition")
14
+ self.options.add_opt_simple(:session_name,"name of session to use for admin commands, by default first one")
15
+ self.options.parse_options!
16
+ end
17
+
18
+ ACTIONS=[ :start, :admin ]
19
+
20
+ def execute_action
21
+ command=self.options.get_next_command(ACTIONS)
22
+ case command
23
+ when :start
24
+ env_args=Aspera::Sync.new(self.options.get_option(:parameters,:mandatory)).compute_args
25
+ async_bin='async'
26
+ Log.log.debug("execute: #{env_args[:env].map{|k,v| "#{k}=\"#{v}\""}.join(' ')} \"#{async_bin}\" \"#{env_args[:args].join('" "')}\"")
27
+ res=system(env_args[:env],[async_bin,async_bin],*env_args[:args])
28
+ Log.log.debug("result=#{res}")
29
+ case res
30
+ when true; return Main.result_success
31
+ when false; raise "failed: #{$?}"
32
+ when nil; return Main.result_status("not started: #{$?}")
33
+ else raise "internal error: unspecified case"
34
+ end
35
+ when :admin
36
+ p=self.options.get_option(:parameters,:mandatory)
37
+ n=self.options.get_option(:session_name,:optional)
38
+ cmdline=['asyncadmin','--quiet']
39
+ if n.nil?
40
+ session=p['sessions'].first
41
+ else
42
+ session=p['sessions'].select{|s|s['name'].eql?(n)}.first
43
+ end
44
+ cmdline.push('--name='+session['name'])
45
+ if session.has_key?('local_db_dir')
46
+ cmdline.push('--local-db-dir='+session['local_db_dir'])
47
+ else
48
+ cmdline.push('--local-dir='+session['local_dir'])
49
+ end
50
+ command2=self.options.get_next_command([:status])
51
+ case command2
52
+ when :status
53
+ stdout, stderr, status = Open3.capture3(*cmdline)
54
+ Log.log.debug("status=#{status}, stderr=#{stderr}")
55
+ items=stdout.split("\n").inject({}){|m,l|i=l.split(/: */);m[i.first.lstrip]=i.last.lstrip;m}
56
+ return {:type=>:single_object,:data=>items}
57
+ else raise "error"
58
+ end # command
59
+ else raise "error"
60
+ end # command
61
+ end # execute_action
62
+ end # Sync
63
+ end # Plugins
64
+ end # Cli
65
+ end # Aspera