berkshelf 5.2.0 → 8.0.15
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/Gemfile +19 -47
- data/Rakefile +14 -4
- data/berkshelf.gemspec +61 -40
- data/bin/berks +2 -2
- data/lib/berkshelf/api-client.rb +1 -0
- data/lib/berkshelf/api_client/chef_server_connection.rb +29 -0
- data/lib/berkshelf/api_client/connection.rb +57 -0
- data/lib/berkshelf/api_client/errors.rb +10 -0
- data/lib/berkshelf/api_client/remote_cookbook.rb +56 -0
- data/lib/berkshelf/api_client/version.rb +5 -0
- data/lib/berkshelf/api_client.rb +24 -0
- data/lib/berkshelf/berksfile.rb +149 -122
- data/lib/berkshelf/cached_cookbook.rb +127 -24
- data/lib/berkshelf/chef_config_compat.rb +51 -0
- data/lib/berkshelf/chef_repo_universe.rb +47 -0
- data/lib/berkshelf/cli.rb +143 -174
- data/lib/berkshelf/commands/shelf.rb +20 -19
- data/lib/berkshelf/community_rest.rb +59 -94
- data/lib/berkshelf/config.rb +97 -127
- data/lib/berkshelf/cookbook_store.rb +7 -6
- data/lib/berkshelf/core_ext/file.rb +1 -1
- data/lib/berkshelf/core_ext/file_utils.rb +4 -4
- data/lib/berkshelf/core_ext.rb +1 -1
- data/lib/berkshelf/dependency.rb +25 -32
- data/lib/berkshelf/downloader.rb +66 -39
- data/lib/berkshelf/errors.rb +23 -17
- data/lib/berkshelf/file_syncer.rb +24 -47
- data/lib/berkshelf/formatters/human.rb +7 -5
- data/lib/berkshelf/formatters/json.rb +6 -6
- data/lib/berkshelf/installer.rb +120 -111
- data/lib/berkshelf/location.rb +14 -14
- data/lib/berkshelf/locations/base.rb +1 -1
- data/lib/berkshelf/locations/git.rb +16 -24
- data/lib/berkshelf/locations/github.rb +2 -2
- data/lib/berkshelf/locations/path.rb +2 -2
- data/lib/berkshelf/lockfile.rb +326 -328
- data/lib/berkshelf/logger.rb +64 -1
- data/lib/berkshelf/mixin/git.rb +6 -5
- data/lib/berkshelf/packager.rb +44 -10
- data/lib/berkshelf/resolver/graph.rb +1 -1
- data/lib/berkshelf/resolver.rb +4 -4
- data/lib/berkshelf/ridley_compat.rb +109 -0
- data/lib/berkshelf/shell.rb +2 -1
- data/lib/berkshelf/shell_out.rb +18 -0
- data/lib/berkshelf/source.rb +77 -33
- data/lib/berkshelf/source_uri.rb +4 -4
- data/lib/berkshelf/ssl_policies.rb +38 -0
- data/lib/berkshelf/thor.rb +1 -1
- data/lib/berkshelf/thor_ext/hash_with_indifferent_access.rb +1 -1
- data/lib/berkshelf/thor_ext.rb +1 -1
- data/lib/berkshelf/uploader.rb +106 -70
- data/lib/berkshelf/validator.rb +13 -5
- data/lib/berkshelf/version.rb +1 -1
- data/lib/berkshelf/visualizer.rb +16 -11
- data/lib/berkshelf.rb +106 -81
- data/spec/config/knife.rb +4 -4
- data/spec/data/trusted_certs/example.crt +22 -0
- data/spec/fixtures/Berksfile +3 -3
- data/spec/fixtures/complex-cookbook-path/cookbooks/app/metadata.rb +2 -0
- data/spec/fixtures/complex-cookbook-path/cookbooks/jenkins/metadata.rb +2 -0
- data/spec/fixtures/complex-cookbook-path/cookbooks/jenkins-config/metadata.rb +4 -0
- data/spec/fixtures/cookbook-path/jenkins-config/metadata.rb +3 -3
- data/spec/fixtures/cookbook-path-uploader/apt-2.3.6/metadata.rb +2 -0
- data/spec/fixtures/cookbook-path-uploader/build-essential-1.4.2/metadata.rb +2 -0
- data/spec/fixtures/cookbook-path-uploader/jenkins-2.0.3/metadata.rb +5 -0
- data/spec/fixtures/cookbook-path-uploader/jenkins-config-0.1.0/metadata.rb +4 -0
- data/spec/fixtures/cookbook-path-uploader/runit-1.5.8/metadata.rb +5 -0
- data/spec/fixtures/cookbook-path-uploader/yum-3.0.6/metadata.rb +2 -0
- data/spec/fixtures/cookbook-path-uploader/yum-epel-0.2.0/metadata.rb +3 -0
- data/spec/fixtures/cookbook-store/jenkins-2.0.3/metadata.rb +5 -5
- data/spec/fixtures/cookbook-store/jenkins-2.0.4/metadata.rb +4 -4
- data/spec/fixtures/cookbooks/example_cookbook/metadata.rb +3 -3
- data/spec/fixtures/cookbooks/example_cookbook-0.5.0/metadata.rb +3 -3
- data/spec/spec_helper.rb +56 -64
- data/spec/support/chef_api.rb +15 -16
- data/spec/support/chef_server.rb +71 -69
- data/spec/support/git.rb +59 -58
- data/spec/support/kitchen.rb +0 -14
- data/spec/support/matchers/file_system_matchers.rb +4 -5
- data/spec/support/matchers/filepath_matchers.rb +2 -2
- data/spec/support/path_helpers.rb +17 -17
- data/spec/support/shared_examples/formatter.rb +1 -1
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/attributes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/files/default/file.h +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/metadata.rb +2 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/recipes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.1.0/templates/default/template.erb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/attributes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/files/default/file.h +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/metadata.rb +2 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/recipes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-0.2.0/templates/default/template.erb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/attributes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/files/default/file.h +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/metadata.rb +2 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/recipes/default.rb +0 -0
- data/spec/tmp/berkshelf/cookbooks/fake-1.0.0/templates/default/template.erb +0 -0
- data/spec/unit/berkshelf/berksfile_spec.rb +84 -105
- data/spec/unit/berkshelf/berkshelf/api_client/chef_server_connection_spec.rb +65 -0
- data/spec/unit/berkshelf/berkshelf/api_client/connection_spec.rb +157 -0
- data/spec/unit/berkshelf/berkshelf/api_client/remote_cookbook_spec.rb +23 -0
- data/spec/unit/berkshelf/berkshelf/api_client_spec.rb +9 -0
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +45 -47
- data/spec/unit/berkshelf/chef_repo_universe_spec.rb +37 -0
- data/spec/unit/berkshelf/cli_spec.rb +7 -8
- data/spec/unit/berkshelf/community_rest_spec.rb +82 -90
- data/spec/unit/berkshelf/config_spec.rb +51 -22
- data/spec/unit/berkshelf/cookbook_store_spec.rb +41 -41
- data/spec/unit/berkshelf/core_ext/file_utils_spec.rb +7 -8
- data/spec/unit/berkshelf/core_ext/pathname_spec.rb +1 -1
- data/spec/unit/berkshelf/dependency_spec.rb +48 -48
- data/spec/unit/berkshelf/downloader_spec.rb +191 -34
- data/spec/unit/berkshelf/errors_spec.rb +3 -3
- data/spec/unit/berkshelf/file_syncer_spec.rb +87 -87
- data/spec/unit/berkshelf/formatters/base_spec.rb +23 -23
- data/spec/unit/berkshelf/formatters/human_spec.rb +2 -2
- data/spec/unit/berkshelf/formatters/json_spec.rb +2 -2
- data/spec/unit/berkshelf/formatters/null_spec.rb +3 -3
- data/spec/unit/berkshelf/installer_spec.rb +8 -8
- data/spec/unit/berkshelf/location_spec.rb +11 -11
- data/spec/unit/berkshelf/locations/base_spec.rb +35 -36
- data/spec/unit/berkshelf/locations/git_spec.rb +90 -93
- data/spec/unit/berkshelf/locations/path_spec.rb +40 -41
- data/spec/unit/berkshelf/lockfile_parser_spec.rb +71 -71
- data/spec/unit/berkshelf/lockfile_spec.rb +205 -211
- data/spec/unit/berkshelf/logger_spec.rb +3 -3
- data/spec/unit/berkshelf/mixin/logging_spec.rb +5 -5
- data/spec/unit/berkshelf/packager_spec.rb +2 -2
- data/spec/unit/berkshelf/resolver/graph_spec.rb +10 -8
- data/spec/unit/berkshelf/resolver_spec.rb +17 -17
- data/spec/unit/berkshelf/ridley_compat_spec.rb +16 -0
- data/spec/unit/berkshelf/shell_spec.rb +34 -34
- data/spec/unit/berkshelf/source_spec.rb +186 -20
- data/spec/unit/berkshelf/source_uri_spec.rb +1 -1
- data/spec/unit/berkshelf/ssl_policies_spec.rb +86 -0
- data/spec/unit/berkshelf/uploader_spec.rb +146 -64
- data/spec/unit/berkshelf/validator_spec.rb +23 -16
- data/spec/unit/berkshelf/visualizer_spec.rb +24 -15
- data/spec/unit/berkshelf_spec.rb +18 -18
- metadata +138 -289
- data/.gitignore +0 -29
- data/.travis.yml +0 -64
- data/CHANGELOG.legacy.md +0 -307
- data/CHANGELOG.md +0 -1358
- data/CONTRIBUTING.md +0 -64
- data/Gemfile.lock +0 -399
- data/Guardfile +0 -23
- data/PLUGINS.md +0 -25
- data/README.md +0 -70
- data/Thorfile +0 -61
- data/appveyor.yml +0 -31
- data/docs/berkshelf_for_newcomers.md +0 -65
- data/features/berksfile.feature +0 -46
- data/features/commands/apply.feature +0 -41
- data/features/commands/contingent.feature +0 -48
- data/features/commands/cookbook.feature +0 -35
- data/features/commands/info.feature +0 -99
- data/features/commands/init.feature +0 -27
- data/features/commands/install.feature +0 -636
- data/features/commands/list.feature +0 -78
- data/features/commands/outdated.feature +0 -130
- data/features/commands/package.feature +0 -17
- data/features/commands/search.feature +0 -17
- data/features/commands/shelf/list.feature +0 -32
- data/features/commands/shelf/show.feature +0 -143
- data/features/commands/shelf/uninstall.feature +0 -96
- data/features/commands/show.feature +0 -83
- data/features/commands/update.feature +0 -142
- data/features/commands/upload.feature +0 -426
- data/features/commands/vendor.feature +0 -111
- data/features/commands/verify.feature +0 -29
- data/features/commands/viz.feature +0 -66
- data/features/community_site.feature +0 -37
- data/features/config.feature +0 -111
- data/features/help.feature +0 -11
- data/features/json_formatter.feature +0 -161
- data/features/lifecycle.feature +0 -378
- data/features/lockfile.feature +0 -378
- data/features/step_definitions/berksfile_steps.rb +0 -39
- data/features/step_definitions/chef/config_steps.rb +0 -12
- data/features/step_definitions/chef_server_steps.rb +0 -60
- data/features/step_definitions/cli_steps.rb +0 -18
- data/features/step_definitions/config_steps.rb +0 -46
- data/features/step_definitions/environment_steps.rb +0 -7
- data/features/step_definitions/filesystem_steps.rb +0 -269
- data/features/step_definitions/gem_steps.rb +0 -13
- data/features/step_definitions/json_steps.rb +0 -23
- data/features/step_definitions/utility_steps.rb +0 -11
- data/features/support/aruba.rb +0 -12
- data/features/support/env.rb +0 -82
- data/generator_files/Berksfile.erb +0 -11
- data/generator_files/CHANGELOG.md.erb +0 -3
- data/generator_files/Gemfile.erb +0 -8
- data/generator_files/README.md.erb +0 -42
- data/generator_files/Thorfile.erb +0 -11
- data/generator_files/Vagrantfile.erb +0 -117
- data/generator_files/chefignore +0 -94
- data/generator_files/default_recipe.erb +0 -6
- data/generator_files/default_test.rb.erb +0 -11
- data/generator_files/gitignore.erb +0 -23
- data/generator_files/helpers.rb.erb +0 -7
- data/generator_files/licenses/apachev2.erb +0 -13
- data/generator_files/licenses/gplv2.erb +0 -15
- data/generator_files/licenses/gplv3.erb +0 -14
- data/generator_files/licenses/mit.erb +0 -20
- data/generator_files/licenses/reserved.erb +0 -3
- data/generator_files/metadata.rb.erb +0 -11
- data/lib/berkshelf/base_generator.rb +0 -43
- data/lib/berkshelf/commands/test_command.rb +0 -13
- data/lib/berkshelf/cookbook_generator.rb +0 -133
- data/lib/berkshelf/init_generator.rb +0 -195
- data/spec/fixtures/cookbooks/example_cookbook/.gitignore +0 -2
- data/spec/fixtures/cookbooks/example_cookbook/.kitchen.yml +0 -26
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +0 -110
- data/spec/unit/berkshelf/init_generator_spec.rb +0 -263
@@ -1,4 +1,4 @@
|
|
1
|
-
require
|
1
|
+
require "fileutils" unless defined?(FileUtils)
|
2
2
|
|
3
3
|
module FileUtils
|
4
4
|
class << self
|
@@ -14,10 +14,10 @@ module FileUtils
|
|
14
14
|
# symlink on Linux
|
15
15
|
# @see {FileUtils::mv}
|
16
16
|
def mv(src, dest, options = {})
|
17
|
-
old_mv(src, dest, options)
|
17
|
+
old_mv(src, dest, **options)
|
18
18
|
rescue Errno::EACCES, Errno::ENOENT
|
19
|
-
options.delete(:force) if options.
|
20
|
-
FileUtils.cp_r(src, dest, options)
|
19
|
+
options.delete(:force) if options.key?(:force)
|
20
|
+
FileUtils.cp_r(src, dest, **options)
|
21
21
|
FileUtils.rm_rf(src)
|
22
22
|
end
|
23
23
|
end
|
data/lib/berkshelf/core_ext.rb
CHANGED
data/lib/berkshelf/dependency.rb
CHANGED
@@ -22,7 +22,7 @@ module Berkshelf
|
|
22
22
|
# @return [String]
|
23
23
|
attr_reader :name
|
24
24
|
# @return [Array<String,Symbol>]
|
25
|
-
|
25
|
+
attr_writer :groups
|
26
26
|
# @return [Berkshelf::Location]
|
27
27
|
attr_reader :location
|
28
28
|
# @return [Semverse::Version]
|
@@ -122,23 +122,24 @@ module Berkshelf
|
|
122
122
|
def cached_cookbook
|
123
123
|
return @cached_cookbook if @cached_cookbook
|
124
124
|
|
125
|
-
@cached_cookbook =
|
126
|
-
|
125
|
+
@cached_cookbook =
|
126
|
+
if location
|
127
|
+
cookbook = location.cached_cookbook
|
127
128
|
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
|
129
|
+
# If we have a cached cookbook, tighten our constraints
|
130
|
+
if cookbook
|
131
|
+
self.locked_version = cookbook.version
|
132
|
+
self.version_constraint = cookbook.version
|
133
|
+
end
|
133
134
|
|
134
|
-
|
135
|
-
else
|
136
|
-
if locked_version
|
137
|
-
CookbookStore.instance.cookbook(name, locked_version)
|
135
|
+
cookbook
|
138
136
|
else
|
139
|
-
|
137
|
+
if locked_version
|
138
|
+
CookbookStore.instance.cookbook(name, locked_version)
|
139
|
+
else
|
140
|
+
CookbookStore.instance.satisfy(name, version_constraint)
|
141
|
+
end
|
140
142
|
end
|
141
|
-
end
|
142
143
|
|
143
144
|
@cached_cookbook
|
144
145
|
end
|
@@ -150,15 +151,6 @@ module Berkshelf
|
|
150
151
|
groups.include?(group.to_sym)
|
151
152
|
end
|
152
153
|
|
153
|
-
# The location for this dependency, such as a remote Chef Server, the
|
154
|
-
# community API, :git, or a :path location. By default, this will be the
|
155
|
-
# community API.
|
156
|
-
#
|
157
|
-
# @return [Berkshelf::Location]
|
158
|
-
def location
|
159
|
-
@location
|
160
|
-
end
|
161
|
-
|
162
154
|
# The list of groups this dependency belongs to.
|
163
155
|
#
|
164
156
|
# @return [Array<Symbol>]
|
@@ -167,7 +159,7 @@ module Berkshelf
|
|
167
159
|
end
|
168
160
|
|
169
161
|
def <=>(other)
|
170
|
-
[
|
162
|
+
[name, version_constraint] <=> [other.name, other.version_constraint]
|
171
163
|
end
|
172
164
|
|
173
165
|
def to_s
|
@@ -175,20 +167,21 @@ module Berkshelf
|
|
175
167
|
end
|
176
168
|
|
177
169
|
def inspect
|
178
|
-
|
170
|
+
"#<Berkshelf::Dependency: " << [
|
179
171
|
"#{name} (#{version_constraint})",
|
180
172
|
"locked_version: #{locked_version.inspect}",
|
181
173
|
"groups: #{groups}",
|
182
|
-
"location: #{location ||
|
183
|
-
].join(
|
174
|
+
"location: #{location || "default"}>",
|
175
|
+
].join(", ")
|
184
176
|
end
|
185
177
|
|
186
178
|
def to_lock
|
187
|
-
out =
|
188
|
-
"
|
189
|
-
|
190
|
-
|
191
|
-
|
179
|
+
out =
|
180
|
+
if location || version_constraint.to_s == ">= 0.0.0"
|
181
|
+
" #{name}\n"
|
182
|
+
else
|
183
|
+
" #{name} (#{version_constraint})\n"
|
184
|
+
end
|
192
185
|
|
193
186
|
out << location.to_lock if location
|
194
187
|
out
|
data/lib/berkshelf/downloader.rb
CHANGED
@@ -1,5 +1,7 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "net/http" unless defined?(Net::HTTP)
|
2
|
+
require "mixlib/archive" unless defined?(Mixlib::Archive)
|
3
|
+
require_relative "ssl_policies"
|
4
|
+
require "faraday" unless defined?(Faraday)
|
3
5
|
|
4
6
|
module Berkshelf
|
5
7
|
class Downloader
|
@@ -14,6 +16,10 @@ module Berkshelf
|
|
14
16
|
@berksfile = berksfile
|
15
17
|
end
|
16
18
|
|
19
|
+
def ssl_policy
|
20
|
+
@ssl_policy ||= SSLPolicy.new
|
21
|
+
end
|
22
|
+
|
17
23
|
# Download the given Berkshelf::Dependency. If the optional block is given,
|
18
24
|
# the temporary path to the cookbook is yielded and automatically deleted
|
19
25
|
# when the block returns. If no block is given, it is the responsibility of
|
@@ -28,11 +34,12 @@ module Berkshelf
|
|
28
34
|
#
|
29
35
|
# @return [String]
|
30
36
|
def download(*args, &block)
|
31
|
-
options
|
37
|
+
# options are ignored
|
38
|
+
# options = args.last.is_a?(Hash) ? args.pop : Hash.new
|
32
39
|
dependency, version = args
|
33
40
|
|
34
41
|
sources.each do |source|
|
35
|
-
if result = try_download(source, dependency, version)
|
42
|
+
if ( result = try_download(source, dependency, version) )
|
36
43
|
if block_given?
|
37
44
|
value = yield result
|
38
45
|
FileUtils.rm_rf(result)
|
@@ -43,7 +50,7 @@ module Berkshelf
|
|
43
50
|
end
|
44
51
|
end
|
45
52
|
|
46
|
-
raise CookbookNotFound.new(dependency, version,
|
53
|
+
raise CookbookNotFound.new(dependency, version, "in any of the sources")
|
47
54
|
end
|
48
55
|
|
49
56
|
# @param [Berkshelf::Source] source
|
@@ -52,27 +59,46 @@ module Berkshelf
|
|
52
59
|
#
|
53
60
|
# @return [String]
|
54
61
|
def try_download(source, name, version)
|
55
|
-
unless remote_cookbook = source.cookbook(name, version)
|
62
|
+
unless ( remote_cookbook = source.cookbook(name, version) )
|
56
63
|
return nil
|
57
64
|
end
|
58
65
|
|
59
66
|
case remote_cookbook.location_type
|
60
67
|
when :opscode, :supermarket
|
61
|
-
|
68
|
+
options = { ssl: source.options[:ssl] }
|
69
|
+
if source.type == :artifactory
|
70
|
+
options[:headers] = { "X-Jfrog-Art-Api" => source.options[:api_key] }
|
71
|
+
end
|
72
|
+
|
73
|
+
# Allow Berkshelf install to function if a relative url exists in location_path
|
74
|
+
path = URI.parse(remote_cookbook.location_path).absolute? ? remote_cookbook.location_path : "#{source.uri_string}#{remote_cookbook.location_path}"
|
75
|
+
|
76
|
+
CommunityREST.new(path, options).download(name, version)
|
62
77
|
when :chef_server
|
78
|
+
tmp_dir = Dir.mktmpdir
|
79
|
+
unpack_dir = Pathname.new(tmp_dir) + "#{name}-#{version}"
|
63
80
|
# @todo Dynamically get credentials for remote_cookbook.location_path
|
64
81
|
credentials = {
|
65
82
|
server_url: remote_cookbook.location_path,
|
66
|
-
client_name: Berkshelf::Config.instance.chef.node_name,
|
67
|
-
client_key: Berkshelf::Config.instance.chef.client_key,
|
68
|
-
ssl:
|
83
|
+
client_name: source.options[:client_name] || Berkshelf::Config.instance.chef.node_name,
|
84
|
+
client_key: source.options[:client_key] || Berkshelf::Config.instance.chef.client_key,
|
85
|
+
ssl: source.options[:ssl],
|
69
86
|
}
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
87
|
+
RidleyCompat.new_client(**credentials) do |conn|
|
88
|
+
cookbook = Chef::CookbookVersion.load(name, version)
|
89
|
+
manifest = cookbook.cookbook_manifest
|
90
|
+
manifest.by_parent_directory.each do |segment, files|
|
91
|
+
files.each do |segment_file|
|
92
|
+
dest = File.join(unpack_dir, segment_file["path"].gsub("/", File::SEPARATOR))
|
93
|
+
FileUtils.mkdir_p(File.dirname(dest))
|
94
|
+
tempfile = conn.streaming_request(segment_file["url"])
|
95
|
+
FileUtils.mv(tempfile.path, dest)
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
unpack_dir
|
74
100
|
when :github
|
75
|
-
|
101
|
+
require "octokit"
|
76
102
|
|
77
103
|
tmp_dir = Dir.mktmpdir
|
78
104
|
archive_path = File.join(tmp_dir, "#{name}-#{version}.tar.gz")
|
@@ -81,19 +107,21 @@ module Berkshelf
|
|
81
107
|
# Find the correct github connection options for this specific cookbook.
|
82
108
|
cookbook_uri = URI.parse(remote_cookbook.location_path)
|
83
109
|
if cookbook_uri.host == "github.com"
|
84
|
-
options = Berkshelf::Config.instance.github.detect { |opts| opts["web_endpoint"]
|
85
|
-
options = {} if options
|
110
|
+
options = Berkshelf::Config.instance.github.detect { |opts| opts["web_endpoint"].nil? }
|
111
|
+
options = {} if options.nil?
|
86
112
|
else
|
87
113
|
options = Berkshelf::Config.instance.github.detect { |opts| opts["web_endpoint"] == "#{cookbook_uri.scheme}://#{cookbook_uri.host}" }
|
88
|
-
raise ConfigurationError.new "Missing github endpoint configuration for #{cookbook_uri.scheme}://#{cookbook_uri.host}" if options
|
114
|
+
raise ConfigurationError.new "Missing github endpoint configuration for #{cookbook_uri.scheme}://#{cookbook_uri.host}" if options.nil?
|
89
115
|
end
|
90
116
|
|
91
|
-
github_client = Octokit::Client.new(
|
92
|
-
|
93
|
-
|
117
|
+
github_client = Octokit::Client.new(
|
118
|
+
access_token: options["access_token"],
|
119
|
+
api_endpoint: options["api_endpoint"], web_endpoint: options["web_endpoint"],
|
120
|
+
connection_options: { ssl: { verify: options["ssl_verify"].nil? ? true : options["ssl_verify"] } }
|
121
|
+
)
|
94
122
|
|
95
123
|
begin
|
96
|
-
url = URI(github_client.archive_link(cookbook_uri.path.gsub(
|
124
|
+
url = URI(github_client.archive_link(cookbook_uri.path.gsub(%r{^/}, ""), ref: "v#{version}"))
|
97
125
|
rescue Octokit::Unauthorized
|
98
126
|
return nil
|
99
127
|
end
|
@@ -101,9 +129,10 @@ module Berkshelf
|
|
101
129
|
# We use Net::HTTP.new and then get here, because Net::HTTP.get does not support proxy settings.
|
102
130
|
http = Net::HTTP.new(url.host, url.port)
|
103
131
|
http.use_ssl = url.scheme == "https"
|
104
|
-
http.verify_mode = (options[
|
132
|
+
http.verify_mode = (options["ssl_verify"].nil? || options["ssl_verify"]) ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
|
105
133
|
resp = http.get(url.request_uri)
|
106
134
|
return nil unless resp.is_a?(Net::HTTPSuccess)
|
135
|
+
|
107
136
|
open(archive_path, "wb") { |file| file.write(resp.body) }
|
108
137
|
|
109
138
|
Mixlib::Archive.new(archive_path).extract(unpack_dir)
|
@@ -111,20 +140,20 @@ module Berkshelf
|
|
111
140
|
# we need to figure out where the cookbook is located in the archive. This is because the directory name
|
112
141
|
# pattern is not cosistant between private and public github repositories
|
113
142
|
cookbook_directory = Dir.entries(unpack_dir).select do |f|
|
114
|
-
(! f.start_with?(
|
143
|
+
(! f.start_with?(".")) && (Pathname.new(File.join(unpack_dir, f)).cookbook?)
|
115
144
|
end[0]
|
116
145
|
|
117
146
|
File.join(unpack_dir, cookbook_directory)
|
118
147
|
when :uri
|
119
|
-
|
148
|
+
require "open-uri" unless defined?(OpenURI)
|
120
149
|
|
121
150
|
tmp_dir = Dir.mktmpdir
|
122
151
|
archive_path = Pathname.new(tmp_dir) + "#{name}-#{version}.tar.gz"
|
123
152
|
unpack_dir = Pathname.new(tmp_dir) + "#{name}-#{version}"
|
124
153
|
|
125
154
|
url = remote_cookbook.location_path
|
126
|
-
open(url,
|
127
|
-
archive_path.open(
|
155
|
+
URI.open(url, "rb") do |remote_file|
|
156
|
+
archive_path.open("wb") { |local_file| local_file.write remote_file.read }
|
128
157
|
end
|
129
158
|
|
130
159
|
Mixlib::Archive.new(archive_path).extract(unpack_dir)
|
@@ -132,13 +161,11 @@ module Berkshelf
|
|
132
161
|
# The top level directory is inconsistant. So we unpack it and
|
133
162
|
# use the only directory created in the unpack_dir.
|
134
163
|
cookbook_directory = unpack_dir.entries.select do |filename|
|
135
|
-
(! filename.to_s.start_with?(
|
164
|
+
(! filename.to_s.start_with?(".")) && (unpack_dir + filename).cookbook?
|
136
165
|
end.first
|
137
166
|
|
138
167
|
(unpack_dir + cookbook_directory).to_s
|
139
168
|
when :gitlab
|
140
|
-
#Thread.exclusive { require 'octokit' unless defined?(Octokit) }
|
141
|
-
|
142
169
|
tmp_dir = Dir.mktmpdir
|
143
170
|
archive_path = Pathname.new(tmp_dir) + "#{name}-#{version}.tar.gz"
|
144
171
|
unpack_dir = Pathname.new(tmp_dir) + "#{name}-#{version}"
|
@@ -147,26 +174,26 @@ module Berkshelf
|
|
147
174
|
cookbook_uri = URI.parse(remote_cookbook.location_path)
|
148
175
|
if cookbook_uri.host
|
149
176
|
options = Berkshelf::Config.instance.gitlab.detect { |opts| opts["web_endpoint"] == "#{cookbook_uri.scheme}://#{cookbook_uri.host}" }
|
150
|
-
raise ConfigurationError.new "Missing github endpoint configuration for #{cookbook_uri.scheme}://#{cookbook_uri.host}" if options
|
177
|
+
raise ConfigurationError.new "Missing github endpoint configuration for #{cookbook_uri.scheme}://#{cookbook_uri.host}" if options.nil?
|
151
178
|
end
|
152
179
|
|
153
|
-
connection ||= Faraday.new(url: options[
|
154
|
-
faraday.headers[:accept] =
|
180
|
+
connection ||= Faraday.new(url: options["web_endpoint"]) do |faraday|
|
181
|
+
faraday.headers[:accept] = "application/x-tar"
|
155
182
|
faraday.response :logger, @logger unless @logger.nil?
|
156
|
-
faraday.adapter Faraday.default_adapter
|
183
|
+
faraday.adapter Faraday.default_adapter # make requests with Net::HTTP
|
157
184
|
end
|
158
185
|
|
159
|
-
resp = connection.get(cookbook_uri.request_uri +
|
186
|
+
resp = connection.get(cookbook_uri.request_uri + "&private_token=" + options["private_token"])
|
160
187
|
return nil unless resp.status == 200
|
188
|
+
|
161
189
|
open(archive_path, "wb") { |file| file.write(resp.body) }
|
162
190
|
|
163
|
-
|
164
|
-
Archive::Tar::Minitar.unpack(tgz, unpack_dir)
|
191
|
+
Mixlib::Archive.new(archive_path).extract(unpack_dir)
|
165
192
|
|
166
193
|
# The top level directory is inconsistant. So we unpack it and
|
167
194
|
# use the only directory created in the unpack_dir.
|
168
195
|
cookbook_directory = unpack_dir.entries.select do |filename|
|
169
|
-
(! filename.to_s.start_with?(
|
196
|
+
(! filename.to_s.start_with?(".")) && (unpack_dir + filename).cookbook?
|
170
197
|
end.first
|
171
198
|
|
172
199
|
(unpack_dir + cookbook_directory).to_s
|
@@ -175,7 +202,7 @@ module Berkshelf
|
|
175
202
|
FileUtils.cp_r(remote_cookbook.location_path, tmp_dir)
|
176
203
|
File.join(tmp_dir, name)
|
177
204
|
else
|
178
|
-
raise
|
205
|
+
raise "unknown location type #{remote_cookbook.location_type}"
|
179
206
|
end
|
180
207
|
rescue CookbookNotFound
|
181
208
|
nil
|
data/lib/berkshelf/errors.rb
CHANGED
@@ -61,7 +61,7 @@ module Berkshelf
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def to_s
|
64
|
-
out
|
64
|
+
out = "Your Berksfile contains multiple entries named "
|
65
65
|
out << "'#{@name}'. Please remove duplicate dependencies, or put them in "
|
66
66
|
out << "different groups."
|
67
67
|
out
|
@@ -83,7 +83,7 @@ module Berkshelf
|
|
83
83
|
|
84
84
|
def to_s
|
85
85
|
@original_exception.to_s +
|
86
|
-
|
86
|
+
"Unable to find a solution for demands: #{demands.join(", ")}"
|
87
87
|
end
|
88
88
|
|
89
89
|
alias_method :message, :to_s
|
@@ -91,6 +91,7 @@ module Berkshelf
|
|
91
91
|
|
92
92
|
class CookbookSyntaxError < BerkshelfError; set_status_code(107); end
|
93
93
|
class ConstraintNotSatisfied < BerkshelfError; set_status_code(111); end
|
94
|
+
|
94
95
|
class BerksfileReadError < BerkshelfError
|
95
96
|
set_status_code(113)
|
96
97
|
|
@@ -254,6 +255,7 @@ module Berkshelf
|
|
254
255
|
end
|
255
256
|
|
256
257
|
class UploadFailure < BerkshelfError; end
|
258
|
+
|
257
259
|
class FrozenCookbook < UploadFailure
|
258
260
|
set_status_code(126)
|
259
261
|
|
@@ -285,11 +287,11 @@ module Berkshelf
|
|
285
287
|
|
286
288
|
def to_s
|
287
289
|
"Berkshelf could not find compatible versions for cookbook '#{@dependency.name}':\n" +
|
288
|
-
|
289
|
-
|
290
|
-
|
291
|
-
|
292
|
-
|
290
|
+
" In Berksfile:\n" +
|
291
|
+
" #{@dependency.name} (#{@dependency.version_constraint})\n\n" +
|
292
|
+
" In Berksfile.lock:\n" +
|
293
|
+
" #{@locked.name} (#{@locked.version})\n\n" +
|
294
|
+
"Try running `berks update #{@dependency.name}`, which will try to find '#{@dependency.name}' matching " +
|
293
295
|
"'#{@dependency.version_constraint}'."
|
294
296
|
end
|
295
297
|
|
@@ -314,7 +316,7 @@ module Berkshelf
|
|
314
316
|
set_status_code(130)
|
315
317
|
|
316
318
|
def to_s
|
317
|
-
|
319
|
+
"There was an error connecting to the Chef Server"
|
318
320
|
end
|
319
321
|
end
|
320
322
|
|
@@ -372,7 +374,7 @@ module Berkshelf
|
|
372
374
|
|
373
375
|
def to_s
|
374
376
|
"Unknown license: '#{license}'\n" +
|
375
|
-
|
377
|
+
"Available licenses: #{CookbookGenerator::LICENSES.join(", ")}"
|
376
378
|
end
|
377
379
|
|
378
380
|
alias_method :message, :to_s
|
@@ -436,11 +438,12 @@ module Berkshelf
|
|
436
438
|
end
|
437
439
|
|
438
440
|
class DuplicateDemand < BerkshelfError; set_status_code(138); end
|
441
|
+
|
439
442
|
class LockfileNotFound < BerkshelfError
|
440
443
|
set_status_code(140)
|
441
444
|
|
442
445
|
def to_s
|
443
|
-
|
446
|
+
"Lockfile not found! Run `berks install` to create the lockfile."
|
444
447
|
end
|
445
448
|
end
|
446
449
|
|
@@ -467,7 +470,7 @@ module Berkshelf
|
|
467
470
|
set_status_code(144)
|
468
471
|
|
469
472
|
def to_s
|
470
|
-
|
473
|
+
"The lockfile is out of sync! Run `berks install` to sync the lockfile."
|
471
474
|
end
|
472
475
|
end
|
473
476
|
|
@@ -527,6 +530,9 @@ module Berkshelf
|
|
527
530
|
alias_method :message, :to_s
|
528
531
|
end
|
529
532
|
|
533
|
+
class CookbookSyntaxError < BerkshelfError; end
|
534
|
+
class RedirectLimitReached < BerkshelfError; end
|
535
|
+
|
530
536
|
class MissingLockfileCookbookVersion < CookbookNotFound
|
531
537
|
set_status_code(149)
|
532
538
|
|
@@ -544,7 +550,7 @@ module Berkshelf
|
|
544
550
|
def intialize(environment_file)
|
545
551
|
@environment_file = environment_file
|
546
552
|
end
|
547
|
-
|
553
|
+
|
548
554
|
def to_s
|
549
555
|
"Could not find environment file #{@environment_file}"
|
550
556
|
end
|
@@ -556,11 +562,11 @@ module Berkshelf
|
|
556
562
|
|
557
563
|
class GitNotInstalled < GitError
|
558
564
|
def initialize
|
559
|
-
super
|
560
|
-
|
561
|
-
|
562
|
-
|
563
|
-
|
565
|
+
super "You need to install Git before you can download " \
|
566
|
+
"cookbooks from git repositories. For more information, please " \
|
567
|
+
"see the Git docs: http://git-scm.org. If you have git installed, " \
|
568
|
+
"please make sure it is in your $PATH and accessible by the user " \
|
569
|
+
"running this command."
|
564
570
|
end
|
565
571
|
end
|
566
572
|
|
@@ -1,11 +1,11 @@
|
|
1
|
-
require
|
1
|
+
require "fileutils" unless defined?(FileUtils)
|
2
2
|
|
3
3
|
module Berkshelf
|
4
4
|
module FileSyncer
|
5
5
|
extend self
|
6
6
|
|
7
7
|
# Files to be ignored during a directory globbing
|
8
|
-
IGNORED_FILES = %w
|
8
|
+
IGNORED_FILES = %w{. ..}.freeze
|
9
9
|
|
10
10
|
#
|
11
11
|
# Glob across the given pattern, accounting for dotfiles, removing Ruby's
|
@@ -17,8 +17,15 @@ module Berkshelf
|
|
17
17
|
# @return [Array<String>]
|
18
18
|
# the list of all files
|
19
19
|
#
|
20
|
-
|
21
|
-
|
20
|
+
# @note
|
21
|
+
# Globbing on windows is strange. Do not pass a path that contains
|
22
|
+
# "symlinked" directories. Dir.glob will not see them. As an example,
|
23
|
+
# 'C:\Documents and Settings' is not a real directory and int recent
|
24
|
+
# versions of windows points at 'C:\users'. Some users have their
|
25
|
+
# temp directory still referring to 'C:\Documents and Settings'.
|
26
|
+
#
|
27
|
+
def glob(pattern, **kwargs)
|
28
|
+
Dir.glob(pattern, File::FNM_DOTMATCH, **kwargs).sort.reject do |file|
|
22
29
|
basename = File.basename(file)
|
23
30
|
IGNORED_FILES.include?(basename)
|
24
31
|
end
|
@@ -58,24 +65,17 @@ module Berkshelf
|
|
58
65
|
[exclude, "#{exclude}/*"]
|
59
66
|
end.flatten
|
60
67
|
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
65
|
-
|
66
|
-
source_files = glob(File.join(source, '**/*'))
|
67
|
-
source_files = source_files.reject do |source_file|
|
68
|
-
basename = relative_path_for(source_file, source)
|
69
|
-
excludes.any? { |exclude| File.fnmatch?(exclude, basename, File::FNM_DOTMATCH) }
|
70
|
-
end
|
68
|
+
source_files =
|
69
|
+
glob("**/*", base: source).reject do |source_file|
|
70
|
+
excludes.any? { |exclude| File.fnmatch?(exclude, source_file, File::FNM_DOTMATCH) }
|
71
|
+
end
|
71
72
|
|
72
73
|
# Ensure the destination directory exists
|
73
74
|
FileUtils.mkdir_p(destination) unless File.directory?(destination)
|
74
75
|
|
75
76
|
# Copy over the filtered source files
|
76
|
-
source_files.each do |
|
77
|
-
|
78
|
-
|
77
|
+
source_files.each do |relative_path|
|
78
|
+
source_file = File.join(source, relative_path)
|
79
79
|
# Create the parent directory
|
80
80
|
parent = File.join(destination, File.dirname(relative_path))
|
81
81
|
FileUtils.mkdir_p(parent) unless File.directory?(parent)
|
@@ -87,14 +87,15 @@ module Berkshelf
|
|
87
87
|
target = File.readlink(source_file)
|
88
88
|
|
89
89
|
destination = File.expand_path(destination)
|
90
|
-
|
91
|
-
FileUtils.ln_sf(target, "#{destination}/#{relative_path}")
|
92
|
-
end
|
90
|
+
FileUtils.ln_sf(target, "#{destination}/#{relative_path}")
|
93
91
|
when :file
|
92
|
+
# TODO: Workaround issue related to [1] which impacts running ChefSpec on Github Actions
|
93
|
+
# [1] https://github.com/docker/for-linux/issues/1015
|
94
|
+
FileUtils.touch(source_file)
|
94
95
|
FileUtils.cp(source_file, "#{destination}/#{relative_path}")
|
95
96
|
else
|
96
97
|
type = File.ftype(source_file)
|
97
|
-
raise
|
98
|
+
raise "Unknown file type: `#{type}' at " \
|
98
99
|
"`#{source_file}'. Failed to sync `#{source_file}' to " \
|
99
100
|
"`#{destination}/#{relative_path}'!"
|
100
101
|
end
|
@@ -102,20 +103,11 @@ module Berkshelf
|
|
102
103
|
|
103
104
|
if options[:delete]
|
104
105
|
# Remove any files in the destination that are not in the source files
|
105
|
-
destination_files = glob("
|
106
|
-
|
107
|
-
# Calculate the relative paths of files so we can compare to the
|
108
|
-
# source.
|
109
|
-
relative_source_files = source_files.map do |file|
|
110
|
-
relative_path_for(file, source)
|
111
|
-
end
|
112
|
-
relative_destination_files = destination_files.map do |file|
|
113
|
-
relative_path_for(file, destination)
|
114
|
-
end
|
106
|
+
destination_files = glob("**/*", base: destination)
|
115
107
|
|
116
108
|
# Remove any extra files that are present in the destination, but are
|
117
109
|
# not in the source list
|
118
|
-
extra_files =
|
110
|
+
extra_files = destination_files - source_files
|
119
111
|
extra_files.each do |file|
|
120
112
|
FileUtils.rm_rf(File.join(destination, file))
|
121
113
|
end
|
@@ -123,20 +115,5 @@ module Berkshelf
|
|
123
115
|
|
124
116
|
true
|
125
117
|
end
|
126
|
-
|
127
|
-
private
|
128
|
-
#
|
129
|
-
# The relative path of the given +path+ to the +parent+.
|
130
|
-
#
|
131
|
-
# @param [String] path
|
132
|
-
# the path to get relative with
|
133
|
-
# @param [String] parent
|
134
|
-
# the parent where the path is contained (hopefully)
|
135
|
-
#
|
136
|
-
# @return [String]
|
137
|
-
#
|
138
|
-
def relative_path_for(path, parent)
|
139
|
-
Pathname.new(path).relative_path_from(Pathname.new(parent)).to_s
|
140
|
-
end
|
141
118
|
end
|
142
119
|
end
|
@@ -19,7 +19,9 @@ module Berkshelf
|
|
19
19
|
def install(source, cookbook)
|
20
20
|
message = "Installing #{cookbook.name} (#{cookbook.version})"
|
21
21
|
|
22
|
-
|
22
|
+
if source.type == :chef_repo
|
23
|
+
message << " from #{cookbook.location_path}"
|
24
|
+
elsif !source.default?
|
23
25
|
message << " from #{source}"
|
24
26
|
message << " ([#{cookbook.location_type}] #{cookbook.location_path})"
|
25
27
|
end
|
@@ -60,13 +62,13 @@ module Berkshelf
|
|
60
62
|
# { 'cookbook' => { 'supermarket.chef.io' => #<Cookbook> } }
|
61
63
|
def outdated(hash)
|
62
64
|
if hash.empty?
|
63
|
-
Berkshelf.ui.info(
|
65
|
+
Berkshelf.ui.info("All cookbooks up to date!")
|
64
66
|
else
|
65
|
-
Berkshelf.ui.info(
|
67
|
+
Berkshelf.ui.info("The following cookbooks have newer versions:")
|
66
68
|
|
67
69
|
hash.each do |name, info|
|
68
|
-
info[
|
69
|
-
out = " * #{name} (#{info[
|
70
|
+
info["remote"].each do |remote_source, remote_version|
|
71
|
+
out = " * #{name} (#{info["local"]} => #{remote_version})"
|
70
72
|
|
71
73
|
unless remote_source.default?
|
72
74
|
out << " [#{remote_source.uri}]"
|
@@ -8,11 +8,11 @@ module Berkshelf
|
|
8
8
|
def initialize
|
9
9
|
@output = {
|
10
10
|
cookbooks: [],
|
11
|
-
errors:
|
12
|
-
messages:
|
13
|
-
warnings:
|
11
|
+
errors: [],
|
12
|
+
messages: [],
|
13
|
+
warnings: [],
|
14
14
|
}
|
15
|
-
@cookbooks =
|
15
|
+
@cookbooks = {}
|
16
16
|
|
17
17
|
Berkshelf.ui.mute { super }
|
18
18
|
end
|
@@ -92,11 +92,11 @@ module Berkshelf
|
|
92
92
|
# { 'cookbook' => { 'supermarket.chef.io' => #<Cookbook> } }
|
93
93
|
def outdated(hash)
|
94
94
|
hash.each do |name, info|
|
95
|
-
info[
|
95
|
+
info["remote"].each do |remote_source, remote_version|
|
96
96
|
source = remote_source.uri.to_s
|
97
97
|
|
98
98
|
cookbooks[name] ||= {}
|
99
|
-
cookbooks[name][:local] = info[
|
99
|
+
cookbooks[name][:local] = info["local"].to_s
|
100
100
|
cookbooks[name][:remote] ||= {}
|
101
101
|
cookbooks[name][:remote][source] = remote_version.to_s
|
102
102
|
end
|