omnibus 5.2.0 → 5.3.0

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.
@@ -197,13 +197,20 @@ module Omnibus
197
197
  #
198
198
  # Execute the given git command, inside the +project_dir+.
199
199
  #
200
+ # autcrlf is a hack to help support windows and posix clients using the
201
+ # same repository but canonicalizing files as they are committed to the
202
+ # repo but converting line endings when they are actually checked out
203
+ # into a working tree. We do not want to change the on-disk representation
204
+ # of our sources regardless of the platform we are building on unless
205
+ # explicitly asked for. Hence, we disable autocrlf.
206
+ #
200
207
  # @see Util#shellout!
201
208
  #
202
209
  # @return [Mixlib::ShellOut]
203
210
  # the shellout object
204
211
  #
205
212
  def git(command)
206
- shellout!("git #{command}", cwd: project_dir)
213
+ shellout!("git -c core.autocrlf=false #{command}", cwd: project_dir)
207
214
  end
208
215
 
209
216
  # Class methods
@@ -15,11 +15,12 @@
15
15
  #
16
16
 
17
17
  require 'fileutils'
18
- require 'open-uri'
19
- require 'ruby-progressbar'
18
+ require 'omnibus/download_helpers'
20
19
 
21
20
  module Omnibus
22
21
  class NetFetcher < Fetcher
22
+ include DownloadHelpers
23
+
23
24
  # Use 7-zip to extract 7z/zip for Windows
24
25
  WIN_7Z_EXTENSIONS = %w(.7z .zip)
25
26
 
@@ -159,53 +160,17 @@ module Omnibus
159
160
  def download
160
161
  log.warn(log_key) { source[:warning] } if source.key?(:warning)
161
162
 
162
- options = download_headers
163
+ options = {}
163
164
 
164
165
  if source[:unsafe]
165
166
  log.warn(log_key) { "Permitting unsafe redirects!" }
166
167
  options[:allow_unsafe_redirects] = true
167
168
  end
168
169
 
169
- options[:read_timeout] = Omnibus::Config.fetcher_read_timeout
170
- fetcher_retries ||= Omnibus::Config.fetcher_retries
171
-
172
- progress_bar = ProgressBar.create(
173
- output: $stdout,
174
- format: '%e %B %p%% (%r KB/sec)',
175
- rate_scale: ->(rate) { rate / 1024 },
176
- )
177
-
178
- reported_total = 0
179
-
180
- options[:content_length_proc] = ->(total) {
181
- reported_total = total
182
- progress_bar.total = total
183
- }
184
- options[:progress_proc] = ->(step) {
185
- downloaded_amount = [step, reported_total].min
186
- progress_bar.progress = downloaded_amount
187
- }
188
-
189
- file = open(download_url, options)
190
- # This is a temporary file. Close and flush it before attempting to copy
191
- # it over.
192
- file.close
193
- FileUtils.cp(file.path, downloaded_file)
194
- file.unlink
195
- rescue SocketError,
196
- Errno::ECONNREFUSED,
197
- Errno::ECONNRESET,
198
- Errno::ENETUNREACH,
199
- Timeout::Error,
200
- OpenURI::HTTPError => e
201
- if fetcher_retries != 0
202
- log.info(log_key) { "Retrying failed download due to #{e} (#{fetcher_retries} retries left)..." }
203
- fetcher_retries -= 1
204
- retry
205
- else
206
- log.error(log_key) { "Download failed - #{e.class}!" }
207
- raise
208
- end
170
+ # Set the cookie if one was given
171
+ options['Cookie'] = source[:cookie] if source[:cookie]
172
+
173
+ download_file!(download_url, downloaded_file, options)
209
174
  end
210
175
 
211
176
  #
@@ -358,43 +323,5 @@ module Omnibus
358
323
  def tar
359
324
  Omnibus.which('gtar') ? 'gtar' : 'tar'
360
325
  end
361
-
362
- #
363
- # The list of headers to pass to the download.
364
- #
365
- # @return [Hash]
366
- #
367
- def download_headers
368
- {}.tap do |h|
369
- # Alright kids, sit down while grandpa tells you a story. Back when the
370
- # Internet was just a series of tubes, and you had to "dial in" using
371
- # this thing called a "modem", ancient astronaunt theorists (computer
372
- # scientists) invented gzip to compress requests sent over said tubes
373
- # and make the Internet faster.
374
- #
375
- # Fast forward to the year of broadband - ungzipping these files was
376
- # tedious and hard, so Ruby and other client libraries decided to do it
377
- # for you:
378
- #
379
- # https://github.com/ruby/ruby/blob/c49ae7/lib/net/http.rb#L1031-L1033
380
- #
381
- # Meanwhile, software manufacturers began automatically compressing
382
- # their software for distribution as a +.tar.gz+, publishing the
383
- # appropriate checksums accordingly.
384
- #
385
- # But consider... If a software manufacturer is publishing the checksum
386
- # for a gzipped tarball, and the client is automatically ungzipping its
387
- # responses, then checksums can (read: should) never match! Herein lies
388
- # the bug that took many hours away from the lives of a once-happy
389
- # developer.
390
- #
391
- # TL;DR - Do not let Ruby ungzip our file
392
- #
393
- h['Accept-Encoding'] = 'identity'
394
-
395
- # Set the cookie if one was given
396
- h['Cookie'] = source[:cookie] if source[:cookie]
397
- end
398
- end
399
326
  end
400
327
  end
@@ -97,6 +97,12 @@ module Omnibus
97
97
  /librt\.so\.1/,
98
98
  /libcrypt\.so\.1/,
99
99
  /libgdbm\.so\.3/,
100
+ /libgcc_s\.so\.1/,
101
+ /libcryptoutil\.so\.1/,
102
+ /libucrypto\.so\.1/,
103
+ /libz\.so\.1/, # while we package our own libz, this get dragged along from Solaris 11's libelf library for some reason...
104
+ /libelf\.so\.1/,
105
+ /libssp\.so\.0/,
100
106
  # solaris 9 libraries:
101
107
  /libm\.so\.1/,
102
108
  /libc_psr\.so\.1/,
@@ -151,6 +157,49 @@ module Omnibus
151
157
  /libmd\.so/,
152
158
  ].freeze
153
159
 
160
+ IGNORED_ENDINGS = %w(
161
+ .[ch]
162
+ .e*rb
163
+ .gemspec
164
+ .gitignore
165
+ .h*h
166
+ .java
167
+ .js
168
+ .json
169
+ .lock
170
+ .log
171
+ .lua
172
+ .md
173
+ .mkd
174
+ .out
175
+ .pl
176
+ .pm
177
+ .png
178
+ .py[oc]*
179
+ .r*html
180
+ .rdoc
181
+ .ri
182
+ .sh
183
+ .sql
184
+ .toml
185
+ .ttf
186
+ .txt
187
+ .xml
188
+ .yml
189
+ Gemfile
190
+ LICENSE
191
+ README
192
+ Rakefile
193
+ VERSION
194
+ ).freeze
195
+
196
+ IGNORED_PATTERNS = %w(
197
+ /share/doc/
198
+ /share/postgresql/
199
+ /share/terminfo/
200
+ /terminfo/
201
+ ).freeze
202
+
154
203
  class << self
155
204
  # @see (HealthCheck#new)
156
205
  def run!(project)
@@ -450,10 +499,14 @@ module Omnibus
450
499
  # the bad libraries (library_name -> dependency_name -> satisfied_lib_path -> count)
451
500
  #
452
501
  def health_check_ldd
502
+ regexp_ends = '.*(' + IGNORED_ENDINGS.map { |e| e.gsub(/\./, '\.') }.join('|') + ')$'
503
+ regexp_patterns = IGNORED_PATTERNS.map { |e| '.*' + e.gsub(/\//, '\/') + '.*' }.join('|')
504
+ regexp = regexp_ends + '|' + regexp_patterns
505
+
453
506
  current_library = nil
454
507
  bad_libs = {}
455
508
 
456
- read_shared_libs("find #{project.install_dir}/ -type f | xargs ldd") do |line|
509
+ read_shared_libs("find #{project.install_dir}/ -type f -regextype posix-extended ! -regex '#{regexp}' | xargs ldd") do |line|
457
510
  case line
458
511
  when /^(.+):$/
459
512
  current_library = Regexp.last_match[1]
@@ -16,10 +16,12 @@
16
16
 
17
17
  require 'uri'
18
18
  require 'fileutils'
19
+ require 'omnibus/download_helpers'
19
20
 
20
21
  module Omnibus
21
22
  class Licensing
22
23
  include Logging
24
+ include DownloadHelpers
23
25
 
24
26
  OUTPUT_DIRECTORY = "LICENSES".freeze
25
27
 
@@ -53,6 +55,7 @@ module Omnibus
53
55
  #
54
56
  def create!
55
57
  prepare
58
+ validate_license_info
56
59
  create_software_license_files
57
60
  create_project_license_file
58
61
  end
@@ -67,6 +70,49 @@ module Omnibus
67
70
  FileUtils.mkdir_p(output_dir)
68
71
  end
69
72
 
73
+ #
74
+ # Inspects the licensing information for the project and the included
75
+ # software components. Logs the found issues to the log as warning.
76
+ #
77
+ # @return [void]
78
+ #
79
+ def validate_license_info
80
+ # First check the project licensing information
81
+
82
+ # Check existence of licensing information
83
+ if project.license == "Unspecified"
84
+ licensing_warning("Project '#{project.name}' does not contain licensing information.")
85
+ end
86
+
87
+ # Check license file exists
88
+ if project.license != "Unspecified" && project.license_file.nil?
89
+ licensing_warning("Project '#{project.name}' does not point to a license file.")
90
+ end
91
+
92
+ # Check used license is a standard license
93
+ if project.license != "Unspecified" && !STANDARD_LICENSES.include?(project.license)
94
+ licensing_warning("Project '#{project.name}' is using '#{project.license}' which is not one of the standard licenses identified in https://opensource.org/licenses/alphabetical. Consider using one of the standard licenses.")
95
+ end
96
+
97
+ # Now let's check the licensing info for software components
98
+ license_map.each do |software_name, license_info|
99
+ # First check if the software specified a license
100
+ if license_info[:license] == "Unspecified"
101
+ licensing_warning("Software '#{software_name}' does not contain licensing information.")
102
+ end
103
+
104
+ # Check if the software specifies any license files
105
+ if license_info[:license] != "Unspecified" && license_info[:license_files].empty?
106
+ licensing_warning("Software '#{software_name}' does not point to any license files.")
107
+ end
108
+
109
+ # Check if the software license is one of the standard licenses
110
+ if license_info[:license] != "Unspecified" && !STANDARD_LICENSES.include?(license_info[:license])
111
+ licensing_warning("Software '#{software_name}' uses license '#{license_info[:license]}' which is not one of the standard licenses identified in https://opensource.org/licenses/alphabetical. Consider using one of the standard licenses.")
112
+ end
113
+ end
114
+ end
115
+
70
116
  #
71
117
  # Creates the top level license file for the project.
72
118
  # Top level file is created at #{project.license_file_path}
@@ -97,10 +143,28 @@ module Omnibus
97
143
  license_files = values[:license_files]
98
144
 
99
145
  license_files.each do |license_file|
100
- if license_file && local?(license_file)
101
- input_file = File.expand_path(license_file, values[:project_dir])
146
+ if license_file
102
147
  output_file = license_package_location(name, license_file)
103
- FileUtils.cp(input_file, output_file) if File.exist?(input_file)
148
+
149
+ if local?(license_file)
150
+ input_file = File.expand_path(license_file, values[:project_dir])
151
+ if File.exist?(input_file)
152
+ FileUtils.cp(input_file, output_file)
153
+ else
154
+ licensing_warning("License file '#{input_file}' does not exist for software '#{name}'.")
155
+ end
156
+ else
157
+ begin
158
+ download_file!(license_file, output_file, enable_progress_bar: false)
159
+ rescue SocketError,
160
+ Errno::ECONNREFUSED,
161
+ Errno::ECONNRESET,
162
+ Errno::ENETUNREACH,
163
+ Timeout::Error,
164
+ OpenURI::HTTPError
165
+ licensing_warning("Can not download license file '#{license_file}' for software '#{name}'.")
166
+ end
167
+ end
104
168
  end
105
169
  end
106
170
  end
@@ -201,7 +265,8 @@ module Omnibus
201
265
  if local?(where)
202
266
  File.join(output_dir, "#{component_name}-#{File.split(where).last}")
203
267
  else
204
- where
268
+ u = URI(where)
269
+ File.join(output_dir, "#{component_name}-#{File.basename(u.path)}")
205
270
  end
206
271
  end
207
272
 
@@ -223,5 +288,108 @@ module Omnibus
223
288
  u = URI(license)
224
289
  return u.scheme.nil?
225
290
  end
291
+
292
+ #
293
+ # Logs the given message as warning.
294
+ #
295
+ # @param [String] message
296
+ # message to log as warning
297
+ def licensing_warning(message)
298
+ log.warn(log_key) { message }
299
+ end
300
+
301
+ STANDARD_LICENSES = [
302
+ #
303
+ # Below licenses are compiled based on https://opensource.org/licenses/alphabetical
304
+ #
305
+ "AFL-3.0", # Academic Free License 3.0
306
+ "AGPL-3.0", # Affero General Public License
307
+ "APL-1.0", # Adaptive Public License
308
+ "Apache-2.0", # Apache License 2.0
309
+ "APSL-2.0", # Apple Public Source License
310
+ "Artistic-2.0", # Artistic license 2.0
311
+ "AAL", # Attribution Assurance Licenses
312
+ "BSD-3-Clause", # BSD 3-Clause "New" or "Revised" License
313
+ "BSD-2-Clause", # BSD 2-Clause "Simplified" or "FreeBSD" License
314
+ "BSL-1.0", # Boost Software License
315
+ "CECILL-2.1", # CeCILL License 2.1
316
+ "CATOSL-1.1", # Computer Associates Trusted Open Source License 1.1
317
+ "CDDL-1.0", # Common Development and Distribution License 1.0
318
+ "CPAL-1.0", # Common Public Attribution License 1.0
319
+ "CUA-OPL-1.0", # CUA Office Public License Version 1.0
320
+ "EUDatagrid", # EU DataGrid Software License
321
+ "EPL-1.0", # Eclipse Public License 1.0
322
+ "eCos-2.0", # eCos License version 2.0
323
+ "ECL-2.0", # Educational Community License, Version 2.0
324
+ "EFL-2.0", # Eiffel Forum License V2.0
325
+ "Entessa", # Entessa Public License
326
+ "EUPL-1.1", # European Union Public License, Version 1.1
327
+ "Fair", # Fair License
328
+ "Frameworx-1.0", # Frameworx License
329
+ "FPL-1.0.0", # Free Public License 1.0.0
330
+ "AGPL-3.0", # GNU Affero General Public License v3
331
+ "GPL-2.0", # GNU General Public License version 2.0
332
+ "GPL-3.0", # GNU General Public License version 3.0
333
+ "LGPL-2.1", # GNU Library or "Lesser" General Public License version 2.1
334
+ "LGPL-3.0", # GNU Library or "Lesser" General Public License version 3.0
335
+ "HPND", # Historical Permission Notice and Disclaimer
336
+ "IPL-1.0", # IBM Public License 1.0
337
+ "IPA", # IPA Font License
338
+ "ISC", # ISC License
339
+ "LPPL-1.3c", # LaTeX Project Public License 1.3c
340
+ "LiLiQ-P", # Licence Libre du Quebec Permissive
341
+ "LiLiQ-R", # Licence Libre du Quebec Reciprocite
342
+ "LiLiQ-R+", # Licence Libre du Quebec Reciprocite forte
343
+ "LPL-1.02", # Lucent Public License Version 1.02
344
+ "MirOS", # MirOS Licence
345
+ "MS-PL", # Microsoft Public License
346
+ "MS-RL", # Microsoft Reciprocal License
347
+ "MIT", # MIT license
348
+ "Motosoto", # Motosoto License
349
+ "MPL-2.0", # Mozilla Public License 2.0
350
+ "Multics", # Multics License
351
+ "NASA-1.3", # NASA Open Source Agreement 1.3
352
+ "NTP", # NTP License
353
+ "Naumen", # Naumen Public License
354
+ "NGPL", # Nethack General Public License
355
+ "Nokia", # Nokia Open Source License
356
+ "NPOSL-3.0", # Non-Profit Open Software License 3.0
357
+ "OCLC-2.0", # OCLC Research Public License 2.0
358
+ "OGTSL", # Open Group Test Suite License
359
+ "OSL-3.0", # Open Software License 3.0
360
+ "OPL-2.1", # OSET Public License version 2.1
361
+ "PHP-3.0", # PHP License 3.0
362
+ "PostgreSQL", # The PostgreSQL License
363
+ "Python-2.0", # Python License
364
+ "CNRI-Python", # CNRI Python license
365
+ "QPL-1.0", # Q Public License
366
+ "RPSL-1.0", # RealNetworks Public Source License V1.0
367
+ "RPL-1.5", # Reciprocal Public License 1.5
368
+ "RSCPL", # Ricoh Source Code Public License
369
+ "OFL-1.1", # SIL Open Font License 1.1
370
+ "SimPL-2.0", # Simple Public License 2.0
371
+ "Sleepycat", # Sleepycat License
372
+ "SPL-1.0", # Sun Public License 1.0
373
+ "Watcom-1.0", # Sybase Open Watcom Public License 1.0
374
+ "NCSA", # University of Illinois/NCSA Open Source License
375
+ "UPL", # Universal Permissive License
376
+ "VSL-1.0", # Vovida Software License v. 1.0
377
+ "W3C", # W3C License
378
+ "WXwindows", # wxWindows Library License
379
+ "Xnet", # X.Net License
380
+ "0BSD", # Zero Clause BSD License
381
+ "ZPL-2.0", # Zope Public License 2.0
382
+ "Zlib", # zlib/libpng license
383
+ #
384
+ # In addition to these we would like to add some of the licenses that
385
+ # are frequently used in our depedencies.
386
+ #
387
+ "Public-Domain", # https://opensource.org/faq#public-domain
388
+ "Ruby", # http://www.ruby-lang.org/en/LICENSE.txt
389
+ "Erlang-Public", # http://www.erlang.org/EPLICENSE
390
+ "Oracle-Binary", # http://www.oracle.com/technetwork/java/javase/terms/license/index.html
391
+ "OpenSSL", # https://www.openssl.org/source/license.html
392
+ "Chef-MLSA", # https://www.chef.io/online-master-agreement/
393
+ ].freeze
226
394
  end
227
395
  end
@@ -36,6 +36,7 @@ module Omnibus
36
36
  PLATFORM_PACKAGER_MAP = {
37
37
  'debian' => DEB,
38
38
  'fedora' => RPM,
39
+ 'suse' => RPM,
39
40
  'rhel' => RPM,
40
41
  'wrlinux' => RPM,
41
42
  'aix' => BFF,
@@ -131,8 +131,14 @@ module Omnibus
131
131
  def write_gen_template
132
132
 
133
133
  # Get a list of all files
134
- files = FileSyncer.glob("#{staging_dir}/**/*").map do |path|
135
-
134
+ files = FileSyncer.glob("#{staging_dir}/**/*").reject do |path|
135
+ # remove any files with spaces.
136
+ if path =~ /[[:space:]]/
137
+ log.warn(log_key) { "Skipping packaging '#{path}' file due to whitespace in filename" }
138
+ true
139
+ end
140
+ end
141
+ files.map! do |path|
136
142
  # If paths have colons or commas, rename them and add them to a post-install,
137
143
  # post-sysck renaming script ('config') which is created if needed
138
144
  if path.match(/:|,/)