ubalo 0.0.21 → 0.0.22
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.
- data/bin/ubalo +24 -69
- data/lib/ubalo.rb +38 -41
- data/lib/ubalo/version.rb +1 -1
- metadata +11 -11
data/bin/ubalo
CHANGED
@@ -173,6 +173,11 @@ command :create do |c|
|
|
173
173
|
c.flag :template
|
174
174
|
|
175
175
|
c.action do |global_options,options,args|
|
176
|
+
# Request available templates first to provoke 403 if not logged-in
|
177
|
+
# properly.
|
178
|
+
templates = ubalo.available_templates
|
179
|
+
template_names = templates.map{|t| t['name']}.sort
|
180
|
+
|
176
181
|
if options.name
|
177
182
|
pod_name = options.name
|
178
183
|
else
|
@@ -187,9 +192,6 @@ command :create do |c|
|
|
187
192
|
raise UbaloMessage, "directory #{destination_path} already exists, giving up."
|
188
193
|
end
|
189
194
|
|
190
|
-
templates = ubalo.available_templates
|
191
|
-
template_names = templates.map{|t| t['name']}
|
192
|
-
|
193
195
|
if options['template']
|
194
196
|
template_name = options['template']
|
195
197
|
unless template_names.include? template_name
|
@@ -237,7 +239,6 @@ arg_name '<pod name>'
|
|
237
239
|
command :run do |c|
|
238
240
|
c.desc 'Use JSON for input and output'
|
239
241
|
c.switch :json
|
240
|
-
c.switch :ssh
|
241
242
|
|
242
243
|
c.action do |global_options,options,args|
|
243
244
|
pod_name = normalize_pod_name(args.shift)
|
@@ -248,14 +249,10 @@ command :run do |c|
|
|
248
249
|
$stderr.print "Running #{pod_name}..."
|
249
250
|
end
|
250
251
|
|
251
|
-
|
252
|
-
|
253
|
-
|
254
|
-
|
255
|
-
task_label = response.fetch('label')
|
256
|
-
result = ubalo.wait_task(task_label, options.json)
|
257
|
-
ubalo.show_result(result, options.json)
|
258
|
-
end
|
252
|
+
response = ubalo.submit_task(pod_name, arg)
|
253
|
+
task_label = response.fetch('label')
|
254
|
+
result = ubalo.wait_task(task_label, options.json)
|
255
|
+
ubalo.show_result(result, options.json)
|
259
256
|
end
|
260
257
|
end
|
261
258
|
|
@@ -321,26 +318,6 @@ command :stop do |c|
|
|
321
318
|
end
|
322
319
|
end
|
323
320
|
|
324
|
-
desc 'Add an ssh key (defaults to ~/.ssh/id_rsa.pub)'
|
325
|
-
arg_name '<file containing ssh key>'
|
326
|
-
command :add_key do |c|
|
327
|
-
c.action do |global_options,options,args|
|
328
|
-
public_key_file = args.shift
|
329
|
-
public_key_file ||= '~/.ssh/id_rsa.pub'
|
330
|
-
|
331
|
-
response = ubalo.upload_key(File.read(File.expand_path(public_key_file)))
|
332
|
-
puts "Success! Key uploaded."
|
333
|
-
end
|
334
|
-
end
|
335
|
-
|
336
|
-
desc 'Clear your ssh key'
|
337
|
-
command :clear_key do |c|
|
338
|
-
c.action do |global_options,options,args|
|
339
|
-
ubalo.clear_key
|
340
|
-
puts "Success! Key cleared."
|
341
|
-
end
|
342
|
-
end
|
343
|
-
|
344
321
|
desc 'Push files to Ubalo'
|
345
322
|
command :push do |c|
|
346
323
|
c.action do |global_options,options,args|
|
@@ -393,41 +370,6 @@ command :pull do |c|
|
|
393
370
|
end
|
394
371
|
end
|
395
372
|
|
396
|
-
desc 'Edit your environment'
|
397
|
-
command :edit do |c|
|
398
|
-
c.action do |global_options,options,args|
|
399
|
-
username = args.first || local_username
|
400
|
-
puts "Opening an ssh connection to edit the environment belonging to #{username}."
|
401
|
-
ubalo.ssh('edit environment', username)
|
402
|
-
end
|
403
|
-
end
|
404
|
-
|
405
|
-
desc 'Edit your shared data'
|
406
|
-
command "shared:edit" do |c|
|
407
|
-
c.action do |global_options,options,args|
|
408
|
-
username = args.first || local_username
|
409
|
-
puts "Opening an ssh connection to edit the shared data belonging to #{username}."
|
410
|
-
ubalo.ssh('edit shared data', username)
|
411
|
-
end
|
412
|
-
end
|
413
|
-
|
414
|
-
desc 'Copy files to or from your environment'
|
415
|
-
command :cp do |c|
|
416
|
-
c.desc 'copy recursively'
|
417
|
-
c.switch :r
|
418
|
-
|
419
|
-
c.action do |global_options,options,args|
|
420
|
-
opts = ""
|
421
|
-
opts << " -r" if options.r
|
422
|
-
|
423
|
-
scp_args = args.join(" ").gsub(/ubalo(?=:)/) do
|
424
|
-
ubalo.ssh_path
|
425
|
-
end
|
426
|
-
|
427
|
-
ubalo.scp(opts, scp_args, local_username)
|
428
|
-
end
|
429
|
-
end
|
430
|
-
|
431
373
|
desc 'Enter username and password for access'
|
432
374
|
command :login do |c|
|
433
375
|
c.desc "Username"
|
@@ -486,6 +428,19 @@ command :unpublish do |c|
|
|
486
428
|
end
|
487
429
|
end
|
488
430
|
|
431
|
+
|
432
|
+
# XXX testing
|
433
|
+
command :upload do |c|
|
434
|
+
c.action do |global_options,options,args|
|
435
|
+
while filename = args.shift
|
436
|
+
$stderr.print "Uploading #{filename.inspect}..."
|
437
|
+
response = ubalo.s3_put filename
|
438
|
+
$stderr.puts " done."
|
439
|
+
puts "Saved as #{response.inspect}."
|
440
|
+
end
|
441
|
+
end
|
442
|
+
end
|
443
|
+
|
489
444
|
def unauthorized_command?(command)
|
490
445
|
command && [:login, :help].include?(command.name)
|
491
446
|
end
|
@@ -531,8 +486,8 @@ on_error do |exception|
|
|
531
486
|
when RestClient::ResourceNotFound
|
532
487
|
$stderr.puts exception.inspect.sub('404 Resource Not Found', 'Error')
|
533
488
|
false # no additional raise required.
|
534
|
-
when RestClient::Unauthorized
|
535
|
-
$stderr.puts "Invalid credentials. Please
|
489
|
+
when RestClient::Unauthorized, RestClient::Forbidden
|
490
|
+
$stderr.puts "Invalid credentials. Please run ubalo login."
|
536
491
|
true # fall back to GLI's handling
|
537
492
|
when GLI::BadCommandLine
|
538
493
|
true # fall back to GLI's handling
|
data/lib/ubalo.rb
CHANGED
@@ -51,6 +51,11 @@ class UbaloMessage < StandardError
|
|
51
51
|
end
|
52
52
|
|
53
53
|
class Ubalo
|
54
|
+
class PodError < StandardError
|
55
|
+
end
|
56
|
+
class S3Error < PodError
|
57
|
+
end
|
58
|
+
|
54
59
|
class << self
|
55
60
|
def format_task task
|
56
61
|
"#{task['label']} #{"(#{task['state']})".lfit(10)} - #{task['pod_name']} (#{time_ago_in_words task['submitted_at']})"
|
@@ -137,13 +142,8 @@ class Ubalo
|
|
137
142
|
get("#{base_url}/tasks", :count => count)
|
138
143
|
end
|
139
144
|
|
140
|
-
def run_task(pod_name, arg)
|
141
|
-
puts "Running #{pod_name} interactively..."
|
142
|
-
ssh('run task', pod_name, arg)
|
143
|
-
end
|
144
|
-
|
145
145
|
def submit_task pod_name, arg
|
146
|
-
post("#{base_url}/pods/#{pod_name}/tasks", :arg => arg)
|
146
|
+
post("#{base_url}/pods/#{pod_name}/tasks", :arg => JSON.dump(:data => arg))
|
147
147
|
end
|
148
148
|
|
149
149
|
def wait_task(label, silent=false)
|
@@ -165,49 +165,14 @@ class Ubalo
|
|
165
165
|
raise "timed-out waiting for task #{label}"
|
166
166
|
end
|
167
167
|
|
168
|
-
def upload_key(key)
|
169
|
-
put("#{base_url}/user", :user => {:ssh_key => key})
|
170
|
-
end
|
171
|
-
|
172
|
-
def clear_key
|
173
|
-
put("#{base_url}/user", :user => {:ssh_key => nil})
|
174
|
-
end
|
175
|
-
|
176
168
|
def download(pod_name)
|
177
169
|
get("#{base_url}/pods/#{pod_name}/files")
|
178
170
|
end
|
179
171
|
|
180
|
-
def upload_code(name, code)
|
181
|
-
post("#{base_url}/api/upload_code", {:pod_name => name, :code => code})
|
182
|
-
end
|
183
|
-
|
184
|
-
def ssh_path
|
185
|
-
h = get("#{base_url}/api/ssh_path")
|
186
|
-
h.fetch('ssh_path')
|
187
|
-
end
|
188
|
-
|
189
172
|
def pods
|
190
173
|
get("#{base_url}/pods")
|
191
174
|
end
|
192
175
|
|
193
|
-
def ssh(action, *args)
|
194
|
-
ssh_command = "ssh -o SendEnv='UBALO_ARGS UBALO_ACTION TERM' -tq #{ssh_path}"
|
195
|
-
execute(action, args, ssh_command)
|
196
|
-
end
|
197
|
-
|
198
|
-
def scp(opts, command, *args)
|
199
|
-
scp_command = "scp -o SendEnv='UBALO_ARGS UBALO_ACTION' #{opts} #{command}"
|
200
|
-
execute('edit environment', args, scp_command)
|
201
|
-
end
|
202
|
-
|
203
|
-
def execute(action, args, command)
|
204
|
-
Process.spawn({'UBALO_ACTION' => action, 'UBALO_ARGS' => JSON.dump(args)}, command)
|
205
|
-
pid, status = Process.wait2
|
206
|
-
unless status.success?
|
207
|
-
abort "Error running command"
|
208
|
-
end
|
209
|
-
end
|
210
|
-
|
211
176
|
def stop_task(label)
|
212
177
|
post("#{base_url}/tasks/#{label}/stop")
|
213
178
|
end
|
@@ -282,7 +247,39 @@ class Ubalo
|
|
282
247
|
post("#{base_url}/pods/#{pod_name}/unpublish")
|
283
248
|
end
|
284
249
|
|
250
|
+
def s3_put filename
|
251
|
+
username = write_s3cfg_and_get_user
|
252
|
+
|
253
|
+
key = "#{username}/uploads/#{filename}"
|
254
|
+
pid = Process.spawn("s3cmd", "put", filename, "#{root_s3_path}/#{key}", {err: "/dev/null", out: "/dev/null"})
|
255
|
+
_, status = Process.wait2(pid)
|
256
|
+
|
257
|
+
unless status.success?
|
258
|
+
raise Ubalo::S3Error, "could not write file #{filename.inspect} from key #{key.inspect}"
|
259
|
+
end
|
260
|
+
key
|
261
|
+
end
|
262
|
+
|
285
263
|
private
|
264
|
+
def root_s3_path
|
265
|
+
"s3://ubalo/users"
|
266
|
+
end
|
267
|
+
|
268
|
+
def write_s3cfg_and_get_user
|
269
|
+
return @s3cfg_user if @s3cfg_user
|
270
|
+
|
271
|
+
response = put("#{base_url}/user")
|
272
|
+
conf = <<EOS
|
273
|
+
[default]
|
274
|
+
access_key = #{response['amazon_access_key_id']}
|
275
|
+
secret_key = #{response['amazon_secret_access_key']}
|
276
|
+
EOS
|
277
|
+
open(File.expand_path("~/.s3cfg"), "w") do |f|
|
278
|
+
f.write conf
|
279
|
+
end
|
280
|
+
@s3cfg_user = response['username']
|
281
|
+
end
|
282
|
+
|
286
283
|
|
287
284
|
def add_headers headers
|
288
285
|
# Add authorization headers.
|
data/lib/ubalo/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ubalo
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.22
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-02-22 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: gli
|
16
|
-
requirement: &
|
16
|
+
requirement: &70246690489020 !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,10 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements: *
|
24
|
+
version_requirements: *70246690489020
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: highline
|
27
|
-
requirement: &
|
27
|
+
requirement: &70246690487940 !ruby/object:Gem::Requirement
|
28
28
|
none: false
|
29
29
|
requirements:
|
30
30
|
- - ! '>='
|
@@ -32,10 +32,10 @@ dependencies:
|
|
32
32
|
version: '0'
|
33
33
|
type: :runtime
|
34
34
|
prerelease: false
|
35
|
-
version_requirements: *
|
35
|
+
version_requirements: *70246690487940
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: json
|
38
|
-
requirement: &
|
38
|
+
requirement: &70246690486780 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ! '>='
|
@@ -43,10 +43,10 @@ dependencies:
|
|
43
43
|
version: '0'
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *70246690486780
|
47
47
|
- !ruby/object:Gem::Dependency
|
48
48
|
name: rest-client
|
49
|
-
requirement: &
|
49
|
+
requirement: &70246690485440 !ruby/object:Gem::Requirement
|
50
50
|
none: false
|
51
51
|
requirements:
|
52
52
|
- - ~>
|
@@ -54,7 +54,7 @@ dependencies:
|
|
54
54
|
version: 1.6.3
|
55
55
|
type: :runtime
|
56
56
|
prerelease: false
|
57
|
-
version_requirements: *
|
57
|
+
version_requirements: *70246690485440
|
58
58
|
description: CLI and API client for Ubalo
|
59
59
|
email: dev@ubalo.com
|
60
60
|
executables:
|
@@ -85,7 +85,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
85
85
|
version: '0'
|
86
86
|
requirements: []
|
87
87
|
rubyforge_project:
|
88
|
-
rubygems_version: 1.8.
|
88
|
+
rubygems_version: 1.8.11
|
89
89
|
signing_key:
|
90
90
|
specification_version: 3
|
91
91
|
summary: CLI and API client for Ubalo
|