aspera-cli 4.0.0.pre1

Sign up to get free protection for your applications and to get access to all the features.
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