omnibus-sonian 1.2.0.1

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 (70) hide show
  1. checksums.yaml +15 -0
  2. data/.gitignore +9 -0
  3. data/.rspec +1 -0
  4. data/.travis.yml +5 -0
  5. data/.yardopts +6 -0
  6. data/CHANGELOG.md +96 -0
  7. data/Gemfile +9 -0
  8. data/LICENSE +201 -0
  9. data/NOTICE +9 -0
  10. data/README.md +195 -0
  11. data/Rakefile +7 -0
  12. data/bin/makeself-header.sh +401 -0
  13. data/bin/makeself.sh +407 -0
  14. data/bin/omnibus +11 -0
  15. data/lib/omnibus.rb +304 -0
  16. data/lib/omnibus/artifact.rb +151 -0
  17. data/lib/omnibus/build_version.rb +285 -0
  18. data/lib/omnibus/builder.rb +328 -0
  19. data/lib/omnibus/clean_tasks.rb +30 -0
  20. data/lib/omnibus/cli.rb +35 -0
  21. data/lib/omnibus/cli/application.rb +140 -0
  22. data/lib/omnibus/cli/base.rb +118 -0
  23. data/lib/omnibus/cli/build.rb +62 -0
  24. data/lib/omnibus/cli/cache.rb +60 -0
  25. data/lib/omnibus/cli/release.rb +49 -0
  26. data/lib/omnibus/config.rb +224 -0
  27. data/lib/omnibus/exceptions.rb +143 -0
  28. data/lib/omnibus/fetcher.rb +184 -0
  29. data/lib/omnibus/fetchers.rb +22 -0
  30. data/lib/omnibus/fetchers/git_fetcher.rb +212 -0
  31. data/lib/omnibus/fetchers/net_fetcher.rb +193 -0
  32. data/lib/omnibus/fetchers/path_fetcher.rb +65 -0
  33. data/lib/omnibus/fetchers/s3_cache_fetcher.rb +42 -0
  34. data/lib/omnibus/health_check.rb +356 -0
  35. data/lib/omnibus/library.rb +62 -0
  36. data/lib/omnibus/overrides.rb +69 -0
  37. data/lib/omnibus/package_release.rb +163 -0
  38. data/lib/omnibus/project.rb +715 -0
  39. data/lib/omnibus/reports.rb +99 -0
  40. data/lib/omnibus/s3_cacher.rb +138 -0
  41. data/lib/omnibus/software.rb +441 -0
  42. data/lib/omnibus/templates/Berksfile.erb +3 -0
  43. data/lib/omnibus/templates/Gemfile.erb +4 -0
  44. data/lib/omnibus/templates/README.md.erb +102 -0
  45. data/lib/omnibus/templates/Vagrantfile.erb +95 -0
  46. data/lib/omnibus/templates/gitignore.erb +8 -0
  47. data/lib/omnibus/templates/omnibus.rb.example.erb +5 -0
  48. data/lib/omnibus/templates/package_scripts/makeselfinst.erb +27 -0
  49. data/lib/omnibus/templates/package_scripts/postinst.erb +17 -0
  50. data/lib/omnibus/templates/package_scripts/postrm.erb +9 -0
  51. data/lib/omnibus/templates/project.rb.erb +21 -0
  52. data/lib/omnibus/templates/software/c-example.rb.erb +42 -0
  53. data/lib/omnibus/templates/software/erlang-example.rb.erb +38 -0
  54. data/lib/omnibus/templates/software/ruby-example.rb.erb +24 -0
  55. data/lib/omnibus/util.rb +61 -0
  56. data/lib/omnibus/version.rb +20 -0
  57. data/omnibus.gemspec +34 -0
  58. data/spec/artifact_spec.rb +106 -0
  59. data/spec/build_version_spec.rb +266 -0
  60. data/spec/data/overrides/bad_line.overrides +3 -0
  61. data/spec/data/overrides/good.overrides +5 -0
  62. data/spec/data/overrides/with_dupes.overrides +4 -0
  63. data/spec/data/software/erchef.rb +40 -0
  64. data/spec/fetchers/net_fetcher_spec.rb +16 -0
  65. data/spec/overrides_spec.rb +114 -0
  66. data/spec/package_release_spec.rb +197 -0
  67. data/spec/s3_cacher_spec.rb +47 -0
  68. data/spec/software_spec.rb +85 -0
  69. data/spec/spec_helper.rb +28 -0
  70. metadata +252 -0
@@ -0,0 +1,42 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2012 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ require 'omnibus/fetcher'
19
+ require 'omnibus/s3_cacher'
20
+
21
+ module Omnibus
22
+ class S3CacheFetcher < NetFetcher
23
+ include SoftwareS3URLs
24
+
25
+ name :s3cache
26
+
27
+ def initialize(software)
28
+ @software = software
29
+ super
30
+ end
31
+
32
+ def fetch
33
+ log "S3 Cache enabled, #{name} will be fetched from S3 cache"
34
+ super
35
+ end
36
+
37
+ def source_uri
38
+ URI.parse(url_for(@software))
39
+ end
40
+ end
41
+ end
42
+
@@ -0,0 +1,356 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2012 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ module Omnibus
19
+ class HealthCheck
20
+
21
+ WHITELIST_LIBS = [
22
+ /ld-linux/,
23
+ /libc\.so/,
24
+ /libcrypt\.so/,
25
+ /libdl/,
26
+ /libfreebl\d\.so/,
27
+ /libgcc_s\.so/,
28
+ /libm\.so/,
29
+ /libnsl\.so/,
30
+ /libpthread/,
31
+ /libresolv\.so/,
32
+ /librt\.so/,
33
+ /libstdc\+\+\.so/,
34
+ /libutil\.so/,
35
+ /linux-vdso.+/,
36
+ /linux-gate\.so/,
37
+ /libz\.so.\d/
38
+ ]
39
+
40
+ ARCH_WHITELIST_LIBS = [
41
+ /libc\.so/,
42
+ /libcrypt\.so/,
43
+ /libdb-5\.3\.so/,
44
+ /libdl\.so/,
45
+ /libffi\.so/,
46
+ /libgdbm\.so/,
47
+ /libm\.so/,
48
+ /libpthread\.so/,
49
+ /librt\.so/,
50
+ /libutil\.so/,
51
+ /libz\.so.\d/
52
+ ]
53
+
54
+ AIX_WHITELIST_LIBS = [
55
+ /libpthread\.a/,
56
+ /libpthreads\.a/,
57
+ /libdl.a/,
58
+ /librtl\.a/,
59
+ /libc\.a/,
60
+ /libcrypt\.a/,
61
+ /unix$/,
62
+ ]
63
+
64
+ SOLARIS_WHITELIST_LIBS = [
65
+ /libaio\.so/,
66
+ /libavl\.so/,
67
+ /libcrypt_[di]\.so/,
68
+ /libcrypto.so/,
69
+ /libcurses\.so/,
70
+ /libdoor\.so/,
71
+ /libgen\.so/,
72
+ /libmd5\.so/,
73
+ /libmd\.so/,
74
+ /libmp\.so/,
75
+ /libscf\.so/,
76
+ /libsec\.so/,
77
+ /libsocket\.so/,
78
+ /libssl.so/,
79
+ /libthread.so/,
80
+ /libuutil\.so/,
81
+ /libz.so/,
82
+ # solaris 11 libraries:
83
+ /libc\.so\.1/,
84
+ /libm\.so\.2/,
85
+ /libdl\.so\.1/,
86
+ /libnsl\.so\.1/,
87
+ /libpthread\.so\.1/,
88
+ /librt\.so\.1/,
89
+ /libcrypt\.so\.1/,
90
+ /libgdbm\.so\.3/,
91
+ # solaris 9 libraries:
92
+ /libm\.so\.1/,
93
+ /libc_psr\.so\.1/,
94
+ /s9_preload\.so\.1/
95
+ ]
96
+
97
+ SMARTOS_WHITELIST_LIBS = [
98
+ /libm.so/,
99
+ /libpthread.so/,
100
+ /librt.so/,
101
+ /libsocket.so/,
102
+ /libdl.so/,
103
+ /libnsl.so/,
104
+ /libgen.so/,
105
+ /libmp.so/,
106
+ /libmd.so/,
107
+ /libc.so/,
108
+ /libgcc_s.so/,
109
+ /libstdc\+\+\.so/,
110
+ /libcrypt.so/,
111
+ /libz\.so.\d/
112
+ ]
113
+
114
+ MAC_WHITELIST_LIBS = [
115
+ /libobjc\.A\.dylib/,
116
+ /libSystem\.B\.dylib/,
117
+ /CoreFoundation/,
118
+ /Tcl$/,
119
+ /Cocoa$/,
120
+ /Carbon$/,
121
+ /IOKit$/,
122
+ /Tk$/,
123
+ /libutil\.dylib/,
124
+ /libffi\.dylib/,
125
+ /libncurses\.5\.4\.dylib/,
126
+ /libiconv/,
127
+ /libstdc\+\+\.6\.dylib/,
128
+ /libz.1.dylib/
129
+ ]
130
+
131
+ FREEBSD_WHITELIST_LIBS = [
132
+ /libc\.so/,
133
+ /libcrypt\.so/,
134
+ /libm\.so/,
135
+ /librt\.so/,
136
+ /libthr\.so/,
137
+ /libutil\.so/,
138
+ /libz\.so.\d/
139
+ ]
140
+
141
+ def self.log(msg)
142
+ puts "[health_check] #{msg}"
143
+ end
144
+
145
+ def self.run(install_dir, whitelist_files = [])
146
+ case OHAI.platform
147
+ when "mac_os_x"
148
+ bad_libs = health_check_otool(install_dir, whitelist_files)
149
+ when "aix"
150
+ bad_libs = health_check_aix(install_dir, whitelist_files)
151
+ else
152
+ bad_libs = health_check_ldd(install_dir, whitelist_files)
153
+ end
154
+
155
+ unresolved = []
156
+ unreliable = []
157
+ detail = []
158
+
159
+ if bad_libs.keys.length > 0
160
+ bad_libs.each do |name, lib_hash|
161
+ lib_hash.each do |lib, linked_libs|
162
+ linked_libs.each do |linked, count|
163
+ if linked =~ /not found/
164
+ unresolved << lib unless unresolved.include? lib
165
+ else
166
+ unreliable << linked unless unreliable.include? linked
167
+ end
168
+ detail << "#{name}|#{lib}|#{linked}|#{count}"
169
+ end
170
+ end
171
+ end
172
+ log "*** Health Check Failed, Summary follows:"
173
+ bad_omnibus_libs, bad_omnibus_bins = bad_libs.keys.partition { |k| k.include? "embedded/lib" }
174
+ log "*** The following Omnibus-built libraries have unsafe or unmet dependencies:"
175
+ bad_omnibus_libs.each { |lib| log " --> #{lib}" }
176
+ log "*** The following Omnibus-built binaries have unsafe or unmet dependencies:"
177
+ bad_omnibus_bins.each { |bin| log " --> #{bin}" }
178
+ if unresolved.length > 0
179
+ log "*** The following requirements could not be resolved:"
180
+ unresolved.each { |lib| log " --> #{lib}"}
181
+ end
182
+ if unreliable.length > 0
183
+ log "*** The following libraries cannot be guaranteed to be on target systems:"
184
+ unreliable.each { |lib| log " --> #{lib}"}
185
+ end
186
+ log "*** The precise failures were:"
187
+ detail.each do |line|
188
+ item, dependency, location, count = line.split('|')
189
+ reason = location =~ /not found/ ? "Unresolved dependency" : "Unsafe dependency"
190
+ log " --> #{item}"
191
+ log " DEPENDS ON: #{dependency}"
192
+ log " COUNT: #{count}"
193
+ log " PROVIDED BY: #{location}"
194
+ log " FAILED BECAUSE: #{reason}"
195
+ end
196
+ raise "Health Check Failed"
197
+ end
198
+ end
199
+
200
+ def self.health_check_otool(install_dir, whitelist_files)
201
+ otool_cmd = "find #{install_dir}/ -type f | egrep '\.(dylib|bundle)$' | xargs otool -L > otool.out 2>/dev/null"
202
+ log "Executing `#{otool_cmd}`"
203
+ shell = Mixlib::ShellOut.new(otool_cmd, :timeout => 3600)
204
+ shell.run_command
205
+
206
+ otool_output = File.read('otool.out')
207
+
208
+ current_library = nil
209
+ bad_libs = {}
210
+
211
+ otool_output.each_line do |line|
212
+ case line
213
+ when /^(.+):$/
214
+ current_library = $1
215
+ when /^\s+(.+) \(.+\)$/
216
+ linked = $1
217
+ name = File.basename(linked)
218
+ bad_libs = check_for_bad_library(install_dir, bad_libs, whitelist_files, current_library, name, linked)
219
+ end
220
+ end
221
+
222
+ File.delete('otool.out')
223
+
224
+ bad_libs
225
+ end
226
+
227
+ def self.check_for_bad_library(install_dir, bad_libs, whitelist_files, current_library, name, linked)
228
+ safe = nil
229
+
230
+ whitelist_libs = case OHAI.platform
231
+ when 'arch'
232
+ ARCH_WHITELIST_LIBS
233
+ when 'mac_os_x'
234
+ MAC_WHITELIST_LIBS
235
+ when 'solaris2'
236
+ SOLARIS_WHITELIST_LIBS
237
+ when 'smartos'
238
+ SMARTOS_WHITELIST_LIBS
239
+ when 'freebsd'
240
+ FREEBSD_WHITELIST_LIBS
241
+ when 'aix'
242
+ AIX_WHITELIST_LIBS
243
+ else
244
+ WHITELIST_LIBS
245
+ end
246
+ whitelist_libs.each do |reg|
247
+ safe ||= true if reg.match(name)
248
+ end
249
+ whitelist_files.each do |reg|
250
+ safe ||= true if reg.match(current_library)
251
+ end
252
+
253
+ log " --> Dependency: #{name}" if ARGV[0] == "verbose"
254
+ log " --> Provided by: #{linked}" if ARGV[0] == "verbose"
255
+
256
+ if !safe && linked !~ Regexp.new(install_dir)
257
+ log " -> FAILED: #{current_library} has unsafe dependencies" if ARGV[0] == "verbose"
258
+ bad_libs[current_library] ||= {}
259
+ bad_libs[current_library][name] ||= {}
260
+ if bad_libs[current_library][name].has_key?(linked)
261
+ bad_libs[current_library][name][linked] += 1
262
+ else
263
+ bad_libs[current_library][name][linked] = 1
264
+ end
265
+ else
266
+ log " -> PASSED: #{name} is either whitelisted or safely provided." if ARGV[0] == "verbose"
267
+ end
268
+
269
+ bad_libs
270
+ end
271
+
272
+ def self.health_check_aix(install_dir, whitelist_files)
273
+ #
274
+ # ShellOut has GC turned off during execution, so when we're
275
+ # executing extremely long commands with lots of output, we
276
+ # should be mindful that the string concatentation for building
277
+ # #stdout will hurt memory usage drastically
278
+ #
279
+ ldd_cmd = "find #{install_dir}/ -type f | xargs file | grep \"RISC System\" | awk -F: '{print $1}' | xargs -n 1 ldd > ldd.out 2>/dev/null"
280
+
281
+ log "Executing `#{ldd_cmd}`"
282
+ shell = Mixlib::ShellOut.new(ldd_cmd, :timeout => 3600)
283
+ shell.run_command
284
+
285
+ ldd_output = File.read('ldd.out')
286
+
287
+ current_library = nil
288
+ bad_libs = {}
289
+
290
+ ldd_output.each_line do |line|
291
+ case line
292
+ when /^(.+) needs:$/
293
+ current_library = $1
294
+ log "*** Analysing dependencies for #{current_library}" if ARGV[0] == "verbose"
295
+ when /^\s+(.+)$/
296
+ name = $1
297
+ linked = $1
298
+ bad_libs = check_for_bad_library(install_dir, bad_libs, whitelist_files, current_library, name, linked)
299
+ when /File is not an executable XCOFF file/ # ignore non-executable files
300
+ else
301
+ log "*** Line did not match for #{current_library}\n#{line}"
302
+ end
303
+ end
304
+
305
+ File.delete('ldd.out')
306
+ bad_libs
307
+ end
308
+
309
+ def self.health_check_ldd(install_dir, whitelist_files)
310
+ #
311
+ # ShellOut has GC turned off during execution, so when we're
312
+ # executing extremely long commands with lots of output, we
313
+ # should be mindful that the string concatentation for building
314
+ # #stdout will hurt memory usage drastically
315
+ #
316
+ ldd_cmd = "find #{install_dir}/ -type f | xargs ldd > ldd.out 2>/dev/null"
317
+
318
+ log "Executing `#{ldd_cmd}`"
319
+ shell = Mixlib::ShellOut.new(ldd_cmd, :timeout => 3600)
320
+ shell.run_command
321
+
322
+ ldd_output = File.read('ldd.out')
323
+
324
+ current_library = nil
325
+ bad_libs = {}
326
+
327
+ ldd_output.each_line do |line|
328
+ case line
329
+ when /^(.+):$/
330
+ current_library = $1
331
+ log "*** Analysing dependencies for #{current_library}" if ARGV[0] == "verbose"
332
+ when /^\s+(.+) \=\>\s+(.+)( \(.+\))?$/
333
+ name = $1
334
+ linked = $2
335
+ bad_libs = check_for_bad_library(install_dir, bad_libs, whitelist_files, current_library, name, linked)
336
+ when /^\s+(.+) \(.+\)$/
337
+ next
338
+ when /^\s+statically linked$/
339
+ next
340
+ when /^\s+libjvm.so/
341
+ next
342
+ when /^\s+libjava.so/
343
+ next
344
+ when /^\s+libmawt.so/
345
+ next
346
+ when /^\s+not a dynamic executable$/ # ignore non-executable files
347
+ else
348
+ log "*** Line did not match for #{current_library}\n#{line}"
349
+ end
350
+ end
351
+
352
+ File.delete('ldd.out')
353
+ bad_libs
354
+ end
355
+ end
356
+ end
@@ -0,0 +1,62 @@
1
+ #
2
+ # Copyright:: Copyright (c) 2012 Opscode, Inc.
3
+ # License:: Apache License, Version 2.0
4
+ #
5
+ # Licensed under the Apache License, Version 2.0 (the "License");
6
+ # you may not use this file except in compliance with the License.
7
+ # You may obtain a copy of the License at
8
+ #
9
+ # http://www.apache.org/licenses/LICENSE-2.0
10
+ #
11
+ # Unless required by applicable law or agreed to in writing, software
12
+ # distributed under the License is distributed on an "AS IS" BASIS,
13
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ # See the License for the specific language governing permissions and
15
+ # limitations under the License.
16
+ #
17
+
18
+ module Omnibus
19
+ #
20
+ # Used to generate the manifest of all software components with versions
21
+ class Library
22
+
23
+ attr_reader :components
24
+
25
+ def initialize(project)
26
+ @components = []
27
+ @project = project
28
+ end
29
+
30
+ def component_added(component)
31
+ @components << component unless @components.include?(component)
32
+ end
33
+
34
+ def version_map
35
+ @components.inject({}) {|map, component|
36
+ map[component.name] = if component.given_version
37
+ {:version => component.version,
38
+ :given_version => component.given_version,
39
+ :overridden => component.overridden?,
40
+ :version_guid => component.version_guid}
41
+ else
42
+ ## Components without a version are
43
+ ## pieces of the omnibus project
44
+ ## itself, and so don't really fit
45
+ ## with the concept of overrides
46
+ v = {:version => @project.build_version}
47
+ if @project.build_version.respond_to?(:git_sha)
48
+ v[:version_guid] = "git:#{@project.build_version.git_sha}"
49
+ end
50
+ v
51
+ end
52
+ map
53
+ }
54
+ end
55
+
56
+ def select(*args, &block)
57
+ @components.select(*args, &block)
58
+ end
59
+ end
60
+
61
+ end
62
+