ubalo 0.0.22 → 0.0.23

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.
Files changed (4) hide show
  1. data/bin/ubalo +33 -79
  2. data/lib/ubalo.rb +60 -69
  3. data/lib/ubalo/version.rb +3 -1
  4. metadata +10 -11
data/bin/ubalo CHANGED
@@ -139,7 +139,9 @@ def process_download response, destination_path=nil
139
139
  end
140
140
 
141
141
  files.each do |filename,content|
142
- File.open(File.join(destination_path, filename), "w") do |f|
142
+ local_filename = File.join(destination_path, filename)
143
+ FileUtils.mkdir_p(File.dirname(local_filename))
144
+ File.open(local_filename, "w") do |f|
143
145
  f.puts content
144
146
  end
145
147
  end
@@ -217,18 +219,24 @@ end
217
219
  desc 'Delete a pod'
218
220
  arg_name '<pod name>'
219
221
  command :delete do |c|
222
+ c.switch :force
223
+
220
224
  c.action do |global_options,options,args|
221
225
  pod_name = normalize_pod_name(args.shift)
222
226
 
223
- hl.choose do |menu|
224
- menu.prompt = "Are you sure you want to delete #{pod_name}? "
225
- menu.choice :yes do
226
- $stderr.print "Deleting #{pod_name}..."
227
- response = ubalo.delete_pod(pod_name)
228
- $stderr.puts " done."
229
- end
230
- menu.choice :no do
231
- raise UbaloMessage, "Cancelled! No changes made to #{pod_name}."
227
+ if options.force
228
+ ubalo.delete_pod(pod_name)
229
+ else
230
+ hl.choose do |menu|
231
+ menu.prompt = "Are you sure you want to delete #{pod_name}? "
232
+ menu.choice :yes do
233
+ $stderr.print "Deleting #{pod_name}..."
234
+ response = ubalo.delete_pod(pod_name)
235
+ $stderr.puts " done."
236
+ end
237
+ menu.choice :no do
238
+ raise UbaloMessage, "Cancelled! No changes made to #{pod_name}."
239
+ end
232
240
  end
233
241
  end
234
242
  end
@@ -237,84 +245,43 @@ end
237
245
  desc 'Run a pod'
238
246
  arg_name '<pod name>'
239
247
  command :run do |c|
240
- c.desc 'Use JSON for input and output'
241
- c.switch :json
242
-
243
248
  c.action do |global_options,options,args|
244
249
  pod_name = normalize_pod_name(args.shift)
245
- if options.json
246
- arg = receive_json_from_stdin
247
- else
248
- arg = args.join(" ")
249
- $stderr.print "Running #{pod_name}..."
250
- end
250
+ arg = args.join(" ")
251
+ $stderr.print "Running #{pod_name}..."
251
252
 
252
253
  response = ubalo.submit_task(pod_name, arg)
253
254
  task_label = response.fetch('label')
254
- result = ubalo.wait_task(task_label, options.json)
255
- ubalo.show_result(result, options.json)
256
- end
257
- end
258
-
259
- def receive_json_from_stdin
260
- if $stdin.tty?
261
- raise UbaloMessage, "please pipe to stdin when using --json"
262
- else
263
- JSON.parse($stdin.read)
255
+ result = ubalo.wait_task(task_label)
256
+ ubalo.show_result(result)
264
257
  end
265
258
  end
266
259
 
267
260
  desc 'Submit a pod for running in the background'
268
261
  arg_name '<pod name>'
269
262
  command :submit do |c|
270
- c.desc 'Receive JSON from stdin'
271
- c.switch :json
272
-
273
263
  c.action do |global_options,options,args|
274
- if options.json
275
- args = receive_json_from_stdin
276
- result = ubalo.submit_task_json(args)
277
- else
278
- pod_name = normalize_pod_name(args.shift)
264
+ pod_name = normalize_pod_name(args.shift)
279
265
 
280
- $stderr.print "Submitting #{pod_name}..."
281
- result = ubalo.submit_task(pod_name, args.join(" "))
282
- $stderr.puts " submitted."
283
- end
284
- ubalo.show_result(result, options.json)
266
+ $stderr.print "Submitting #{pod_name}..."
267
+ result = ubalo.submit_task(pod_name, args.join(" "))
268
+ $stderr.puts " submitted."
269
+
270
+ ubalo.show_result(result)
285
271
  end
286
272
  end
287
273
 
288
274
  desc 'Check or get the result of a task'
289
275
  arg_name '<task label>'
290
276
  command :check do |c|
291
- c.desc 'Get details and give output as JSON'
292
- c.switch :json
293
-
294
277
  c.action do |global_options,options,args|
295
- if options.json
296
- args = receive_json_from_stdin
297
- result = ubalo.check_task_json(args)
298
- else
299
- task_label = args.first
300
-
301
- $stderr.print "Checking task #{task_label}..."
302
- result = ubalo.check_task(task_label)
303
- $stderr.puts " found."
304
- end
278
+ task_label = args.first
305
279
 
306
- ubalo.show_result(result, options.json)
307
- end
308
- end
280
+ $stderr.print "Checking task #{task_label}..."
281
+ result = ubalo.check_task(task_label)
282
+ $stderr.puts " found."
309
283
 
310
- desc 'Stop running a specific task'
311
- arg_name '<task label>'
312
- command :stop do |c|
313
- c.action do |global_options,options,args|
314
- task_label = args.first
315
- $stderr.print "Stopping task #{task_label}..."
316
- result = ubalo.stop_task(task_label)
317
- $stderr.puts " stopped."
284
+ ubalo.show_result(result)
318
285
  end
319
286
  end
320
287
 
@@ -428,19 +395,6 @@ command :unpublish do |c|
428
395
  end
429
396
  end
430
397
 
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
-
444
398
  def unauthorized_command?(command)
445
399
  command && [:login, :help].include?(command.name)
446
400
  end
data/lib/ubalo.rb CHANGED
@@ -51,12 +51,41 @@ class UbaloMessage < StandardError
51
51
  end
52
52
 
53
53
  class Ubalo
54
- class PodError < StandardError
54
+ class UbaloJSON
55
+ def self.content_type
56
+ "application/json; schema=ubalo-data"
57
+ end
58
+
59
+ def self.dump(obj)
60
+ JSON.dump('data' => obj)
61
+ end
62
+
63
+ def self.load(data)
64
+ JSON.load(data)['data']
65
+ end
55
66
  end
56
- class S3Error < PodError
67
+
68
+ class PodError < StandardError
57
69
  end
58
70
 
59
71
  class << self
72
+ def print_content name, content
73
+ data = content.fetch('data')
74
+ content_type = content.fetch('content_type')
75
+ if content_type == UbaloJSON.content_type
76
+ s = UbaloJSON.load(data).pretty_inspect.strip
77
+ if s.include?("\n")
78
+ puts "#{name}:"
79
+ puts s
80
+ else
81
+ puts "#{name}: #{s}"
82
+ end
83
+ else
84
+ puts "#{name}: (#{content_type})"
85
+ puts data.indent
86
+ end
87
+ end
88
+
60
89
  def format_task task
61
90
  "#{task['label']} #{"(#{task['state']})".lfit(10)} - #{task['pod_name']} (#{time_ago_in_words task['submitted_at']})"
62
91
  end
@@ -78,13 +107,13 @@ class Ubalo
78
107
  seconds = Time.now - Time.parse(time)
79
108
  case
80
109
  when seconds < 60
81
- "#{pluralize seconds.floor, "second"} ago"
110
+ "#{pluralize(seconds.floor, "second")} ago"
82
111
  when seconds/60 < 60
83
- "#{pluralize (seconds/60).floor, "minute"} ago"
112
+ "#{pluralize((seconds/60).floor, "minute")} ago"
84
113
  when seconds/60/60 < 24
85
- "#{pluralize (seconds/60/60).floor, "hour"} ago"
114
+ "#{pluralize((seconds/60/60).floor, "hour")} ago"
86
115
  else
87
- "#{pluralize (seconds/60/60/24).floor, "day"} ago"
116
+ "#{pluralize((seconds/60/60/24).floor, "day")} ago"
88
117
  end
89
118
  end
90
119
 
@@ -135,7 +164,7 @@ class Ubalo
135
164
 
136
165
  def whoami
137
166
  response = get("#{base_url}/user")
138
- "You are #{response['username']}, with role #{response['role']}."
167
+ "You are logged in as #{response['username'].inspect}."
139
168
  end
140
169
 
141
170
  def tasks count
@@ -143,7 +172,11 @@ class Ubalo
143
172
  end
144
173
 
145
174
  def submit_task pod_name, arg
146
- post("#{base_url}/pods/#{pod_name}/tasks", :arg => JSON.dump(:data => arg))
175
+ params = {
176
+ :arg_content_type => UbaloJSON.content_type,
177
+ :arg => UbaloJSON.dump(arg)
178
+ }
179
+ post("#{base_url}/pods/#{pod_name}/tasks", params)
147
180
  end
148
181
 
149
182
  def wait_task(label, silent=false)
@@ -173,38 +206,32 @@ class Ubalo
173
206
  get("#{base_url}/pods")
174
207
  end
175
208
 
176
- def stop_task(label)
177
- post("#{base_url}/tasks/#{label}/stop")
178
- end
209
+ def show_result(result)
210
+ puts " label: #{result['label']}"
211
+ puts " pod: #{result['pod_name']}"
212
+ if arg = result['arg']
213
+ Ubalo.print_content(' arg', arg)
214
+ end
179
215
 
180
- def show_result(result, json=false)
181
- if json
182
- puts JSON.dump(result)
183
- else
184
- puts " label: #{result['label']}"
185
- puts " pod: #{result['pod_name']}"
186
- puts " arg: #{result['arg']}"
187
- puts " state: #{result['state']}"
188
- case result['exit_type']
189
- when 'exited'
190
- puts "status: #{result['exit_result']}"
191
- when 'terminated'
192
- puts "terminated with signal: #{result['exit_result']}"
193
- end
216
+ puts " state: #{result['state']}"
217
+
218
+ if container_process = result['container_process']
219
+ puts "status: #{container_process['exit_result']}"
194
220
 
195
- if result['stdout']
221
+ if stdout = container_process['stdout'] and stdout.length > 0
196
222
  puts "stdout:"
197
- puts result['stdout'].indent
223
+ puts stdout.indent
198
224
  end
199
- if result['stderr']
225
+
226
+ if stderr = container_process['stderr'] and stderr.length > 0
200
227
  puts "stderr:"
201
- puts result['stderr'].indent
202
- end
203
- if result['outputs']
204
- puts "output:"
205
- puts result['outputs'].pretty_inspect.indent
228
+ puts stderr.indent
206
229
  end
207
230
  end
231
+
232
+ if outputs = result['outputs']
233
+ Ubalo.print_content('output', outputs)
234
+ end
208
235
  end
209
236
 
210
237
  def get_authorization login, password
@@ -231,10 +258,6 @@ class Ubalo
231
258
  get("#{base_url}/tasks/#{label}")
232
259
  end
233
260
 
234
- def check_task_json hash
235
- check_task(hash[:label])
236
- end
237
-
238
261
  def publish pod_name
239
262
  post("#{base_url}/pods/#{pod_name}/publish")
240
263
  end
@@ -247,39 +270,7 @@ class Ubalo
247
270
  post("#{base_url}/pods/#{pod_name}/unpublish")
248
271
  end
249
272
 
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
-
263
273
  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
-
283
274
 
284
275
  def add_headers headers
285
276
  # Add authorization headers.
data/lib/ubalo/version.rb CHANGED
@@ -1,3 +1,5 @@
1
1
  class Ubalo
2
- VERSION = "0.0.22"
2
+ unless const_defined?('VERSION')
3
+ VERSION = "0.0.23"
4
+ end
3
5
  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.22
4
+ version: 0.0.23
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-02-22 00:00:00.000000000 Z
12
+ date: 2012-03-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gli
16
- requirement: &70246690489020 !ruby/object:Gem::Requirement
16
+ requirement: &70245226856660 !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: *70246690489020
24
+ version_requirements: *70245226856660
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: highline
27
- requirement: &70246690487940 !ruby/object:Gem::Requirement
27
+ requirement: &70245226856180 !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: *70246690487940
35
+ version_requirements: *70245226856180
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: json
38
- requirement: &70246690486780 !ruby/object:Gem::Requirement
38
+ requirement: &70245226855760 !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: *70246690486780
46
+ version_requirements: *70245226855760
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rest-client
49
- requirement: &70246690485440 !ruby/object:Gem::Requirement
49
+ requirement: &70245226855240 !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: *70246690485440
57
+ version_requirements: *70245226855240
58
58
  description: CLI and API client for Ubalo
59
59
  email: dev@ubalo.com
60
60
  executables:
@@ -90,4 +90,3 @@ signing_key:
90
90
  specification_version: 3
91
91
  summary: CLI and API client for Ubalo
92
92
  test_files: []
93
- has_rdoc: