ubalo 0.0.7 → 0.0.8

Sign up to get free protection for your applications and to get access to all the features.
Files changed (3) hide show
  1. data/bin/ubalo +169 -19
  2. data/lib/ubalo.rb +52 -42
  3. 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", "name"), "w") do |f|
126
- f.puts name
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.check_task(task_label, true)
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
- $stderr.print "Submitting #{pod_name}..."
234
- result = ubalo.submit_task(pod_name, args.join(" "))
235
- $stderr.puts " submitted."
313
+ ubalo.ssh(pod_name)
314
+ end
315
+ end
236
316
 
237
- ubalo.show_result(result)
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 'Check or get the result of a task'
243
- arg_name '<task label>'
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
- task_label = args.first
247
- unless task_label
248
- raise "please specify a task"
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
- $stderr.print "Checking task #{task_label}..."
380
+ puts ubalo.upload_key(File.read(public_key_file))["message"]
381
+ end
382
+ end
252
383
 
253
- result = ubalo.check_task(task_label, true)
254
- ubalo.show_result(result, options.verbose, options.json)
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
- @ubalo ||= Ubalo.login(token, connect_url)
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
- post(:submit_task, {:pod_name => pod_name, :arg => arg})
101
- end
102
-
103
- def check_task(label, blocking=false)
104
- if blocking
105
- 60.times do
106
- h = check_task_once(label)
107
- if %w{complete failed}.include?(h['state'])
108
- $stderr.puts " done."
109
- return h
110
- end
111
- $stderr.print '.'
112
- $stderr.flush
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.puts
116
- raise "timed-out waiting for task"
117
- else
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['environ'], h['environ_fullname']]
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.exec({'UBALO_ENVIRON' => environ}, ssh_command)
152
- end
153
-
154
- def scp(environ, opts, args)
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 outputs
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
- private
206
- def check_task_once label
207
- get(:check_task, :label => label)
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.7
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-02 00:00:00.000000000Z
12
+ date: 2011-12-03 00:00:00.000000000Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gli
16
- requirement: &2161042040 !ruby/object:Gem::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: *2161042040
24
+ version_requirements: *2157148100
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: highline
27
- requirement: &2161041600 !ruby/object:Gem::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: *2161041600
35
+ version_requirements: *2157147660
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rest-client
38
- requirement: &2161041080 !ruby/object:Gem::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: *2161041080
46
+ version_requirements: *2157147160
47
47
  description: CLI and API client for Ubalo
48
48
  email: dev@ubalo.com
49
49
  executables: