ubalo 0.0.27 → 0.0.28

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 +24 -89
  2. data/lib/ubalo.rb +83 -17
  3. data/lib/ubalo/version.rb +1 -1
  4. metadata +21 -10
data/bin/ubalo CHANGED
@@ -55,6 +55,8 @@ def normalize_pod_name(pod_name)
55
55
  else
56
56
  "#{local_username}/#{pod_name}"
57
57
  end
58
+ else
59
+ raise UbaloMessage, "Please specify a pod name"
58
60
  end
59
61
  end
60
62
 
@@ -123,8 +125,8 @@ end
123
125
  def process_download pod_response, destination_path=nil
124
126
  name = pod_response.fetch('name')
125
127
  fullname = pod_response.fetch('fullname')
126
- url = pod_response.fetch('url')
127
- files = pod_response.fetch('files')
128
+ pod_url = pod_response.fetch('url')
129
+ files_url = pod_response.fetch('archive').fetch('get_url')
128
130
 
129
131
  destination_path ||= name
130
132
 
@@ -135,16 +137,10 @@ def process_download pod_response, destination_path=nil
135
137
  FileUtils.mkdir(destination_path)
136
138
  FileUtils.mkdir(File.join(destination_path, ".ubalo"))
137
139
 
138
- File.open(File.join(destination_path, ".ubalo", "config"), "w") do |f|
139
- f.puts(YAML.dump("pod_url" => url))
140
- end
140
+ ubalo.retrieve_files(destination_path, files_url)
141
141
 
142
- files.each do |filename,content|
143
- local_filename = File.join(destination_path, filename)
144
- FileUtils.mkdir_p(File.dirname(local_filename))
145
- File.open(local_filename, "w") do |f|
146
- f.write content
147
- end
142
+ File.open(File.join(destination_path, ".ubalo", "config"), "w") do |f|
143
+ f.puts(YAML.dump("pod_url" => pod_url))
148
144
  end
149
145
 
150
146
  [fullname, destination_path]
@@ -158,62 +154,10 @@ command :clone do |c|
158
154
  destination_path = args.shift
159
155
 
160
156
  $stderr.print "Fetching #{pod_name}..."
161
- pod_response = ubalo.download(pod_name)
162
-
163
- fullname, destination_path = process_download(pod_response)
164
- $stderr.puts " done."
165
- $stderr.puts "Retrieved #{fullname} into #{destination_path}."
166
- end
167
- end
168
-
169
- desc 'Create a new pod'
170
- arg_name '<pod name>'
171
- command :create do |c|
172
-
173
- c.desc "Pod name"
174
- c.flag :name
175
- c.desc "Pod template"
176
- c.flag :template
177
-
178
- c.action do |global_options,options,args|
179
- # Request available templates first to provoke 403 if not logged-in
180
- # properly.
181
- templates = ubalo.available_templates
182
- template_names = templates.map{|t| t['name']}.sort
183
-
184
- if options.name
185
- pod_name = options.name
186
- else
187
- pod_name = hl.ask("New pod name: ")
188
- if pod_name.empty?
189
- raise UbaloMessage, "No pod name given"
190
- end
191
- end
192
- destination_path = pod_name
193
-
194
- if File.exists?(pod_name)
195
- raise UbaloMessage, "directory #{destination_path} already exists, giving up."
196
- end
197
-
198
- if options['template']
199
- template_name = options['template']
200
- unless template_names.include? template_name
201
- raise UbaloMessage, "Invalid template name"
202
- end
203
- else
204
- template_name = hl.choose do |menu|
205
- menu.prompt = "Template for your new pod: "
206
- menu.choices(*template_names)
207
- end
208
- end
209
-
210
- $stderr.print "Creating a new #{template_name} pod called #{pod_name}..."
211
- pod_response, files_response = ubalo.create_pod(pod_name, template_name)
157
+ pod_response = ubalo.clone(pod_name)
212
158
 
213
159
  fullname, destination_path = process_download(pod_response)
214
-
215
- $stderr.puts " done."
216
- $stderr.puts "Created #{fullname} and placed in #{destination_path}/."
160
+ $stderr.puts " saved to #{destination_path}."
217
161
  end
218
162
  end
219
163
 
@@ -286,34 +230,25 @@ command :check do |c|
286
230
  end
287
231
  end
288
232
 
289
- desc 'Push files to Ubalo'
290
- command :push do |c|
233
+ desc 'Pushes a pod directory directly to Ubalo'
234
+ command :push_to do |c|
291
235
  c.action do |global_options,options,args|
292
- pod_url = local_config.fetch('pod_url')
293
-
294
- if File.exist?(".ubaloignore")
295
- ignore_patterns = File.read(".ubaloignore").each_line.map(&:strip)
296
- else
297
- ignore_patterns = []
298
- end
299
-
300
- ignore_patterns += %w{. .. .ubalo}
301
-
302
- filenames = []
303
- Dir.glob('{.**,**}').each do |path|
304
- next if ignore_patterns.any?{|pattern| File.fnmatch?(pattern, path, File::FNM_DOTMATCH)}
236
+ pod_name = normalize_pod_name(args.shift)
305
237
 
306
- filenames << path
307
- end
238
+ # First ensure that the pod exists.
239
+ pod_url = "#{ubalo.base_url}/pods/#{pod_name}"
240
+ pod = ubalo.create_or_update(pod_url)
308
241
 
309
- files = {}
310
- filenames.each do |filename|
311
- files[filename] = File.read(filename)
312
- end
242
+ # Now push the files archive.
243
+ ubalo.push_files(pod_url)
244
+ end
245
+ end
313
246
 
314
- print "Uploading changes... "
315
- result = ubalo.push(pod_url, files)
316
- puts "Code changes saved."
247
+ desc 'Push files to Ubalo'
248
+ command :push do |c|
249
+ c.action do |global_options,options,args|
250
+ pod_url = local_config.fetch('pod_url')
251
+ ubalo.push_files(pod_url)
317
252
  end
318
253
  end
319
254
 
data/lib/ubalo.rb CHANGED
@@ -4,6 +4,10 @@ require 'json'
4
4
  require 'open3'
5
5
  require 'pp'
6
6
 
7
+ require 'zlib'
8
+ require 'archive/tar/minitar'
9
+ include Archive::Tar
10
+
7
11
  class String
8
12
  def lfit max_length
9
13
  if length - 3 <= max_length
@@ -69,6 +73,23 @@ class Ubalo
69
73
  end
70
74
 
71
75
  class << self
76
+ def tgz_filename
77
+ "ubalo-files.tar.gz"
78
+ end
79
+
80
+ def make_tgz file_list, tgz_name
81
+ tgz = Zlib::GzipWriter.new(File.open(tgz_name, 'wb'))
82
+ Minitar.pack(file_list, tgz)
83
+ tgz_name
84
+ end
85
+
86
+ def extract_tgz destination_dir, tgz_name
87
+ Dir.chdir(destination_dir) do
88
+ tgz = Zlib::GzipReader.new(File.open(tgz_name, 'rb'))
89
+ Minitar.unpack(tgz, '.')
90
+ end
91
+ end
92
+
72
93
  def print_content name, content
73
94
  data = content.fetch('data')
74
95
  content_type = content.fetch('content_type')
@@ -116,7 +137,6 @@ class Ubalo
116
137
  "#{pluralize((seconds/60/60/24).floor, "day")} ago"
117
138
  end
118
139
  end
119
-
120
140
  end
121
141
 
122
142
  attr_reader :base_url
@@ -132,14 +152,15 @@ class Ubalo
132
152
  end
133
153
 
134
154
  def raw_request(method, url, params)
155
+ resource = RestClient::Resource.new url, timeout: 60
135
156
  if method == :get
136
- RestClient.get url, add_headers(:params => params, :accept => :json)
157
+ resource.get add_headers(:params => params, :accept => :json)
137
158
  elsif method == :post
138
- RestClient.post url, params, add_headers(:accept => :json)
159
+ resource.post params, add_headers(:accept => :json)
139
160
  elsif method == :put
140
- RestClient.put url, params, add_headers(:accept => :json)
161
+ resource.put params, add_headers(:accept => :json)
141
162
  elsif method == :delete
142
- RestClient.delete url, add_headers(:accept => :json)
163
+ resource.delete add_headers(:accept => :json)
143
164
  else
144
165
  raise "don't understand request method #{method.inspect}"
145
166
  end
@@ -158,11 +179,11 @@ class Ubalo
158
179
  end
159
180
 
160
181
  def put(url, params={})
161
- request(:put, url, params)
182
+ raw_request(:put, url, params)
162
183
  end
163
184
 
164
185
  def delete(url)
165
- request(:delete, url, {})
186
+ raw_request(:delete, url, {})
166
187
  end
167
188
 
168
189
  def whoami
@@ -183,7 +204,7 @@ class Ubalo
183
204
  end
184
205
 
185
206
  def wait_task(label, silent=false)
186
- 60.times do
207
+ 600.times do
187
208
  h = check_task(label)
188
209
  if h['state'] == 'exited'
189
210
  unless silent
@@ -201,7 +222,7 @@ class Ubalo
201
222
  raise "timed-out waiting for task #{label}"
202
223
  end
203
224
 
204
- def download(pod_name)
225
+ def clone(pod_name)
205
226
  get("#{base_url}/pods/#{pod_name}")
206
227
  rescue RestClient::ResourceNotFound
207
228
  raise UbaloMessage, "could not find #{pod_name}"
@@ -243,20 +264,65 @@ class Ubalo
243
264
  post("#{base_url}/user/authorization", :user => {:login => login, :password => password})
244
265
  end
245
266
 
246
- def available_templates
247
- get("#{base_url}/templates")
267
+ def create_or_update pod_url, params={}
268
+ put(pod_url, :pod => params)
248
269
  end
249
270
 
250
- def create_pod name, template
251
- post("#{base_url}/templates/#{template}/pods", :pod => {:name => name})
271
+ def check_task label
272
+ get("#{base_url}/tasks/#{label}")
252
273
  end
253
274
 
254
- def push pod_url, files
255
- raw_request(:put, "#{pod_url}", :pod => {:files => files})
275
+ def upload_tgz pod_url, tgz_name
276
+ # Create the new archive in rails.
277
+ response = post("#{pod_url}/archives")
278
+ label = response.fetch('label')
279
+ put_url = response.fetch('put_url')
280
+ archive_location = response.fetch('url')
281
+
282
+ print "Uploading files... "
283
+ RestClient.put put_url, File.open(tgz_name, 'rb'), content_type: 'application/x-tar', content_encoding: 'x-gzip'
284
+ put("#{archive_location}/activate")
285
+
286
+ puts "done."
256
287
  end
257
288
 
258
- def check_task label
259
- get("#{base_url}/tasks/#{label}")
289
+ def push_files(pod_url)
290
+ ignore_filename = ".ubaloignore"
291
+ if File.exist?(ignore_filename)
292
+ ignore_patterns = File.read(ignore_filename).each_line.map(&:strip)
293
+ else
294
+ ignore_patterns = []
295
+ end
296
+
297
+ ignore_patterns += %w{. .. .ubalo ubalo-files.tar.gz}
298
+
299
+ filenames = []
300
+ Dir.glob('{.**,**}').each do |path|
301
+ next if ignore_patterns.any?{|pattern| File.fnmatch?(pattern, path, File::FNM_DOTMATCH)}
302
+
303
+ filenames << path
304
+ end
305
+
306
+ begin
307
+ Ubalo.make_tgz(filenames, Ubalo.tgz_filename)
308
+ upload_tgz(pod_url, Ubalo.tgz_filename)
309
+ ensure
310
+ FileUtils.rm_f(Ubalo.tgz_filename)
311
+ end
312
+ end
313
+
314
+ def retrieve_files(destination_path, files_url)
315
+ # First retrieve the S3 URL.
316
+ RestClient.get(files_url) do |response|
317
+ if response.code == 200
318
+ File.open(File.join(destination_path, Ubalo.tgz_filename), "wb") do |f|
319
+ f.write response
320
+ end
321
+ Ubalo.extract_tgz(destination_path, Ubalo.tgz_filename)
322
+ else
323
+ raise UbaloMessage, "failed to download pod files"
324
+ end
325
+ end
260
326
  end
261
327
 
262
328
  def publish pod_name
data/lib/ubalo/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  class Ubalo
2
2
  unless const_defined?('VERSION')
3
- VERSION = "0.0.27"
3
+ VERSION = "0.0.28"
4
4
  end
5
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.27
4
+ version: 0.0.28
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-23 00:00:00.000000000 Z
12
+ date: 2012-03-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: gli
16
- requirement: &70147294336420 !ruby/object:Gem::Requirement
16
+ requirement: &70105707914620 !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: *70147294336420
24
+ version_requirements: *70105707914620
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: highline
27
- requirement: &70147294335260 !ruby/object:Gem::Requirement
27
+ requirement: &70105707914160 !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: *70147294335260
35
+ version_requirements: *70105707914160
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: json
38
- requirement: &70147294334080 !ruby/object:Gem::Requirement
38
+ requirement: &70105707827700 !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: *70147294334080
46
+ version_requirements: *70105707827700
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: rest-client
49
- requirement: &70147294327800 !ruby/object:Gem::Requirement
49
+ requirement: &70105707826560 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ~>
@@ -54,7 +54,18 @@ dependencies:
54
54
  version: 1.6.3
55
55
  type: :runtime
56
56
  prerelease: false
57
- version_requirements: *70147294327800
57
+ version_requirements: *70105707826560
58
+ - !ruby/object:Gem::Dependency
59
+ name: archive-tar-minitar
60
+ requirement: &70105707825660 !ruby/object:Gem::Requirement
61
+ none: false
62
+ requirements:
63
+ - - ! '>='
64
+ - !ruby/object:Gem::Version
65
+ version: '0'
66
+ type: :runtime
67
+ prerelease: false
68
+ version_requirements: *70105707825660
58
69
  description: CLI and API client for Ubalo
59
70
  email: dev@ubalo.com
60
71
  executables: