ubalo 0.1 → 0.2

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/lib/ubalo.rb CHANGED
@@ -4,326 +4,14 @@ require 'rest-client'
4
4
  require 'json'
5
5
  require 'pp'
6
6
 
7
- require 'zlib'
8
- require 'archive/tar/minitar'
9
- include Archive::Tar
10
-
11
- def indent str, amount=2
12
- if str
13
- str.each_line.map do |l|
14
- " "*amount + l
15
- end.join
16
- else
17
- ""
18
- end
19
- end
20
-
21
- class UbaloOKExit < StandardError
22
-
23
- end
24
-
25
- class UbaloMessage < StandardError
26
-
27
- end
28
-
29
- class Ubalo
30
- class UbaloJSON
31
- def self.content_type
32
- "application/json; schema=ubalo-data"
33
- end
34
-
35
- def self.dump(obj)
36
- JSON.dump('data' => obj)
37
- end
38
-
39
- def self.load(data)
40
- JSON.load(data)['data']
41
- end
42
- end
43
-
44
- class PodError < StandardError
45
- end
46
-
47
- class << self
48
- def make_tgz file_list, tgz_name
49
- tgz = Zlib::GzipWriter.new(File.open(tgz_name, 'wb'))
50
- Minitar.pack(file_list, tgz)
51
- tgz_name
52
- end
53
-
54
- def extract_tgz destination_dir, tgz_name
55
- Dir.chdir(destination_dir) do
56
- tgz = Zlib::GzipReader.new(File.open(tgz_name, 'rb'))
57
- Minitar.unpack(tgz, '.')
58
- end
59
- end
60
-
61
- def print_content name, content
62
- data = content.fetch('data')
63
- content_type = content.fetch('content_type')
64
- if content_type == UbaloJSON.content_type
65
- s = UbaloJSON.load(data).pretty_inspect.strip
66
- if s.include?("\n")
67
- puts "#{name}:"
68
- puts s
69
- else
70
- puts "#{name}: #{s}"
71
- end
72
- else
73
- puts "#{name}: (#{content_type})"
74
- puts indent(data)
75
- end
76
- end
77
-
78
- def format_task task
79
- "#{task['label']} (#{task['state']}) - #{task['pod_name']} (#{time_ago_in_words task['submitted_at']})"
80
- end
81
-
82
- def format_pod pod
83
- "#{pod.fetch('fullname')} (updated #{time_ago_in_words pod.fetch('updated_at')})"
84
- end
85
-
86
- private
87
- def pluralize count, word
88
- if count == 1
89
- "#{count} #{word}"
90
- else
91
- "#{count} #{word}s"
92
- end
93
- end
94
-
95
- def time_ago_in_words time
96
- seconds = Time.now - Time.parse(time)
97
- case
98
- when seconds < 60
99
- "#{pluralize(seconds.floor, "second")} ago"
100
- when seconds/60 < 60
101
- "#{pluralize((seconds/60).floor, "minute")} ago"
102
- when seconds/60/60 < 24
103
- "#{pluralize((seconds/60/60).floor, "hour")} ago"
104
- else
105
- "#{pluralize((seconds/60/60/24).floor, "day")} ago"
106
- end
107
- end
108
- end
109
-
110
- attr_reader :base_url
111
- attr_accessor :authorization
112
-
113
- def self.login authorization, base_url
114
- new(authorization, base_url)
115
- end
116
-
117
- def initialize authorization, base_url
118
- @authorization = authorization
119
- @base_url = base_url
120
- end
121
-
122
- def raw_request(method, url, params)
123
- resource = RestClient::Resource.new url, timeout: 60
124
- if method == :get
125
- resource.get add_headers(:params => params, :accept => :json)
126
- elsif method == :post
127
- resource.post params, add_headers(:accept => :json)
128
- elsif method == :put
129
- resource.put params, add_headers(:accept => :json)
130
- elsif method == :delete
131
- resource.delete add_headers(:accept => :json)
132
- else
133
- raise "don't understand request method #{method.inspect}"
134
- end
135
- end
136
-
137
- def request(method, url, params)
138
- parse(raw_request(method, url, params))
139
- end
140
-
141
- def post(url, params={})
142
- request(:post, url, params)
143
- end
144
-
145
- def get(url, params={})
146
- request(:get, url, params)
147
- end
148
-
149
- def put(url, params={})
150
- raw_request(:put, url, params)
151
- end
152
-
153
- def delete(url)
154
- raw_request(:delete, url, {})
155
- end
156
-
157
- def whoami
158
- response = get("#{base_url}/user")
159
- "You are logged in as #{response['username'].inspect}."
160
- end
161
-
162
- def tasks count
163
- get("#{base_url}/tasks", :count => count)
164
- end
165
-
166
- def submit_task pod_name, arg
167
- params = {
168
- :arg_content_type => UbaloJSON.content_type,
169
- :arg => UbaloJSON.dump(arg)
170
- }
171
- post("#{base_url}/pods/#{pod_name}/tasks", params)
172
- end
173
-
174
- def poll_on(message)
175
- 600.times do
176
- if result = yield
177
- $stderr.puts " done."
178
- return result
179
- end
180
- $stderr.print '.'
181
- $stderr.flush
182
- sleep 0.5
183
- end
184
-
185
- $stderr.puts
186
- raise "timed-out polling on #{message}"
187
- end
188
-
189
- def wait_task(label)
190
- poll_on("task #{label}") do
191
- task = check_task(label)
192
- task if task['state'] == 'exited'
193
- end
194
- end
195
-
196
- def clone(pod_name)
197
- get("#{base_url}/pods/#{pod_name}")
198
- rescue RestClient::ResourceNotFound
199
- raise UbaloMessage, "could not find #{pod_name}"
200
- end
201
-
202
- def pods
203
- get("#{base_url}/pods")
204
- end
205
-
206
- def show_result(result)
207
- puts " label: #{result['label']}"
208
- puts " pod: #{result['pod_name']}"
209
- if arg = result['arg']
210
- Ubalo.print_content(' arg', arg)
211
- end
212
-
213
- puts " state: #{result['state']}"
214
-
215
- if container_process = result['container_process']
216
- puts "status: #{container_process['exit_result']}"
217
-
218
- if stdout = container_process['stdout'] and stdout.length > 0
219
- puts "stdout:"
220
- puts indent(stdout)
221
- end
222
-
223
- if stderr = container_process['stderr'] and stderr.length > 0
224
- puts "stderr:"
225
- puts indent(stderr)
226
- end
227
- end
228
-
229
- if outputs = result['outputs']
230
- Ubalo.print_content('output', outputs)
231
- end
232
- end
233
-
234
- def get_authorization login, password
235
- post("#{base_url}/user/authorization", :user => {:login => login, :password => password})
236
- end
237
-
238
- def create_or_update pod_url, params={}
239
- put(pod_url, :pod => params)
240
- end
241
-
242
- def check_task label
243
- get("#{base_url}/tasks/#{label}")
244
- end
245
-
246
- def upload_tgz pod_url, tgz_name
247
- # Create the new archive in rails.
248
- response = post("#{pod_url}/archives")
249
- label = response.fetch('label')
250
- put_url = response.fetch('put_url')
251
- archive_location = response.fetch('url')
252
-
253
- print "Uploading files... "
254
- RestClient.put put_url, File.open(tgz_name, 'rb'), content_type: 'application/x-tar', content_encoding: 'x-gzip'
255
- put("#{archive_location}/activate")
256
-
257
- puts "done."
258
- end
259
-
260
- def push_files(pod_url)
261
- ignore_filename = ".ubaloignore"
262
- if File.exist?(ignore_filename)
263
- ignore_patterns = File.read(ignore_filename).each_line.map(&:strip)
264
- else
265
- ignore_patterns = []
266
- end
267
-
268
- ignore_patterns += %w{. .. .ubalo}
269
-
270
- filenames = []
271
- Dir.glob('{.**,**}').each do |path|
272
- next if ignore_patterns.any?{|pattern| File.fnmatch?(pattern, path, File::FNM_DOTMATCH)}
273
-
274
- filenames << path
275
- end
276
-
277
- if filenames.empty?
278
- raise UbaloMessage, "You do not have files to push. Cancelling!"
279
- end
280
-
281
- Dir.mktmpdir do |dir|
282
- tar_path = File.join(dir, "files.tar.gz")
283
- Ubalo.make_tgz(filenames, tar_path)
284
- upload_tgz(pod_url, tar_path)
285
- end
286
-
287
- print "Waiting on pod compilation.."
288
- poll_on("compilation of pod at #{pod_url}") do
289
- pod = get(pod_url)
290
- pod if pod['state'] == 'compiled'
291
- end
292
- end
293
-
294
- def retrieve_files(destination_path, files_url)
295
- Dir.mktmpdir do |dir|
296
- tar_path = File.join(dir, "files.tar.gz")
297
- RestClient.get(files_url) do |response|
298
- if response.code == 200
299
- File.open(tar_path, "wb") do |f|
300
- f.write response
301
- end
302
- Ubalo.extract_tgz(destination_path, tar_path)
303
- else
304
- raise UbaloMessage, "failed to download pod files"
305
- end
306
- end
307
- end
308
- end
309
-
310
- def delete_pod pod_name
311
- delete("#{base_url}/pods/#{pod_name}")
312
- end
313
-
314
- private
315
-
316
- def add_headers headers
317
- # Add authorization headers.
318
- if authorization
319
- headers.merge!(:authorization => authorization)
320
- end
321
-
322
- # Add version header.
323
- headers.merge!('X-Ubalo-Version' => Ubalo::VERSION)
324
- end
325
-
326
- def parse(result)
327
- JSON.load(result)
7
+ require "ubalo/util"
8
+ require "ubalo/account"
9
+ require "ubalo/pod"
10
+ require "ubalo/pod_archive"
11
+ require "ubalo/task"
12
+ require "ubalo/pod_dir"
13
+
14
+ module Ubalo
15
+ class Error < StandardError
328
16
  end
329
17
  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.1'
4
+ version: '0.2'
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-03-30 00:00:00.000000000 Z
12
+ date: 2012-04-03 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gli
16
- requirement: &70153937178120 !ruby/object:Gem::Requirement
16
+ requirement: &70111153539360 !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: *70153937178120
24
+ version_requirements: *70111153539360
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: highline
27
- requirement: &70153937175760 !ruby/object:Gem::Requirement
27
+ requirement: &70111153538720 !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: *70153937175760
35
+ version_requirements: *70111153538720
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: json
38
- requirement: &70153937174580 !ruby/object:Gem::Requirement
38
+ requirement: &70111153538200 !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: *70153937174580
46
+ version_requirements: *70111153538200
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rest-client
49
- requirement: &70153937172960 !ruby/object:Gem::Requirement
49
+ requirement: &70111153537640 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,10 +54,10 @@ dependencies:
54
54
  version: 1.6.3
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70153937172960
57
+ version_requirements: *70111153537640
58
58
  - !ruby/object:Gem::Dependency
59
59
  name: archive-tar-minitar
60
- requirement: &70153937171020 !ruby/object:Gem::Requirement
60
+ requirement: &70111153536860 !ruby/object:Gem::Requirement
61
61
  none: false
62
62
  requirements:
63
63
  - - ! '>='
@@ -65,7 +65,7 @@ dependencies:
65
65
  version: '0'
66
66
  type: :runtime
67
67
  prerelease: false
68
- version_requirements: *70153937171020
68
+ version_requirements: *70111153536860
69
69
  description: CLI and API client for Ubalo
70
70
  email: dev@ubalo.com
71
71
  executables:
@@ -73,6 +73,12 @@ executables:
73
73
  extensions: []
74
74
  extra_rdoc_files: []
75
75
  files:
76
+ - lib/ubalo/account.rb
77
+ - lib/ubalo/pod.rb
78
+ - lib/ubalo/pod_archive.rb
79
+ - lib/ubalo/pod_dir.rb
80
+ - lib/ubalo/task.rb
81
+ - lib/ubalo/util.rb
76
82
  - lib/ubalo/version.rb
77
83
  - lib/ubalo.rb
78
84
  - bin/ubalo
@@ -88,12 +94,18 @@ required_ruby_version: !ruby/object:Gem::Requirement
88
94
  - - ! '>='
89
95
  - !ruby/object:Gem::Version
90
96
  version: '0'
97
+ segments:
98
+ - 0
99
+ hash: -3363828113033122894
91
100
  required_rubygems_version: !ruby/object:Gem::Requirement
92
101
  none: false
93
102
  requirements:
94
103
  - - ! '>='
95
104
  - !ruby/object:Gem::Version
96
105
  version: '0'
106
+ segments:
107
+ - 0
108
+ hash: -3363828113033122894
97
109
  requirements: []
98
110
  rubyforge_project:
99
111
  rubygems_version: 1.8.11
@@ -101,4 +113,3 @@ signing_key:
101
113
  specification_version: 3
102
114
  summary: CLI and API client for Ubalo
103
115
  test_files: []
104
- has_rdoc: