ubalo 0.0.7 → 0.0.8
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 +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:
|