ubalo 0.0.7 → 0.0.8
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/ubalo +169 -19
- data/lib/ubalo.rb +52 -42
- metadata +8 -8
data/bin/ubalo
CHANGED
@@ -43,6 +43,13 @@ def ubalo
|
|
43
43
|
@ubalo
|
44
44
|
end
|
45
45
|
|
46
|
+
def local_config
|
47
|
+
unless @local_config
|
48
|
+
raise "Please run this command from within a local pod directory"
|
49
|
+
end
|
50
|
+
@local_config
|
51
|
+
end
|
52
|
+
|
46
53
|
program_desc 'Command-line access to ubalo.com.'
|
47
54
|
version "0.0.7"
|
48
55
|
|
@@ -112,6 +119,7 @@ end
|
|
112
119
|
def process_download response, destination_path=nil
|
113
120
|
name = response.fetch('name')
|
114
121
|
fullname = response.fetch('fullname')
|
122
|
+
url = response.fetch('url')
|
115
123
|
files = response.fetch('files')
|
116
124
|
destination_path ||= name
|
117
125
|
|
@@ -122,8 +130,8 @@ def process_download response, destination_path=nil
|
|
122
130
|
FileUtils.mkdir(destination_path)
|
123
131
|
FileUtils.mkdir(File.join(destination_path, ".ubalo"))
|
124
132
|
|
125
|
-
File.open(File.join(destination_path, ".ubalo", "
|
126
|
-
f.puts
|
133
|
+
File.open(File.join(destination_path, ".ubalo", "config"), "w") do |f|
|
134
|
+
f.puts(YAML.dump("pod_url" => url, "filenames" => files.keys))
|
127
135
|
end
|
128
136
|
|
129
137
|
files.each do |filename,content|
|
@@ -150,7 +158,7 @@ command :get do |c|
|
|
150
158
|
|
151
159
|
fullname, destination_path = process_download(response)
|
152
160
|
$stderr.puts " done."
|
153
|
-
$stderr.puts "Retrieved #{fullname} into #{destination_path}
|
161
|
+
$stderr.puts "Retrieved #{fullname} into #{destination_path}."
|
154
162
|
end
|
155
163
|
end
|
156
164
|
|
@@ -204,7 +212,6 @@ end
|
|
204
212
|
desc 'Run a pod'
|
205
213
|
arg_name '<pod name>'
|
206
214
|
command :run do |c|
|
207
|
-
|
208
215
|
c.action do |global_options,options,args|
|
209
216
|
pod_name = args.shift
|
210
217
|
unless pod_name
|
@@ -215,43 +222,182 @@ command :run do |c|
|
|
215
222
|
response = ubalo.submit_task(pod_name, args.join(" "))
|
216
223
|
task_label = response['label']
|
217
224
|
|
218
|
-
result = ubalo.
|
225
|
+
result = ubalo.wait_task(task_label)
|
219
226
|
ubalo.show_result(result)
|
220
227
|
end
|
221
228
|
end
|
222
229
|
|
230
|
+
def receive_json_from_stdin
|
231
|
+
if $stdin.tty?
|
232
|
+
raise "please pipe to stdin when using --json"
|
233
|
+
else
|
234
|
+
JSON.parse($stdin.read)
|
235
|
+
end
|
236
|
+
end
|
237
|
+
|
223
238
|
desc 'Submit a pod for running in the background'
|
224
239
|
arg_name '<pod name>'
|
225
240
|
command :submit do |c|
|
241
|
+
c.desc 'Receive JSON from stdin'
|
242
|
+
c.switch :json
|
243
|
+
|
244
|
+
c.action do |global_options,options,args|
|
245
|
+
if options.json
|
246
|
+
args = receive_json_from_stdin
|
247
|
+
result = ubalo.submit_task_json(args)
|
248
|
+
else
|
249
|
+
pod_name = args.shift
|
250
|
+
unless pod_name
|
251
|
+
raise "please specify a pod"
|
252
|
+
end
|
253
|
+
|
254
|
+
$stderr.print "Submitting #{pod_name}..."
|
255
|
+
result = ubalo.submit_task(pod_name, args.join(" "))
|
256
|
+
$stderr.puts " submitted."
|
257
|
+
end
|
258
|
+
ubalo.show_result(result, options.json)
|
259
|
+
end
|
260
|
+
end
|
261
|
+
|
262
|
+
desc 'Check or get the result of a task'
|
263
|
+
arg_name '<task label>'
|
264
|
+
command :check do |c|
|
265
|
+
c.desc 'Get details and give output as JSON'
|
266
|
+
c.switch :json
|
267
|
+
|
268
|
+
c.action do |global_options,options,args|
|
269
|
+
if options.json
|
270
|
+
args = receive_json_from_stdin
|
271
|
+
result = ubalo.check_task_json(args)
|
272
|
+
else
|
273
|
+
task_label = args.first
|
274
|
+
unless task_label
|
275
|
+
raise "please specify a task"
|
276
|
+
end
|
277
|
+
|
278
|
+
$stderr.print "Checking task #{task_label}..."
|
279
|
+
result = ubalo.check_task(task_label)
|
280
|
+
end
|
281
|
+
|
282
|
+
ubalo.show_result(result, options.json)
|
283
|
+
end
|
284
|
+
end
|
285
|
+
|
286
|
+
desc 'Add an ssh key (defaults to ~/.ssh/id_rsa.pub)'
|
287
|
+
arg_name '<file containing ssh key>'
|
288
|
+
command :add_key do |c|
|
289
|
+
c.action do |global_options,options,args|
|
290
|
+
public_key_file = args.shift
|
291
|
+
public_key_file ||= File.expand_path('~/.ssh/id_rsa.pub')
|
292
|
+
|
293
|
+
puts ubalo.upload_key(File.read(public_key_file))["message"]
|
294
|
+
end
|
295
|
+
end
|
296
|
+
|
297
|
+
desc 'Clear all ssh keys'
|
298
|
+
command :clear_keys do |c|
|
299
|
+
c.action do |global_options,options,args|
|
300
|
+
puts ubalo.clear_keys.fetch('message')
|
301
|
+
end
|
302
|
+
end
|
226
303
|
|
304
|
+
desc 'Modify a pod'
|
305
|
+
arg_name '<pod name>'
|
306
|
+
command :edit do |c|
|
227
307
|
c.action do |global_options,options,args|
|
228
308
|
pod_name = args.shift
|
229
309
|
unless pod_name
|
230
310
|
raise "please specify a pod"
|
231
311
|
end
|
232
312
|
|
233
|
-
|
234
|
-
|
235
|
-
|
313
|
+
ubalo.ssh(pod_name)
|
314
|
+
end
|
315
|
+
end
|
236
316
|
|
237
|
-
|
317
|
+
desc 'Push code to Ubalo'
|
318
|
+
command :push do |c|
|
319
|
+
c.action do |global_options,options,args|
|
320
|
+
filenames = local_config['filenames']
|
321
|
+
contents = {}
|
322
|
+
filenames.each do |filename|
|
323
|
+
contents[filename] = File.read(filename)
|
324
|
+
end
|
325
|
+
|
326
|
+
# Don't bother formatting for multiple files just yet.
|
327
|
+
fail unless filenames.length == 1
|
238
328
|
|
329
|
+
print "Uploading changes to #{filenames.first}... "
|
330
|
+
result = ubalo.push(local_config['pod_url'], contents)
|
331
|
+
puts result['message']
|
239
332
|
end
|
240
333
|
end
|
241
334
|
|
242
|
-
desc '
|
243
|
-
|
244
|
-
command :check do |c|
|
335
|
+
desc 'Pull code from Ubalo'
|
336
|
+
command :pull do |c|
|
245
337
|
c.action do |global_options,options,args|
|
246
|
-
|
247
|
-
|
248
|
-
|
338
|
+
print "Pulling changes from Ubalo..."
|
339
|
+
contents = ubalo.pull(local_config['pod_url'])
|
340
|
+
puts " received."
|
341
|
+
|
342
|
+
filenames = local_config['filenames']
|
343
|
+
|
344
|
+
filenames.each do |filename|
|
345
|
+
|
346
|
+
if File.exists?(filename)
|
347
|
+
existing_contents = File.read(filename)
|
348
|
+
else
|
349
|
+
existing_contents = nil
|
350
|
+
end
|
351
|
+
|
352
|
+
if contents[filename] == existing_contents
|
353
|
+
puts "Checking #{filename}... no changes."
|
354
|
+
else
|
355
|
+
hl.choose do |menu|
|
356
|
+
menu.prompt = "Changes made to #{filename}. Overwrite your copy? "
|
357
|
+
menu.choice :yes do
|
358
|
+
open(filename, 'w') do |f|
|
359
|
+
f.puts contents[filename]
|
360
|
+
end
|
361
|
+
puts "Changes saved to #{filename}."
|
362
|
+
end
|
363
|
+
|
364
|
+
menu.choice :no do
|
365
|
+
puts "Cancelled! No changes made to #{filename}."
|
366
|
+
end
|
367
|
+
end
|
368
|
+
end
|
249
369
|
end
|
370
|
+
end
|
371
|
+
end
|
372
|
+
|
373
|
+
desc 'Add an ssh key (defaults to ~/.ssh/id_rsa.pub)'
|
374
|
+
arg_name '<file containing ssh key>'
|
375
|
+
command :add_key do |c|
|
376
|
+
c.action do |global_options,options,args|
|
377
|
+
public_key_file = args.shift
|
378
|
+
public_key_file ||= File.expand_path('~/.ssh/id_rsa.pub')
|
250
379
|
|
251
|
-
|
380
|
+
puts ubalo.upload_key(File.read(public_key_file))["message"]
|
381
|
+
end
|
382
|
+
end
|
252
383
|
|
253
|
-
|
254
|
-
|
384
|
+
desc 'Clear all ssh keys'
|
385
|
+
command :clear_keys do |c|
|
386
|
+
c.action do |global_options,options,args|
|
387
|
+
puts ubalo.clear_keys.fetch('message')
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
desc 'Modify a pod'
|
392
|
+
arg_name '<pod name>'
|
393
|
+
command :edit do |c|
|
394
|
+
c.action do |global_options,options,args|
|
395
|
+
pod_name = args.shift
|
396
|
+
unless pod_name
|
397
|
+
raise "please specify a pod"
|
398
|
+
end
|
399
|
+
|
400
|
+
ubalo.ssh(pod_name)
|
255
401
|
end
|
256
402
|
end
|
257
403
|
|
@@ -294,8 +440,12 @@ pre do |global,command,options,args|
|
|
294
440
|
raise "No credentials found. Please run 'ubalo login'."
|
295
441
|
end
|
296
442
|
|
297
|
-
|
443
|
+
local_config_filename = ".ubalo/config"
|
444
|
+
if File.exists?(local_config_filename)
|
445
|
+
@local_config = YAML.load_file(local_config_filename)
|
446
|
+
end
|
298
447
|
|
448
|
+
@ubalo ||= Ubalo.login(token, connect_url)
|
299
449
|
@debug = global.debug
|
300
450
|
|
301
451
|
true
|
data/lib/ubalo.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
1
|
require 'rest-client'
|
2
2
|
require 'json'
|
3
3
|
require 'open3'
|
4
|
+
require 'pp'
|
4
5
|
|
5
6
|
class String
|
6
7
|
def lfit max_length
|
@@ -74,6 +75,10 @@ class Ubalo
|
|
74
75
|
|
75
76
|
def get(action, params={})
|
76
77
|
url = "#{base_url}/#{action}"
|
78
|
+
url_get(url, params)
|
79
|
+
end
|
80
|
+
|
81
|
+
def url_get url, params={}
|
77
82
|
if token
|
78
83
|
params.merge!({:auth_token => token})
|
79
84
|
end
|
@@ -83,6 +88,10 @@ class Ubalo
|
|
83
88
|
|
84
89
|
def post(action, params={})
|
85
90
|
url = "#{base_url}/#{action}"
|
91
|
+
url_post(url, params)
|
92
|
+
end
|
93
|
+
|
94
|
+
def url_post(url, params={})
|
86
95
|
response = RestClient.post url, {:auth_token => token}.merge(params)
|
87
96
|
parse(response)
|
88
97
|
end
|
@@ -97,26 +106,26 @@ class Ubalo
|
|
97
106
|
end
|
98
107
|
|
99
108
|
def submit_task(pod_name, arg)
|
100
|
-
|
101
|
-
end
|
102
|
-
|
103
|
-
def
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
$stderr.
|
112
|
-
|
113
|
-
sleep 0.5
|
109
|
+
submit_task_json({:pod_name => pod_name, :arg => arg})
|
110
|
+
end
|
111
|
+
|
112
|
+
def submit_task_json hash
|
113
|
+
post(:submit_task, hash)
|
114
|
+
end
|
115
|
+
|
116
|
+
def wait_task(label)
|
117
|
+
60.times do
|
118
|
+
h = check_task(label)
|
119
|
+
if %w{complete failed}.include?(h['state'])
|
120
|
+
$stderr.puts " done."
|
121
|
+
return h
|
114
122
|
end
|
115
|
-
$stderr.
|
116
|
-
|
117
|
-
|
118
|
-
check_task_once(label)
|
123
|
+
$stderr.print '.'
|
124
|
+
$stderr.flush
|
125
|
+
sleep 0.5
|
119
126
|
end
|
127
|
+
$stderr.puts
|
128
|
+
raise "timed-out waiting for task"
|
120
129
|
end
|
121
130
|
|
122
131
|
def upload_key(key)
|
@@ -137,7 +146,7 @@ class Ubalo
|
|
137
146
|
|
138
147
|
def ssh_path(name)
|
139
148
|
h = get(:ssh_path, :pod_name => name)
|
140
|
-
[h['ssh_path'], h['
|
149
|
+
[h['ssh_path'], h['environ_fullname']]
|
141
150
|
end
|
142
151
|
|
143
152
|
def pods
|
@@ -148,27 +157,16 @@ class Ubalo
|
|
148
157
|
ssh_path, environ = ssh_path(pod_name)
|
149
158
|
puts "Opening an ssh connection to edit the '#{environ}' environment for the '#{pod_name}' pod."
|
150
159
|
ssh_command = "ssh -o SendEnv='UBALO_ENVIRON TERM' -tq #{ssh_path}"
|
151
|
-
Process.
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
Process.exec({'UBALO_ENVIRON' => environ}, "scp -o SendEnv=UBALO_ENVIRON #{opts} #{args}")
|
156
|
-
end
|
157
|
-
|
158
|
-
def ls(pod_name, options)
|
159
|
-
ssh_path, environ = ssh_path(pod_name)
|
160
|
-
ssh_command = "ssh -o SendEnv=UBALO_ENVIRON -q #{ssh_path}"
|
161
|
-
out_and_err, status = Open3.capture2e({'UBALO_ENVIRON' => environ}, "#{ssh_command} ls#{options}")
|
162
|
-
out_and_err
|
163
|
-
end
|
164
|
-
|
165
|
-
def show_result(result, verbose=false, json=false)
|
166
|
-
if result['outputs']
|
167
|
-
outputs = JSON.dump(result['outputs'])
|
160
|
+
Process.spawn({'UBALO_ENVIRON' => environ}, ssh_command)
|
161
|
+
pid, status = Process.wait2
|
162
|
+
unless status.success?
|
163
|
+
abort "Error running ssh"
|
168
164
|
end
|
165
|
+
end
|
169
166
|
|
167
|
+
def show_result(result, json=false)
|
170
168
|
if json
|
171
|
-
puts
|
169
|
+
puts JSON.dump(result)
|
172
170
|
else
|
173
171
|
puts " label: #{result['label']}"
|
174
172
|
puts " pod: #{result['pod_name']}"
|
@@ -183,9 +181,9 @@ class Ubalo
|
|
183
181
|
puts "stderr:"
|
184
182
|
puts result['stderr'].indent
|
185
183
|
end
|
186
|
-
if outputs
|
184
|
+
if result['outputs']
|
187
185
|
puts "output:"
|
188
|
-
puts outputs.indent
|
186
|
+
puts result['outputs'].pretty_inspect.indent
|
189
187
|
end
|
190
188
|
end
|
191
189
|
end
|
@@ -202,11 +200,23 @@ class Ubalo
|
|
202
200
|
post(:create_pod, template: type, pod_name: name)
|
203
201
|
end
|
204
202
|
|
205
|
-
|
206
|
-
|
207
|
-
|
203
|
+
def push pod_url, contents
|
204
|
+
url_post("#{pod_url}/api/push", contents: contents)
|
205
|
+
end
|
206
|
+
|
207
|
+
def pull pod_url
|
208
|
+
url_get("#{pod_url}/api/pull")['contents']
|
209
|
+
end
|
210
|
+
|
211
|
+
def check_task label
|
212
|
+
check_task_json({label: label})
|
208
213
|
end
|
209
214
|
|
215
|
+
def check_task_json hash
|
216
|
+
get(:check_task, hash)
|
217
|
+
end
|
218
|
+
|
219
|
+
private
|
210
220
|
def parse(result)
|
211
221
|
JSON.load(result)
|
212
222
|
end
|
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.8
|
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: 2011-12-
|
12
|
+
date: 2011-12-03 00:00:00.000000000Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: gli
|
16
|
-
requirement: &
|
16
|
+
requirement: &2157148100 !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: *2157148100
|
25
25
|
- !ruby/object:Gem::Dependency
|
26
26
|
name: highline
|
27
|
-
requirement: &
|
27
|
+
requirement: &2157147660 !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: *2157147660
|
36
36
|
- !ruby/object:Gem::Dependency
|
37
37
|
name: rest-client
|
38
|
-
requirement: &
|
38
|
+
requirement: &2157147160 !ruby/object:Gem::Requirement
|
39
39
|
none: false
|
40
40
|
requirements:
|
41
41
|
- - ~>
|
@@ -43,7 +43,7 @@ dependencies:
|
|
43
43
|
version: 1.6.3
|
44
44
|
type: :runtime
|
45
45
|
prerelease: false
|
46
|
-
version_requirements: *
|
46
|
+
version_requirements: *2157147160
|
47
47
|
description: CLI and API client for Ubalo
|
48
48
|
email: dev@ubalo.com
|
49
49
|
executables:
|