ubalo 0.0.27 → 0.0.28

Sign up to get free protection for your applications and to get access to all the features.
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: