omnibus 3.1.1 → 3.2.0.rc.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (105) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +71 -0
  3. data/Gemfile +0 -7
  4. data/README.md +108 -36
  5. data/Rakefile +1 -5
  6. data/docs/omnibus-build-cache.md +5 -5
  7. data/features/commands/_deprecated.feature +21 -3
  8. data/features/step_definitions/generator_steps.rb +7 -7
  9. data/lib/omnibus.rb +232 -171
  10. data/lib/omnibus/build_version.rb +2 -2
  11. data/lib/omnibus/builder.rb +38 -19
  12. data/lib/omnibus/cleaner.rb +5 -5
  13. data/lib/omnibus/cleanroom.rb +141 -0
  14. data/lib/omnibus/cli.rb +6 -9
  15. data/lib/omnibus/cli/base.rb +2 -1
  16. data/lib/omnibus/cli/cache.rb +15 -21
  17. data/lib/omnibus/cli/deprecated.rb +40 -4
  18. data/lib/omnibus/cli/publish.rb +61 -0
  19. data/lib/omnibus/config.rb +350 -189
  20. data/lib/omnibus/digestable.rb +131 -0
  21. data/lib/omnibus/exceptions.rb +163 -83
  22. data/lib/omnibus/fetcher.rb +1 -1
  23. data/lib/omnibus/fetchers/net_fetcher.rb +19 -13
  24. data/lib/omnibus/fetchers/path_fetcher.rb +8 -1
  25. data/lib/omnibus/fetchers/s3_cache_fetcher.rb +16 -7
  26. data/lib/omnibus/generator.rb +2 -2
  27. data/lib/omnibus/generator_files/Gemfile.erb +4 -1
  28. data/lib/omnibus/generator_files/README.md.erb +10 -0
  29. data/lib/omnibus/generator_files/{omnibus.rb.example.erb → omnibus.rb.erb} +20 -11
  30. data/lib/omnibus/generator_files/package_scripts/makeselfinst.erb +1 -1
  31. data/lib/omnibus/generator_files/project.rb.erb +2 -2
  32. data/lib/omnibus/generator_files/windows_msi/localization-en-us.wxl.erb +3 -3
  33. data/lib/omnibus/git_cache.rb +192 -0
  34. data/lib/omnibus/health_check.rb +171 -116
  35. data/lib/omnibus/library.rb +4 -2
  36. data/lib/omnibus/logger.rb +60 -1
  37. data/lib/omnibus/null_argumentable.rb +51 -0
  38. data/lib/omnibus/ohai.rb +29 -8
  39. data/lib/omnibus/package.rb +240 -0
  40. data/lib/omnibus/packagers/base.rb +21 -42
  41. data/lib/omnibus/packagers/mac_dmg.rb +5 -5
  42. data/lib/omnibus/packagers/mac_pkg.rb +20 -19
  43. data/lib/omnibus/packagers/windows_msi.rb +7 -7
  44. data/lib/omnibus/project.rb +969 -486
  45. data/lib/omnibus/publisher.rb +76 -0
  46. data/lib/omnibus/publishers/artifactory_publisher.rb +168 -0
  47. data/lib/omnibus/publishers/null_publisher.rb +23 -0
  48. data/lib/omnibus/publishers/s3_publisher.rb +99 -0
  49. data/lib/omnibus/s3_cache.rb +150 -63
  50. data/lib/omnibus/software.rb +749 -321
  51. data/lib/omnibus/{sugar.rb → sugarable.rb} +11 -6
  52. data/lib/omnibus/version.rb +1 -1
  53. data/omnibus.gemspec +8 -8
  54. data/spec/data/complicated/config/projects/angrychef.rb +1 -1
  55. data/spec/data/complicated/config/projects/chef-windows.rb +1 -1
  56. data/spec/data/complicated/config/projects/chef.rb +1 -1
  57. data/spec/data/complicated/config/projects/chefdk-windows.rb +1 -1
  58. data/spec/data/complicated/config/projects/chefdk.rb +1 -1
  59. data/spec/data/complicated/config/software/cacerts.rb +1 -1
  60. data/spec/data/complicated/config/software/chef-client-msi.rb +1 -1
  61. data/spec/data/complicated/config/software/libgcc.rb +1 -1
  62. data/spec/data/complicated/config/software/libiconv.rb +0 -11
  63. data/spec/data/complicated/config/software/libpng.rb +2 -2
  64. data/spec/data/complicated/config/software/openssl.rb +1 -1
  65. data/spec/data/complicated/config/software/ruby.rb +1 -1
  66. data/spec/data/complicated/config/software/runit.rb +4 -4
  67. data/spec/data/projects/chefdk.rb +1 -1
  68. data/spec/data/projects/sample.rb +1 -1
  69. data/spec/data/software/erchef.rb +3 -1
  70. data/spec/functional/packagers/mac_spec.rb +25 -24
  71. data/spec/functional/packagers/windows_spec.rb +21 -20
  72. data/spec/spec_helper.rb +43 -4
  73. data/spec/unit/build_version_spec.rb +14 -16
  74. data/spec/unit/cleanroom_spec.rb +63 -0
  75. data/spec/unit/config_spec.rb +36 -30
  76. data/spec/unit/digestable_spec.rb +38 -0
  77. data/spec/unit/fetchers/net_fetcher_spec.rb +98 -87
  78. data/spec/unit/{install_path_cache_spec.rb → git_cache_spec.rb} +67 -56
  79. data/spec/unit/health_check_spec.rb +73 -0
  80. data/spec/unit/library_spec.rb +166 -159
  81. data/spec/unit/ohai_spec.rb +19 -0
  82. data/spec/unit/omnibus_spec.rb +43 -41
  83. data/spec/unit/package_spec.rb +178 -0
  84. data/spec/unit/packagers/base_spec.rb +17 -47
  85. data/spec/unit/packagers/mac_pkg_spec.rb +104 -126
  86. data/spec/unit/project_spec.rb +176 -25
  87. data/spec/unit/publisher_spec.rb +49 -0
  88. data/spec/unit/publishers/artifactory_publisher_spec.rb +80 -0
  89. data/spec/unit/publishers/s3_publisher_spec.rb +120 -0
  90. data/spec/unit/s3_cacher_spec.rb +84 -19
  91. data/spec/unit/software_spec.rb +397 -170
  92. data/spec/unit/sugarable_spec.rb +43 -0
  93. metadata +62 -50
  94. data/Guardfile +0 -10
  95. data/lib/omnibus/artifact.rb +0 -165
  96. data/lib/omnibus/cli/release.rb +0 -40
  97. data/lib/omnibus/generator_files/Vagrantfile.erb +0 -75
  98. data/lib/omnibus/install_path_cache.rb +0 -105
  99. data/lib/omnibus/overrides.rb +0 -88
  100. data/lib/omnibus/package_release.rb +0 -154
  101. data/lib/omnibus/software_s3_urls.rb +0 -50
  102. data/spec/unit/artifact_spec.rb +0 -91
  103. data/spec/unit/overrides_spec.rb +0 -102
  104. data/spec/unit/package_release_spec.rb +0 -180
  105. data/spec/unit/sugar_spec.rb +0 -17
@@ -0,0 +1,76 @@
1
+ #
2
+ # Copyright 2014 Chef Software, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Omnibus
18
+ class Publisher
19
+ class << self
20
+ #
21
+ # Shortcut class method for creating a new instance of this class and
22
+ # executing the publishing sequence.
23
+ #
24
+ # @param (see Publisher#initialize)
25
+ #
26
+ def publish(pattern, options = {}, &block)
27
+ new(pattern, options).publish(&block)
28
+ end
29
+ end
30
+
31
+ include Logging
32
+
33
+ #
34
+ # Create a new publisher from the given pattern.
35
+ #
36
+ # @param [String] pattern
37
+ # the path/pattern of the release artifact(s)
38
+ # @param [Hash] options
39
+ # the list of options passed to the publisher
40
+ #
41
+ def initialize(pattern, options = {})
42
+ @pattern = pattern
43
+ @options = options.dup
44
+ end
45
+
46
+ #
47
+ # The list of packages that match the pattern in the initializer.
48
+ #
49
+ # @return [Array<String>]
50
+ #
51
+ def packages
52
+ @packages ||= Dir.glob(@pattern).map { |path| Package.new(path) }
53
+ end
54
+
55
+ #
56
+ # @abstract
57
+ #
58
+ # @param [Proc] block
59
+ # if given, the block will yield the currently uploading "thing"
60
+ #
61
+ # @return [Array<String>]
62
+ # the list of uploaded packages
63
+ #
64
+ def publish(&_block)
65
+ raise AbstractMethod.new("#{self.class.name}#publish")
66
+ end
67
+
68
+ private
69
+
70
+ def safe_require(name)
71
+ require name
72
+ rescue LoadError
73
+ raise GemNotInstalled.new(name)
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,168 @@
1
+ #
2
+ # Copyright 2014 Chef Software, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ require 'uri'
18
+
19
+ module Omnibus
20
+ class ArtifactoryPublisher < Publisher
21
+ def publish(&block)
22
+ log.info(log_key) { 'Starting artifactory publisher' }
23
+ safe_require('artifactory')
24
+
25
+ packages.each do |package|
26
+ # Make sure the package is good to go!
27
+ log.debug(log_key) { "Validating '#{package.name}'" }
28
+ package.validate!
29
+
30
+ # Upload the actual package
31
+ log.info(log_key) { "Uploading '#{package.name}'" }
32
+ artifact_for(package).upload(
33
+ repository,
34
+ remote_path_for(package),
35
+ metadata_for(package),
36
+ )
37
+
38
+ # If a block was given, "yield" the package to the caller
39
+ block.call(package) if block
40
+ end
41
+ end
42
+
43
+ private
44
+
45
+ #
46
+ # The artifact object that corresponds to this package.
47
+ #
48
+ # @param [Package] package
49
+ # the package to create the artifact from
50
+ #
51
+ # @return [Artifactory::Resource::Artifact]
52
+ #
53
+ def artifact_for(package)
54
+ Artifactory::Resource::Artifact.new(
55
+ local_path: package.path,
56
+ client: client,
57
+ checksums: {
58
+ 'md5' => package.metadata[:md5],
59
+ 'sha1' => package.metadata[:sha1],
60
+ }
61
+ )
62
+ end
63
+
64
+ #
65
+ # The Artifactory client object to communicate with the Artifactory API.
66
+ #
67
+ # @return [Artifactory::Client]
68
+ #
69
+ def client
70
+ @client ||= Artifactory::Client.new(
71
+ endpoint: Config.artifactory_endpoint,
72
+ username: Config.artifactory_username,
73
+ password: Config.artifactory_password,
74
+ ssl_pem_file: Config.artifactory_ssl_pem_file,
75
+ ssl_verify: Config.artifactory_ssl_verify,
76
+ proxy_username: Config.artifactory_proxy_username,
77
+ proxy_password: Config.artifactory_proxy_password,
78
+ proxy_address: Config.artifactory_proxy_address,
79
+ proxy_port: Config.artifactory_proxy_port,
80
+ )
81
+ end
82
+
83
+ #
84
+ # The metadata for this package.
85
+ #
86
+ # @param [Package] package
87
+ # the package to generate the metadata for
88
+ #
89
+ # @return [Hash<String, String>]
90
+ #
91
+ def metadata_for(package)
92
+ {
93
+ 'omnibus.project' => package.metadata[:name],
94
+ 'omnibus.platform' => package.metadata[:platform],
95
+ 'omnibus.platform_version' => package.metadata[:platform_version],
96
+ 'omnibus.arch' => package.metadata[:arch],
97
+ 'omnibus.version' => package.metadata[:version],
98
+ 'omnibus.md5' => package.metadata[:md5],
99
+ 'omnibus.sha1' => package.metadata[:sha1],
100
+ 'omnibus.sha256' => package.metadata[:sha256],
101
+ 'omnibus.sha512' => package.metadata[:sha512],
102
+ }
103
+ end
104
+
105
+ #
106
+ # The name of the Artifactory repository (as supplied as an option).
107
+ #
108
+ # @return [String]
109
+ #
110
+ def repository
111
+ @options[:repository]
112
+ end
113
+
114
+ #
115
+ # The path where the package will live inside of the Artifactory repository.
116
+ # This is dynamically computed from the values in the project definition
117
+ # and the package metadata.
118
+ #
119
+ # @example
120
+ # com/getchef/chef/11.6.0/chef-11.6.0-1.el6.x86_64.rpm
121
+ #
122
+ # @param [Package] package
123
+ # the package to generate the remote path for
124
+ #
125
+ # @return [String]
126
+ #
127
+ def remote_path_for(package)
128
+ unless package.metadata[:homepage]
129
+ raise OldMetadata.new(package.metadata.path)
130
+ end
131
+
132
+ domain_parts = parsed_uri_for(package).host.split('.')
133
+ domain_parts.delete('www')
134
+ domain_parts.reverse!
135
+
136
+ File.join(
137
+ *domain_parts,
138
+ package.metadata[:name],
139
+ package.metadata[:version],
140
+ package.metadata[:basename],
141
+ )
142
+ end
143
+
144
+ #
145
+ # The parsed domain for this package. Ruby's URI parser does not "assume"
146
+ # a valid protocol, so passing a URI like "CHANGEME.org" will essentially
147
+ # result in an unsable object that has no useful, extractable information.
148
+ #
149
+ # This method will essentially "force" a default protocol on the +homepage+
150
+ # attribute of the package, so that it can be parsed like a good little URI.
151
+ #
152
+ # @param [Package] package
153
+ # the package to generate the remote path for
154
+ #
155
+ # @return [URI]
156
+ # the parsed URI object
157
+ #
158
+ def parsed_uri_for(package)
159
+ raw = package.metadata[:homepage]
160
+
161
+ if raw =~ /\Ahttps?:\/\//
162
+ URI.parse(raw)
163
+ else
164
+ URI.parse("http://#{raw}")
165
+ end
166
+ end
167
+ end
168
+ end
@@ -0,0 +1,23 @@
1
+ #
2
+ # Copyright 2014 Chef Software, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Omnibus
18
+ class NullPublisher < Publisher
19
+ def publish
20
+ # noop
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,99 @@
1
+ #
2
+ # Copyright 2012-2014 Chef Software, Inc.
3
+ #
4
+ # Licensed under the Apache License, Version 2.0 (the "License");
5
+ # you may not use this file except in compliance with the License.
6
+ # You may obtain a copy of the License at
7
+ #
8
+ # http://www.apache.org/licenses/LICENSE-2.0
9
+ #
10
+ # Unless required by applicable law or agreed to in writing, software
11
+ # distributed under the License is distributed on an "AS IS" BASIS,
12
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
+ # See the License for the specific language governing permissions and
14
+ # limitations under the License.
15
+ #
16
+
17
+ module Omnibus
18
+ class S3Publisher < Publisher
19
+ def publish(&block)
20
+ log.info(log_key) { 'Starting S3 publisher' }
21
+ safe_require('uber-s3')
22
+
23
+ packages.each do |package|
24
+ # Make sure the package is good to go!
25
+ log.debug(log_key) { "Validating '#{package.name}'" }
26
+ package.validate!
27
+
28
+ # Upload the metadata first
29
+ log.debug(log_key) { "Uploading '#{package.metadata.name}'" }
30
+ client.store(key_for(package, package.metadata.name), package.metadata.to_json,
31
+ access: access_policy,
32
+ )
33
+
34
+ # Upload the actual package
35
+ log.info(log_key) { "Uploading '#{package.name}'" }
36
+ client.store(key_for(package, package.name), package.content,
37
+ access: access_policy,
38
+ content_md5: package.metadata[:md5],
39
+ )
40
+
41
+ # If a block was given, "yield" the package to the caller
42
+ block.call(package) if block
43
+ end
44
+ end
45
+
46
+ private
47
+
48
+ #
49
+ # The actual S3 client object to communicate with the S3 API.
50
+ #
51
+ # @return [UberS3]
52
+ #
53
+ def client
54
+ @client ||= UberS3.new(
55
+ access_key: Config.publish_s3_access_key,
56
+ secret_access_key: Config.publish_s3_secret_key,
57
+ bucket: @options[:bucket],
58
+ adaper: :net_http,
59
+ )
60
+ end
61
+
62
+ #
63
+ # The unique upload key for this package. The additional "stuff" is
64
+ # postfixed to the end of the path.
65
+ #
66
+ # @param [Package] package
67
+ # the package this key is for
68
+ # @param [Array<String>] stuff
69
+ # the additional things to prepend
70
+ #
71
+ # @return [String]
72
+ #
73
+ def key_for(package, *stuff)
74
+ File.join(
75
+ package.metadata[:platform],
76
+ package.metadata[:platform_version],
77
+ package.metadata[:arch],
78
+ package.name,
79
+ *stuff,
80
+ )
81
+ end
82
+
83
+ #
84
+ # The access policy that corresponds to the +s3_access+ given in the
85
+ # initializer option. Any access control that is not the strict string
86
+ # +"public"+ is assumed to be private.
87
+ #
88
+ # @return [Symbol]
89
+ # the UberS3-ready access policy
90
+ #
91
+ def access_policy
92
+ if @options[:acl].to_s == 'public'
93
+ :public_read
94
+ else
95
+ :private
96
+ end
97
+ end
98
+ end
99
+ end
@@ -20,90 +20,177 @@ require 'uber-s3'
20
20
  module Omnibus
21
21
  class S3Cache
22
22
  include Logging
23
- include SoftwareS3URLs
24
23
 
25
- def initialize
26
- unless config.s3_bucket && config.s3_access_key && config.s3_secret_key
27
- raise InvalidS3Configuration.new(config.s3_bucket, config.s3_access_key, config.s3_secret_key)
24
+ class << self
25
+ #
26
+ # List all software in the cache.
27
+ #
28
+ # @return [Array<Software>]
29
+ #
30
+ def list
31
+ cached = keys
32
+ softwares.select do |software|
33
+ key = key_for(software)
34
+ cached.include?(key)
35
+ end
28
36
  end
29
- @client = UberS3.new(
30
- access_key: config.s3_access_key,
31
- secret_access_key: config.s3_secret_key,
32
- bucket: config.s3_bucket,
33
- adapter: :net_http,
34
- )
35
- end
36
37
 
37
- def config
38
- Omnibus.config
39
- end
38
+ #
39
+ # The list of objects in the cache, by their key.
40
+ #
41
+ # @return [Array<String>]
42
+ #
43
+ def keys
44
+ bucket.objects('/').map(&:key)
45
+ end
40
46
 
41
- def list
42
- existing_keys = list_by_key
43
- tarball_software.select { |s| existing_keys.include?(key_for_package(s)) }
44
- end
47
+ #
48
+ # List all software missing from the cache.
49
+ #
50
+ # @return [Array<Software>]
51
+ #
52
+ def missing
53
+ cached = keys
54
+ softwares.select do |software|
55
+ key = key_for(software)
56
+ !cached.include?(key)
57
+ end
58
+ end
45
59
 
46
- def list_by_key
47
- bucket.objects('/').map(&:key)
48
- end
60
+ #
61
+ # Populate the cache with the all the missing software definitions.
62
+ #
63
+ # @return [true]
64
+ #
65
+ def populate
66
+ missing.each do |software|
67
+ fetch(software)
68
+
69
+ key = key_for(software)
70
+ content = IO.read(software.project_file)
71
+
72
+ log.info(log_key) do
73
+ "Caching '#{software.project_file}' to '#{Config.s3_bucket}/#{key}'"
74
+ end
75
+
76
+ client.store(key, content,
77
+ access: :public_read,
78
+ content_md5: software.checksum
79
+ )
80
+ end
49
81
 
50
- def missing
51
- already_cached = list_by_key
52
- tarball_software.delete_if { |s| already_cached.include?(key_for_package(s)) }
53
- end
82
+ true
83
+ end
54
84
 
55
- def tarball_software
56
- Omnibus.projects.map do |project|
57
- project.library.select { |s| s.source && s.source.key?(:url) }
58
- end.flatten
59
- end
85
+ #
86
+ # Fetch all source tarballs onto the local machine.
87
+ #
88
+ # @return [true]
89
+ #
90
+ def fetch_missing
91
+ missing.each do |software|
92
+ fetch(software)
93
+ end
94
+ end
60
95
 
61
- def populate
62
- missing.each do |software|
63
- fetch(software)
96
+ #
97
+ # @private
98
+ #
99
+ # The key with which to cache the package on S3. This is the name of the
100
+ # package, the version of the package, and its checksum.
101
+ #
102
+ # @example
103
+ # "zlib-1.2.6-618e944d7c7cd6521551e30b32322f4a"
104
+ #
105
+ # @param [Software] software
106
+ #
107
+ # @return [String]
108
+ #
109
+ def key_for(software)
110
+ unless software.name
111
+ raise InsufficientSpecification.new(:name, software)
112
+ end
64
113
 
65
- key = key_for_package(software)
66
- content = IO.read(software.project_file)
114
+ unless software.version
115
+ raise InsufficientSpecification.new(:version, software)
116
+ end
67
117
 
68
- log.info(log_key) do
69
- "Uploading #{software.project_file} as #{config.s3_bucket}/#{key}"
118
+ unless software.checksum
119
+ raise InsufficientSpecification.new(:checksum, software)
70
120
  end
71
121
 
72
- @client.store(key, content, access: :public_read, content_md5: software.checksum)
122
+ "#{software.name}-#{software.version}-#{software.checksum}"
73
123
  end
74
- end
75
124
 
76
- def fetch_missing
77
- missing.each do |software|
78
- fetch(software)
125
+ private
126
+
127
+ #
128
+ # The client to connect to S3 with.
129
+ #
130
+ # @return [UberS3::Client]
131
+ #
132
+ def client
133
+ @client ||= UberS3.new(
134
+ access_key: Config.s3_access_key,
135
+ secret_access_key: Config.s3_secret_key,
136
+ bucket: Config.s3_bucket,
137
+ adapter: :net_http,
138
+ )
79
139
  end
80
- end
81
140
 
82
- private
83
-
84
- def ensure_cache_dir
85
- FileUtils.mkdir_p(config.cache_dir)
86
- end
141
+ #
142
+ # The bucket where the objects live.
143
+ #
144
+ # @return [UberS3::Bucket]
145
+ #
146
+ def bucket
147
+ @bucket ||= begin
148
+ if client.exists?('/')
149
+ client.bucket
150
+ else
151
+ client.connection.put('/')
152
+ end
153
+ end
154
+ end
87
155
 
88
- def fetch(software)
89
- log.info(log_key) { "Fetching #{software.name}" }
90
- fetcher = Fetcher.without_caching_for(software)
91
- if fetcher.fetch_required?
92
- log.debug(log_key) { 'Updating cache' }
93
- fetcher.download
94
- fetcher.verify_checksum!
95
- else
96
- log.debug(log_key) { 'Cached copy up to date, skipping.' }
156
+ #
157
+ # The list of softwares for all Omnibus projects.
158
+ #
159
+ # @return [Array<Software>]
160
+ #
161
+ def softwares
162
+ Omnibus.projects.inject({}) do |hash, project|
163
+ project.library.each do |software|
164
+ if software.source && software.source.key?(:url)
165
+ hash[software.name] = software
166
+ end
167
+ end
168
+
169
+ hash
170
+ end.values.sort
97
171
  end
98
- end
99
172
 
100
- def bucket
101
- @bucket ||= begin
102
- if @client.exists?('/')
103
- @client.bucket
173
+ #
174
+ # Fetch the remote software definition onto disk.
175
+ #
176
+ # @param [Software] software
177
+ # the software to fetch
178
+ #
179
+ # @return [true]
180
+ #
181
+ def fetch(software)
182
+ log.info(log_key) { "Fetching #{software.name}" }
183
+ fetcher = Fetcher.without_caching_for(software)
184
+
185
+ if fetcher.fetch_required?
186
+ log.debug(log_key) { 'Updating cache' }
187
+ fetcher.download
188
+ fetcher.verify_checksum!
104
189
  else
105
- @client.connection.put('/')
190
+ log.debug(log_key) { 'Cached copy up to date, skipping.' }
106
191
  end
192
+
193
+ true
107
194
  end
108
195
  end
109
196
  end