cfoundry 0.3.19 → 0.3.20
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/cfoundry/upload_helpers.rb +100 -0
- data/lib/cfoundry/v1/app.rb +4 -91
- data/lib/cfoundry/v2/app.rb +61 -3
- data/lib/cfoundry/v2/base.rb +21 -0
- data/lib/cfoundry/v2/model.rb +2 -2
- data/lib/cfoundry/version.rb +1 -1
- metadata +6 -5
@@ -0,0 +1,100 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "pathname"
|
3
|
+
require "digest/sha1"
|
4
|
+
|
5
|
+
module CFoundry
|
6
|
+
module UploadHelpers
|
7
|
+
# Default paths to exclude from upload payload.
|
8
|
+
UPLOAD_EXCLUDE = %w{.git _darcs .svn}
|
9
|
+
|
10
|
+
def make_fingerprints(path)
|
11
|
+
fingerprints = []
|
12
|
+
total_size = 0
|
13
|
+
|
14
|
+
Dir.glob("#{path}/**/*", File::FNM_DOTMATCH) do |filename|
|
15
|
+
next if File.directory?(filename)
|
16
|
+
|
17
|
+
size = File.size(filename)
|
18
|
+
|
19
|
+
total_size += size
|
20
|
+
|
21
|
+
fingerprints << {
|
22
|
+
:size => size,
|
23
|
+
:sha1 => Digest::SHA1.file(filename).hexdigest,
|
24
|
+
:fn => filename
|
25
|
+
}
|
26
|
+
end
|
27
|
+
|
28
|
+
[fingerprints, total_size]
|
29
|
+
end
|
30
|
+
|
31
|
+
def prepare_package(path, to)
|
32
|
+
if path =~ /\.(jar|war|zip)$/
|
33
|
+
CFoundry::Zip.unpack(path, to)
|
34
|
+
elsif war_file = Dir.glob("#{path}/*.war").first
|
35
|
+
CFoundry::Zip.unpack(war_file, to)
|
36
|
+
else
|
37
|
+
check_unreachable_links(path)
|
38
|
+
|
39
|
+
FileUtils.mkdir(to)
|
40
|
+
|
41
|
+
files = Dir.glob("#{path}/{*,.[^\.]*}")
|
42
|
+
|
43
|
+
exclude = UPLOAD_EXCLUDE
|
44
|
+
if File.exists?("#{path}/.vmcignore")
|
45
|
+
exclude += File.read("#{path}/.vmcignore").split(/\n+/)
|
46
|
+
end
|
47
|
+
|
48
|
+
# prevent initial copying if we can, remove sub-files later
|
49
|
+
files.reject! do |f|
|
50
|
+
exclude.any? do |e|
|
51
|
+
File.fnmatch(f.sub(path + "/", ""), e)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
FileUtils.cp_r(files, to)
|
56
|
+
|
57
|
+
find_sockets(to).each do |s|
|
58
|
+
File.delete s
|
59
|
+
end
|
60
|
+
|
61
|
+
# remove ignored globs more thoroughly
|
62
|
+
#
|
63
|
+
# note that the above file list only includes toplevel
|
64
|
+
# files/directories for cp_r, so this is where sub-files/etc. are
|
65
|
+
# removed
|
66
|
+
exclude.each do |e|
|
67
|
+
Dir.glob("#{to}/#{e}").each do |f|
|
68
|
+
FileUtils.rm_rf(f)
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def check_unreachable_links(path)
|
75
|
+
files = Dir.glob("#{path}/**/*", File::FNM_DOTMATCH)
|
76
|
+
|
77
|
+
# only used for friendlier error message
|
78
|
+
pwd = Pathname.pwd
|
79
|
+
|
80
|
+
abspath = File.expand_path(path)
|
81
|
+
unreachable = []
|
82
|
+
files.each do |f|
|
83
|
+
file = Pathname.new(f)
|
84
|
+
if file.symlink? && !file.realpath.to_s.start_with?(abspath)
|
85
|
+
unreachable << file.relative_path_from(pwd)
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
unless unreachable.empty?
|
90
|
+
root = Pathname.new(path).relative_path_from(pwd)
|
91
|
+
raise "Can't deploy application containing links '#{unreachable}' that reach outside its root '#{root}'"
|
92
|
+
end
|
93
|
+
end
|
94
|
+
|
95
|
+
def find_sockets(path)
|
96
|
+
files = Dir.glob("#{path}/**/*", File::FNM_DOTMATCH)
|
97
|
+
files && files.select { |f| File.socket? f }
|
98
|
+
end
|
99
|
+
end
|
100
|
+
end
|
data/lib/cfoundry/v1/app.rb
CHANGED
@@ -1,9 +1,7 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
require "digest/sha1"
|
3
|
-
require "pathname"
|
4
1
|
require "tmpdir"
|
5
2
|
|
6
3
|
require "cfoundry/zip"
|
4
|
+
require "cfoundry/upload_helpers"
|
7
5
|
require "cfoundry/chatty_hash"
|
8
6
|
|
9
7
|
require "cfoundry/v1/framework"
|
@@ -17,6 +15,8 @@ module CFoundry::V1
|
|
17
15
|
# retrieval, as the attributes are all lazily retrieved. Setting attributes
|
18
16
|
# does not perform any requests; use #update! to commit your changes.
|
19
17
|
class App
|
18
|
+
include CFoundry::UploadHelpers
|
19
|
+
|
20
20
|
# Application name.
|
21
21
|
attr_accessor :name
|
22
22
|
|
@@ -323,9 +323,6 @@ module CFoundry::V1
|
|
323
323
|
Instance.new(@name, 0, @client).file(*path)
|
324
324
|
end
|
325
325
|
|
326
|
-
# Default paths to exclude from upload payload.
|
327
|
-
UPLOAD_EXCLUDE = %w{.git _darcs .svn}
|
328
|
-
|
329
326
|
# Upload application's code to target. Do this after #create! and before
|
330
327
|
# #start!
|
331
328
|
#
|
@@ -443,69 +440,11 @@ module CFoundry::V1
|
|
443
440
|
}
|
444
441
|
end
|
445
442
|
|
446
|
-
def prepare_package(path, to)
|
447
|
-
if path =~ /\.(jar|war|zip)$/
|
448
|
-
CFoundry::Zip.unpack(path, to)
|
449
|
-
elsif war_file = Dir.glob("#{path}/*.war").first
|
450
|
-
CFoundry::Zip.unpack(war_file, to)
|
451
|
-
else
|
452
|
-
check_unreachable_links(path)
|
453
|
-
|
454
|
-
FileUtils.mkdir(to)
|
455
|
-
|
456
|
-
files = Dir.glob("#{path}/{*,.[^\.]*}")
|
457
|
-
|
458
|
-
exclude = UPLOAD_EXCLUDE
|
459
|
-
if File.exists?("#{path}/.vmcignore")
|
460
|
-
exclude += File.read("#{path}/.vmcignore").split(/\n+/)
|
461
|
-
end
|
462
|
-
|
463
|
-
# prevent initial copying if we can, remove sub-files later
|
464
|
-
files.reject! do |f|
|
465
|
-
exclude.any? do |e|
|
466
|
-
File.fnmatch(f.sub(path + "/", ""), e)
|
467
|
-
end
|
468
|
-
end
|
469
|
-
|
470
|
-
FileUtils.cp_r(files, to)
|
471
|
-
|
472
|
-
find_sockets(to).each do |s|
|
473
|
-
File.delete s
|
474
|
-
end
|
475
|
-
|
476
|
-
# remove ignored globs more thoroughly
|
477
|
-
#
|
478
|
-
# note that the above file list only includes toplevel
|
479
|
-
# files/directories for cp_r, so this is where sub-files/etc. are
|
480
|
-
# removed
|
481
|
-
exclude.each do |e|
|
482
|
-
Dir.glob("#{to}/#{e}").each do |f|
|
483
|
-
FileUtils.rm_rf(f)
|
484
|
-
end
|
485
|
-
end
|
486
|
-
end
|
487
|
-
end
|
488
|
-
|
489
443
|
# Minimum size for an application payload to bother checking resources.
|
490
444
|
RESOURCE_CHECK_LIMIT = 64 * 1024
|
491
445
|
|
492
446
|
def determine_resources(path)
|
493
|
-
fingerprints =
|
494
|
-
total_size = 0
|
495
|
-
|
496
|
-
Dir.glob("#{path}/**/*", File::FNM_DOTMATCH) do |filename|
|
497
|
-
next if File.directory?(filename)
|
498
|
-
|
499
|
-
size = File.size(filename)
|
500
|
-
|
501
|
-
total_size += size
|
502
|
-
|
503
|
-
fingerprints << {
|
504
|
-
:size => size,
|
505
|
-
:sha1 => Digest::SHA1.file(filename).hexdigest,
|
506
|
-
:fn => filename
|
507
|
-
}
|
508
|
-
end
|
447
|
+
fingerprints, total_size = make_fingerprints(path)
|
509
448
|
|
510
449
|
return if total_size <= RESOURCE_CHECK_LIMIT
|
511
450
|
|
@@ -519,32 +458,6 @@ module CFoundry::V1
|
|
519
458
|
resources
|
520
459
|
end
|
521
460
|
|
522
|
-
def check_unreachable_links(path)
|
523
|
-
files = Dir.glob("#{path}/**/*", File::FNM_DOTMATCH)
|
524
|
-
|
525
|
-
# only used for friendlier error message
|
526
|
-
pwd = Pathname.pwd
|
527
|
-
|
528
|
-
abspath = File.expand_path(path)
|
529
|
-
unreachable = []
|
530
|
-
files.each do |f|
|
531
|
-
file = Pathname.new(f)
|
532
|
-
if file.symlink? && !file.realpath.to_s.start_with?(abspath)
|
533
|
-
unreachable << file.relative_path_from(pwd)
|
534
|
-
end
|
535
|
-
end
|
536
|
-
|
537
|
-
unless unreachable.empty?
|
538
|
-
root = Pathname.new(path).relative_path_from(pwd)
|
539
|
-
raise "Can't deploy application containing links '#{unreachable}' that reach outside its root '#{root}'"
|
540
|
-
end
|
541
|
-
end
|
542
|
-
|
543
|
-
def find_sockets(path)
|
544
|
-
files = Dir.glob("#{path}/**/*", File::FNM_DOTMATCH)
|
545
|
-
files && files.select { |f| File.socket? f }
|
546
|
-
end
|
547
|
-
|
548
461
|
# Class represnting a running instance of an application.
|
549
462
|
class Instance
|
550
463
|
# The application this instance belongs to.
|
data/lib/cfoundry/v2/app.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
|
-
require "fileutils"
|
2
|
-
require "digest/sha1"
|
3
|
-
require "pathname"
|
4
1
|
require "tmpdir"
|
5
2
|
require "json"
|
6
3
|
|
7
4
|
require "cfoundry/zip"
|
5
|
+
require "cfoundry/upload_helpers"
|
8
6
|
require "cfoundry/chatty_hash"
|
9
7
|
|
10
8
|
require "cfoundry/v2/model"
|
@@ -17,6 +15,8 @@ module CFoundry::V2
|
|
17
15
|
# retrieval, as the attributes are all lazily retrieved. Setting attributes
|
18
16
|
# does not perform any requests; use #update! to commit your changes.
|
19
17
|
class App < Model
|
18
|
+
include CFoundry::UploadHelpers
|
19
|
+
|
20
20
|
attribute :name
|
21
21
|
attribute :production
|
22
22
|
to_one :space
|
@@ -154,5 +154,63 @@ module CFoundry::V2
|
|
154
154
|
b.service_instance == instance
|
155
155
|
}
|
156
156
|
end
|
157
|
+
|
158
|
+
# Upload application's code to target. Do this after #create! and before
|
159
|
+
# #start!
|
160
|
+
#
|
161
|
+
# [path]
|
162
|
+
# A path pointing to either a directory, or a .jar, .war, or .zip
|
163
|
+
# file.
|
164
|
+
#
|
165
|
+
# If a .vmcignore file is detected under the given path, it will be used
|
166
|
+
# to exclude paths from the payload, similar to a .gitignore.
|
167
|
+
#
|
168
|
+
# [check_resources]
|
169
|
+
# If set to `false`, the entire payload will be uploaded
|
170
|
+
# without checking the resource cache.
|
171
|
+
#
|
172
|
+
# Only do this if you know what you're doing.
|
173
|
+
def upload(path, check_resources = true)
|
174
|
+
unless File.exist? path
|
175
|
+
raise "invalid application path '#{path}'"
|
176
|
+
end
|
177
|
+
|
178
|
+
zipfile = "#{Dir.tmpdir}/#{@guid}.zip"
|
179
|
+
tmpdir = "#{Dir.tmpdir}/.vmc_#{@guid}_files"
|
180
|
+
|
181
|
+
FileUtils.rm_f(zipfile)
|
182
|
+
FileUtils.rm_rf(tmpdir)
|
183
|
+
|
184
|
+
prepare_package(path, tmpdir)
|
185
|
+
|
186
|
+
resources = determine_resources(tmpdir) if check_resources
|
187
|
+
|
188
|
+
packed = CFoundry::Zip.pack(tmpdir, zipfile)
|
189
|
+
|
190
|
+
@client.base.upload_app(@guid, packed && zipfile, resources || [])
|
191
|
+
ensure
|
192
|
+
FileUtils.rm_f(zipfile) if zipfile
|
193
|
+
FileUtils.rm_rf(tmpdir) if tmpdir
|
194
|
+
end
|
195
|
+
|
196
|
+
private
|
197
|
+
|
198
|
+
# Minimum size for an application payload to bother checking resources.
|
199
|
+
RESOURCE_CHECK_LIMIT = 64 * 1024
|
200
|
+
|
201
|
+
def determine_resources(path)
|
202
|
+
fingerprints, total_size = make_fingerprints(path)
|
203
|
+
|
204
|
+
return if total_size <= RESOURCE_CHECK_LIMIT
|
205
|
+
|
206
|
+
resources = @client.base.resource_match(fingerprints)
|
207
|
+
|
208
|
+
resources.each do |resource|
|
209
|
+
FileUtils.rm_f resource[:fn]
|
210
|
+
resource[:fn].sub!("#{path}/", "")
|
211
|
+
end
|
212
|
+
|
213
|
+
resources
|
214
|
+
end
|
157
215
|
end
|
158
216
|
end
|
data/lib/cfoundry/v2/base.rb
CHANGED
@@ -78,6 +78,27 @@ module CFoundry::V2
|
|
78
78
|
end
|
79
79
|
end
|
80
80
|
|
81
|
+
def resource_match(fingerprints)
|
82
|
+
post(fingerprints, "v2", "resource_match", :json => :json)
|
83
|
+
end
|
84
|
+
|
85
|
+
def upload_app(guid, zipfile, resources = [])
|
86
|
+
payload = {
|
87
|
+
:resources => resources.to_json,
|
88
|
+
:multipart => true,
|
89
|
+
:application =>
|
90
|
+
if zipfile.is_a? File
|
91
|
+
zipfile
|
92
|
+
elsif zipfile.is_a? String
|
93
|
+
File.new(zipfile, "rb")
|
94
|
+
end
|
95
|
+
}
|
96
|
+
|
97
|
+
put(payload, "v2", "apps", guid, "bits")
|
98
|
+
rescue RestClient::ServerBrokeConnection
|
99
|
+
retry
|
100
|
+
end
|
101
|
+
|
81
102
|
|
82
103
|
def params_from(args)
|
83
104
|
depth, query = args
|
data/lib/cfoundry/v2/model.rb
CHANGED
@@ -172,11 +172,11 @@ module CFoundry::V2
|
|
172
172
|
end
|
173
173
|
|
174
174
|
def update!(diff = @diff)
|
175
|
-
@client.base.send(:"update_#{object_name}", @guid, diff)
|
175
|
+
@manifest = @client.base.send(:"update_#{object_name}", @guid, diff)
|
176
176
|
|
177
177
|
@diff.clear if diff == @diff
|
178
178
|
|
179
|
-
|
179
|
+
true
|
180
180
|
end
|
181
181
|
|
182
182
|
def delete!
|
data/lib/cfoundry/version.rb
CHANGED
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: cfoundry
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 59
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 3
|
9
|
-
-
|
10
|
-
version: 0.3.
|
9
|
+
- 20
|
10
|
+
version: 0.3.20
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Alex Suraci
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-08-
|
18
|
+
date: 2012-08-15 00:00:00 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: rest-client
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- lib/cfoundry/client.rb
|
111
111
|
- lib/cfoundry/errors.rb
|
112
112
|
- lib/cfoundry/uaaclient.rb
|
113
|
+
- lib/cfoundry/upload_helpers.rb
|
113
114
|
- lib/cfoundry/v1/app.rb
|
114
115
|
- lib/cfoundry/v1/base.rb
|
115
116
|
- lib/cfoundry/v1/client.rb
|
@@ -168,7 +169,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
168
169
|
requirements: []
|
169
170
|
|
170
171
|
rubyforge_project: cfoundry
|
171
|
-
rubygems_version: 1.8.
|
172
|
+
rubygems_version: 1.8.24
|
172
173
|
signing_key:
|
173
174
|
specification_version: 3
|
174
175
|
summary: High-level library for working with the Cloud Foundry API.
|