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,7 +1,7 @@
|
|
1
1
|
module Berkshelf
|
2
2
|
# All tasks that operate on the Berkshelf shelf.
|
3
3
|
class Shelf < Thor
|
4
|
-
desc
|
4
|
+
desc "list", "List all cookbooks and their versions"
|
5
5
|
def list
|
6
6
|
cookbooks = store.cookbooks.inject({}) do |hash, cookbook|
|
7
7
|
(hash[cookbook.cookbook_name] ||= []).push(cookbook.version)
|
@@ -9,17 +9,17 @@ module Berkshelf
|
|
9
9
|
end
|
10
10
|
|
11
11
|
if cookbooks.empty?
|
12
|
-
Berkshelf.formatter.msg
|
12
|
+
Berkshelf.formatter.msg "There are no cookbooks in the Berkshelf shelf"
|
13
13
|
else
|
14
|
-
Berkshelf.formatter.msg
|
14
|
+
Berkshelf.formatter.msg "Cookbooks in the Berkshelf shelf:"
|
15
15
|
cookbooks.sort.each do |cookbook, versions|
|
16
|
-
Berkshelf.formatter.msg(" * #{cookbook} (#{versions.sort.join(
|
16
|
+
Berkshelf.formatter.msg(" * #{cookbook} (#{versions.sort.join(", ")})")
|
17
17
|
end
|
18
18
|
end
|
19
19
|
end
|
20
20
|
|
21
|
-
method_option :version, aliases:
|
22
|
-
desc
|
21
|
+
method_option :version, aliases: "-v", type: :string, desc: "Version to show"
|
22
|
+
desc "show", "Display information about a cookbook in the Berkshelf shelf"
|
23
23
|
def show(name)
|
24
24
|
cookbooks = find(name, options[:version])
|
25
25
|
|
@@ -35,9 +35,9 @@ module Berkshelf
|
|
35
35
|
end
|
36
36
|
end
|
37
37
|
|
38
|
-
method_option :version, aliases:
|
39
|
-
method_option :force, aliases:
|
40
|
-
desc
|
38
|
+
method_option :version, aliases: "-v", type: :string, desc: "Version to remove"
|
39
|
+
method_option :force, aliases: "-f", type: :boolean, desc: "Force removal, even if other cookbooks are contingent", default: false
|
40
|
+
desc "uninstall", "Remove a cookbook from the Berkshelf shelf"
|
41
41
|
def uninstall(name)
|
42
42
|
cookbooks = find(name, options[:version])
|
43
43
|
cookbooks.each { |c| uninstall_cookbook(c, options[:force]) }
|
@@ -67,14 +67,15 @@ module Berkshelf
|
|
67
67
|
# the list of cookbooks that match the parameters - this is always an
|
68
68
|
# array!
|
69
69
|
def find(name, version = nil)
|
70
|
-
cookbooks =
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
70
|
+
cookbooks =
|
71
|
+
if version
|
72
|
+
[store.cookbook(name, version)].compact
|
73
|
+
else
|
74
|
+
store.cookbooks(name).sort
|
75
|
+
end
|
75
76
|
|
76
77
|
if cookbooks.empty?
|
77
|
-
raise CookbookNotFound.new(name, version,
|
78
|
+
raise CookbookNotFound.new(name, version, "in the Berkshelf shelf")
|
78
79
|
end
|
79
80
|
|
80
81
|
cookbooks
|
@@ -95,10 +96,10 @@ module Berkshelf
|
|
95
96
|
# if contingencies exist
|
96
97
|
def uninstall_cookbook(cookbook, force = false)
|
97
98
|
unless options[:force] || (contingent = contingencies(cookbook)).empty?
|
98
|
-
contingent = contingent.map { |c| "#{c.cookbook_name} (#{c.version})" }.join(
|
99
|
+
contingent = contingent.map { |c| "#{c.cookbook_name} (#{c.version})" }.join(", ")
|
99
100
|
confirm = Berkshelf.ui.ask("[#{contingent}] depend on #{cookbook.cookbook_name}.\n\nAre you sure you want to continue? (y/N)")
|
100
101
|
|
101
|
-
exit unless confirm.to_s.upcase[0] ==
|
102
|
+
exit unless confirm.to_s.upcase[0] == "Y"
|
102
103
|
end
|
103
104
|
|
104
105
|
FileUtils.rm_rf(cookbook.path)
|
@@ -120,7 +121,7 @@ module Berkshelf
|
|
120
121
|
end
|
121
122
|
|
122
123
|
class Cli < Thor
|
123
|
-
desc
|
124
|
-
subcommand
|
124
|
+
desc "shelf SUBCOMMAND", "Interact with the cookbook store"
|
125
|
+
subcommand "shelf", Berkshelf::Shelf
|
125
126
|
end
|
126
127
|
end
|
@@ -1,9 +1,8 @@
|
|
1
|
-
require
|
2
|
-
require
|
3
|
-
require 'mixlib/archive'
|
1
|
+
require "retryable" unless defined?(Retryable)
|
2
|
+
require "mixlib/archive" unless defined?(Mixlib::Archive)
|
4
3
|
|
5
4
|
module Berkshelf
|
6
|
-
class CommunityREST
|
5
|
+
class CommunityREST
|
7
6
|
class << self
|
8
7
|
# @param [String] target
|
9
8
|
# file path to the tar.gz archive on disk
|
@@ -25,30 +24,30 @@ module Berkshelf
|
|
25
24
|
#
|
26
25
|
# @return [String]
|
27
26
|
def uri_escape_version(version)
|
28
|
-
version.to_s.
|
27
|
+
version.to_s.tr(".", "_")
|
29
28
|
end
|
30
29
|
|
31
30
|
# @param [String] uri
|
32
31
|
#
|
33
32
|
# @return [String]
|
34
33
|
def version_from_uri(uri)
|
35
|
-
File.basename(uri.to_s).
|
34
|
+
File.basename(uri.to_s).tr("_", ".")
|
36
35
|
end
|
37
36
|
|
38
37
|
private
|
39
38
|
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
39
|
+
def is_gzip_file(path)
|
40
|
+
# You cannot write "\x1F\x8B" because the default encoding of
|
41
|
+
# ruby >= 1.9.3 is UTF-8 and 8B is an invalid in UTF-8.
|
42
|
+
IO.binread(path, 2) == [0x1F, 0x8B].pack("C*")
|
43
|
+
end
|
45
44
|
|
46
|
-
|
47
|
-
|
48
|
-
|
45
|
+
def is_tar_file(path)
|
46
|
+
IO.binread(path, 8, 257).to_s == "ustar\x0000"
|
47
|
+
end
|
49
48
|
end
|
50
49
|
|
51
|
-
V1_API =
|
50
|
+
V1_API = "https://supermarket.chef.io".freeze
|
52
51
|
|
53
52
|
# @return [String]
|
54
53
|
attr_reader :api_uri
|
@@ -58,6 +57,8 @@ module Berkshelf
|
|
58
57
|
# @return [Float]
|
59
58
|
# time to wait between retries
|
60
59
|
attr_reader :retry_interval
|
60
|
+
# @return [Berkshelf::RidleyCompat]
|
61
|
+
attr_reader :connection
|
61
62
|
|
62
63
|
# @param [String] uri (CommunityREST::V1_API)
|
63
64
|
# location of community site to connect to
|
@@ -67,23 +68,14 @@ module Berkshelf
|
|
67
68
|
# @option options [Float] :retry_interval (0.5)
|
68
69
|
# how often we should pause between retries
|
69
70
|
def initialize(uri = V1_API, options = {})
|
70
|
-
options
|
71
|
-
|
72
|
-
@
|
71
|
+
options = options.dup
|
72
|
+
options = { retries: 5, retry_interval: 0.5, ssl: Berkshelf::Config.instance.ssl }.merge(options)
|
73
|
+
@api_uri = uri
|
74
|
+
options[:server_url] = uri
|
75
|
+
@retries = options.delete(:retries)
|
73
76
|
@retry_interval = options.delete(:retry_interval)
|
74
77
|
|
75
|
-
|
76
|
-
b.response :parse_json
|
77
|
-
b.response :follow_redirects
|
78
|
-
b.request :retry,
|
79
|
-
max: @retries,
|
80
|
-
interval: @retry_interval,
|
81
|
-
exceptions: [Faraday::Error::TimeoutError]
|
82
|
-
|
83
|
-
b.adapter :httpclient
|
84
|
-
end
|
85
|
-
|
86
|
-
super(api_uri, options)
|
78
|
+
@connection = Berkshelf::RidleyCompatJSON.new(**options)
|
87
79
|
end
|
88
80
|
|
89
81
|
# Download and extract target cookbook archive to the local file system,
|
@@ -97,14 +89,14 @@ module Berkshelf
|
|
97
89
|
# @return [String, nil]
|
98
90
|
# cookbook filepath, or nil if archive does not contain a cookbook
|
99
91
|
def download(name, version)
|
100
|
-
archive
|
92
|
+
archive = stream(find(name, version)["file"])
|
101
93
|
scratch = Dir.mktmpdir
|
102
94
|
extracted = self.class.unpack(archive.path, scratch)
|
103
95
|
|
104
96
|
if File.cookbook?(extracted)
|
105
97
|
extracted
|
106
98
|
else
|
107
|
-
Dir.glob(
|
99
|
+
Dir.glob("#{extracted}/*").find do |dir|
|
108
100
|
File.cookbook?(dir)
|
109
101
|
end
|
110
102
|
end
|
@@ -113,50 +105,53 @@ module Berkshelf
|
|
113
105
|
end
|
114
106
|
|
115
107
|
def find(name, version)
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
108
|
+
body = connection.get("cookbooks/#{name}/versions/#{self.class.uri_escape_version(version)}")
|
109
|
+
|
110
|
+
# Artifactory responds with a 200 and blank body for unknown cookbooks.
|
111
|
+
raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") if body.nil?
|
112
|
+
|
113
|
+
body
|
114
|
+
rescue CookbookNotFound
|
115
|
+
raise
|
116
|
+
rescue Berkshelf::APIClient::ServiceNotFound
|
117
|
+
raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
|
118
|
+
rescue
|
119
|
+
raise CommunitySiteError.new(api_uri, "'#{name}' (#{version})")
|
126
120
|
end
|
127
121
|
|
128
122
|
# Returns the latest version of the cookbook and its download link.
|
129
123
|
#
|
130
124
|
# @return [String]
|
131
125
|
def latest_version(name)
|
132
|
-
|
126
|
+
body = connection.get("cookbooks/#{name}")
|
133
127
|
|
134
|
-
|
135
|
-
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
-
|
128
|
+
# Artifactory responds with a 200 and blank body for unknown cookbooks.
|
129
|
+
raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") if body.nil?
|
130
|
+
|
131
|
+
self.class.version_from_uri body["latest_version"]
|
132
|
+
rescue Berkshelf::APIClient::ServiceNotFound
|
133
|
+
raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
|
134
|
+
rescue
|
135
|
+
raise CommunitySiteError.new(api_uri, "the latest version of '#{name}'")
|
142
136
|
end
|
143
137
|
|
144
138
|
# @param [String] name
|
145
139
|
#
|
146
140
|
# @return [Array]
|
147
141
|
def versions(name)
|
148
|
-
|
142
|
+
body = connection.get("cookbooks/#{name}")
|
149
143
|
|
150
|
-
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
when 404
|
156
|
-
raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
|
157
|
-
else
|
158
|
-
raise CommunitySiteError.new(api_uri, "versions of '#{name}'")
|
144
|
+
# Artifactory responds with a 200 and blank body for unknown cookbooks.
|
145
|
+
raise CookbookNotFound.new(name, nil, "at `#{api_uri}'") if body.nil?
|
146
|
+
|
147
|
+
body["versions"].collect do |version_uri|
|
148
|
+
self.class.version_from_uri(version_uri)
|
159
149
|
end
|
150
|
+
|
151
|
+
rescue Berkshelf::APIClient::ServiceNotFound
|
152
|
+
raise CookbookNotFound.new(name, nil, "at `#{api_uri}'")
|
153
|
+
rescue
|
154
|
+
raise CommunitySiteError.new(api_uri, "versions of '#{name}'")
|
160
155
|
end
|
161
156
|
|
162
157
|
# @param [String] name
|
@@ -176,43 +171,13 @@ module Berkshelf
|
|
176
171
|
#
|
177
172
|
# @return [Tempfile]
|
178
173
|
def stream(target)
|
179
|
-
local = Tempfile.new(
|
174
|
+
local = Tempfile.new("community-rest-stream")
|
180
175
|
local.binmode
|
181
|
-
|
182
|
-
|
183
|
-
open(target, 'rb', open_uri_options) do |remote|
|
184
|
-
local.write(remote.read)
|
185
|
-
end
|
176
|
+
Retryable.retryable(tries: retries, on: Berkshelf::APIClientError, sleep: retry_interval) do
|
177
|
+
connection.streaming_request(target, {}, local)
|
186
178
|
end
|
187
|
-
|
188
|
-
local
|
189
179
|
ensure
|
190
180
|
local.close(false) unless local.nil?
|
191
181
|
end
|
192
|
-
|
193
|
-
private
|
194
|
-
|
195
|
-
def open_uri_options
|
196
|
-
options = {}
|
197
|
-
options.merge!(headers)
|
198
|
-
options.merge!(open_uri_proxy_options)
|
199
|
-
options.merge!(ssl_verify_mode: ssl_verify_mode)
|
200
|
-
end
|
201
|
-
|
202
|
-
def open_uri_proxy_options
|
203
|
-
if proxy && proxy[:user] && proxy[:password]
|
204
|
-
{proxy_http_basic_authentication: [ proxy[:uri], proxy[:user], proxy[:password] ]}
|
205
|
-
else
|
206
|
-
{}
|
207
|
-
end
|
208
|
-
end
|
209
|
-
|
210
|
-
def ssl_verify_mode
|
211
|
-
if Berkshelf::Config.instance.ssl.verify.nil? || Berkshelf::Config.instance.ssl.verify
|
212
|
-
OpenSSL::SSL::VERIFY_PEER
|
213
|
-
else
|
214
|
-
OpenSSL::SSL::VERIFY_NONE
|
215
|
-
end
|
216
|
-
end
|
217
182
|
end
|
218
183
|
end
|
data/lib/berkshelf/config.rb
CHANGED
@@ -1,22 +1,32 @@
|
|
1
|
-
require
|
2
|
-
require
|
1
|
+
require "mixlib/config" unless defined?(Mixlib::Config)
|
2
|
+
require "openssl" unless defined?(OpenSSL)
|
3
|
+
|
4
|
+
# we need this method, but have to inject it into mixlib-config directly
|
5
|
+
# to have it available from config contexts
|
6
|
+
module Mixlib
|
7
|
+
module Config
|
8
|
+
def each(&block)
|
9
|
+
save(true).each(&block)
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
3
13
|
|
4
14
|
module Berkshelf
|
5
|
-
class Config
|
15
|
+
class Config
|
6
16
|
class << self
|
7
17
|
# @return [String]
|
8
18
|
def store_location
|
9
|
-
File.join(Berkshelf.berkshelf_path,
|
19
|
+
File.join(Berkshelf.berkshelf_path, "config.json")
|
10
20
|
end
|
11
21
|
|
12
22
|
# @return [String]
|
13
23
|
def local_location
|
14
|
-
ENV[
|
24
|
+
ENV["BERKSHELF_CONFIG"] || File.join(".", ".berkshelf", "config.json")
|
15
25
|
end
|
16
26
|
|
17
27
|
# @return [String]
|
18
28
|
def path
|
19
|
-
path = File.
|
29
|
+
path = File.exist?(local_location) ? local_location : store_location
|
20
30
|
File.expand_path(path)
|
21
31
|
end
|
22
32
|
|
@@ -30,22 +40,12 @@ module Berkshelf
|
|
30
40
|
@instance = nil
|
31
41
|
end
|
32
42
|
|
33
|
-
# @return [String, nil]
|
34
|
-
# the contents of the file
|
35
|
-
def file
|
36
|
-
File.read(path) if File.exists?(path)
|
37
|
-
end
|
38
|
-
|
39
43
|
# Instantiate and return or just return the currently instantiated Berkshelf
|
40
44
|
# configuration
|
41
45
|
#
|
42
46
|
# @return [Config]
|
43
47
|
def instance
|
44
|
-
@instance ||=
|
45
|
-
from_json file
|
46
|
-
else
|
47
|
-
new
|
48
|
-
end
|
48
|
+
@instance ||= new(path)
|
49
49
|
coerce_ssl
|
50
50
|
end
|
51
51
|
|
@@ -54,131 +54,101 @@ module Berkshelf
|
|
54
54
|
# @return [Config]
|
55
55
|
def reload
|
56
56
|
@instance = nil
|
57
|
-
|
57
|
+
instance
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
# force proper X509 types from any configuration strings
|
61
61
|
#
|
62
62
|
# @return [Config]
|
63
63
|
def coerce_ssl
|
64
|
-
ssl = @instance
|
64
|
+
ssl = @instance[:ssl]
|
65
65
|
ssl[:ca_cert] = OpenSSL::X509::Certificate.new(File.read(ssl[:ca_cert])) if ssl[:ca_cert] && ssl[:ca_cert].is_a?(String)
|
66
66
|
ssl[:client_cert] = OpenSSL::X509::Certificate.new(File.read(ssl[:client_cert])) if ssl[:client_cert] && ssl[:client_cert].is_a?(String)
|
67
67
|
ssl[:client_key] = OpenSSL::PKey::RSA.new(File.read(ssl[:client_key])) if ssl[:client_key] && ssl[:client_key].is_a?(String)
|
68
68
|
@instance
|
69
69
|
end
|
70
|
+
|
71
|
+
def from_file(path)
|
72
|
+
new(path)
|
73
|
+
end
|
70
74
|
end
|
71
75
|
|
76
|
+
attr_accessor :path
|
77
|
+
|
72
78
|
# @param [String] path
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
79
|
+
def initialize(path = self.class.path)
|
80
|
+
# this is a bit tricky, mixlib-config wants to extend a class and create effectively a global config object while
|
81
|
+
# what we want to do is use an instance, so we create an anonymous class and shove it into an instance variable.
|
82
|
+
# this is actually similar to what mixlib-config itself does to create config contexts.
|
83
|
+
@klass = Class.new
|
84
|
+
@klass.extend(Mixlib::Config)
|
85
|
+
@klass.extend(BerksConfig)
|
86
|
+
|
87
|
+
@path = File.expand_path(path)
|
88
|
+
@klass.from_file(@path) if File.exist?(@path)
|
89
|
+
# yeah, if !File.exist?() you just get back an empty config object
|
90
|
+
|
91
|
+
Berkshelf.ui.warn "The `cookbook.copyright' config is deprecated and will be removed in a future release." unless cookbook.copyright.nil?
|
92
|
+
Berkshelf.ui.warn "The `cookbook.email' config is deprecated and will be removed in a future release." unless cookbook.email.nil?
|
93
|
+
Berkshelf.ui.warn "The `cookbook.license' config is deprecated and will be removed in a future release." unless cookbook.license.nil?
|
94
|
+
Berkshelf.ui.warn "The `vagrant.vm.box' config is deprecated and will be removed in a future release." unless vagrant.vm.box.nil?
|
95
|
+
Berkshelf.ui.warn "The `vagrant.vm.forward_port' config is deprecated and will be removed in a future release." unless vagrant.vm.forward_port.nil?
|
96
|
+
Berkshelf.ui.warn "The `vagrant.vm.provision' config is deprecated and will be removed in a future release." unless vagrant.vm.provision.nil?
|
97
|
+
Berkshelf.ui.warn "The `vagrant.vm.omnibus.version' config is deprecated and will be removed in a future release." unless vagrant.vm.omnibus.version.nil?
|
98
|
+
end
|
99
|
+
|
100
|
+
def method_missing(method, *args, &block)
|
101
|
+
@klass.send(method, *args, &block)
|
102
|
+
end
|
103
|
+
|
104
|
+
module BerksConfig
|
105
|
+
def self.extended(base)
|
106
|
+
base.class_exec do
|
107
|
+
config_strict_mode true
|
108
|
+
config_context :api do
|
109
|
+
default :timeout, "30"
|
110
|
+
end
|
111
|
+
config_context :chef do
|
112
|
+
default :chef_server_url, Berkshelf.chef_config.chef_server_url
|
113
|
+
default :validation_client_name, Berkshelf.chef_config.validation_client_name
|
114
|
+
default :validation_key_path, Berkshelf.chef_config.validation_key
|
115
|
+
default :client_key, Berkshelf.chef_config.client_key
|
116
|
+
default :node_name, Berkshelf.chef_config.node_name
|
117
|
+
default :trusted_certs_dir, Berkshelf.chef_config.trusted_certs_dir
|
118
|
+
default :artifactory_api_key, Berkshelf.chef_config.artifactory_api_key
|
119
|
+
end
|
120
|
+
config_context :cookbook do
|
121
|
+
default :copyright, nil
|
122
|
+
default :email, nil
|
123
|
+
default :license, nil
|
124
|
+
end
|
125
|
+
default :allowed_licenses, []
|
126
|
+
default :raise_license_exception, false
|
127
|
+
config_context :vagrant do
|
128
|
+
config_context :vm do
|
129
|
+
default :box, nil
|
130
|
+
default :forward_port, nil
|
131
|
+
default :provision, nil
|
132
|
+
config_context :omnibus do
|
133
|
+
default :version, nil
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
config_context :ssl do
|
138
|
+
default :verify, true
|
139
|
+
default :cert_store, false
|
140
|
+
default :ca_file, nil
|
141
|
+
default :ca_path, nil
|
142
|
+
default :ca_cert, nil
|
143
|
+
default :client_cert, nil
|
144
|
+
default :client_key, nil
|
145
|
+
end
|
146
|
+
default :github, []
|
147
|
+
default :gitlab, []
|
148
|
+
# :git, :ssh, or :https
|
149
|
+
default :github_protocol, :https
|
87
150
|
end
|
88
151
|
end
|
89
152
|
end
|
90
|
-
|
91
|
-
attribute 'api.timeout',
|
92
|
-
type: String,
|
93
|
-
default: '30'
|
94
|
-
attribute 'chef.chef_server_url',
|
95
|
-
type: String,
|
96
|
-
default: Berkshelf.chef_config.chef_server_url
|
97
|
-
attribute 'chef.validation_client_name',
|
98
|
-
type: String,
|
99
|
-
default: Berkshelf.chef_config.validation_client_name
|
100
|
-
attribute 'chef.validation_key_path',
|
101
|
-
type: String,
|
102
|
-
default: Berkshelf.chef_config.validation_key
|
103
|
-
attribute 'chef.client_key',
|
104
|
-
type: String,
|
105
|
-
default: Berkshelf.chef_config.client_key
|
106
|
-
attribute 'chef.node_name',
|
107
|
-
type: String,
|
108
|
-
default: Berkshelf.chef_config.node_name
|
109
|
-
attribute 'cookbook.copyright',
|
110
|
-
type: String,
|
111
|
-
default: Berkshelf.chef_config.cookbook_copyright
|
112
|
-
attribute 'cookbook.email',
|
113
|
-
type: String,
|
114
|
-
default: Berkshelf.chef_config.cookbook_email
|
115
|
-
attribute 'cookbook.license',
|
116
|
-
type: String,
|
117
|
-
default: Berkshelf.chef_config.cookbook_license
|
118
|
-
attribute 'allowed_licenses',
|
119
|
-
type: Array,
|
120
|
-
default: Array.new
|
121
|
-
attribute 'raise_license_exception',
|
122
|
-
type: Buff::Boolean,
|
123
|
-
default: false
|
124
|
-
attribute 'vagrant.vm.box',
|
125
|
-
type: String,
|
126
|
-
default: 'bento/ubuntu-14.04',
|
127
|
-
required: true
|
128
|
-
# @todo Deprecated, remove?
|
129
|
-
attribute 'vagrant.vm.box_url',
|
130
|
-
type: String,
|
131
|
-
default: nil
|
132
|
-
attribute 'vagrant.vm.forward_port',
|
133
|
-
type: Hash,
|
134
|
-
default: Hash.new
|
135
|
-
attribute 'vagrant.vm.provision',
|
136
|
-
type: String,
|
137
|
-
default: 'chef_solo'
|
138
|
-
# @todo Deprecated, remove. There's a really weird tri-state here where
|
139
|
-
# nil is used to represent an unset value, just FYI
|
140
|
-
attribute 'vagrant.omnibus.enabled',
|
141
|
-
type: Buff::Boolean,
|
142
|
-
default: nil
|
143
|
-
attribute 'vagrant.omnibus.version',
|
144
|
-
type: String,
|
145
|
-
default: 'latest'
|
146
|
-
attribute 'ssl.verify',
|
147
|
-
type: Buff::Boolean,
|
148
|
-
default: true,
|
149
|
-
required: true
|
150
|
-
attribute 'ssl.cert_store',
|
151
|
-
type: Buff::Boolean,
|
152
|
-
default: false,
|
153
|
-
required: false
|
154
|
-
attribute 'ssl.ca_file',
|
155
|
-
type: String,
|
156
|
-
default: nil,
|
157
|
-
required: false
|
158
|
-
attribute 'ssl.ca_path',
|
159
|
-
type: String,
|
160
|
-
default: nil,
|
161
|
-
required: false
|
162
|
-
attribute 'ssl.client_cert',
|
163
|
-
type: String,
|
164
|
-
default: nil,
|
165
|
-
required: false
|
166
|
-
attribute 'ssl.client_key',
|
167
|
-
type: String,
|
168
|
-
default: nil,
|
169
|
-
required: false
|
170
|
-
attribute 'github',
|
171
|
-
type: Array,
|
172
|
-
default: [],
|
173
|
-
required: false
|
174
|
-
attribute 'gitlab',
|
175
|
-
type: Array,
|
176
|
-
default: [],
|
177
|
-
required: false
|
178
|
-
attribute 'github_protocol',
|
179
|
-
# :git, :ssh, or :https
|
180
|
-
type: Symbol,
|
181
|
-
default: :https,
|
182
|
-
required: false
|
183
153
|
end
|
184
154
|
end
|
@@ -1,4 +1,5 @@
|
|
1
|
-
require
|
1
|
+
require "fileutils" unless defined?(FileUtils)
|
2
|
+
require "chef/exceptions"
|
2
3
|
|
3
4
|
module Berkshelf
|
4
5
|
class CookbookStore
|
@@ -7,7 +8,7 @@ module Berkshelf
|
|
7
8
|
#
|
8
9
|
# @return [String]
|
9
10
|
def default_path
|
10
|
-
File.join(Berkshelf.berkshelf_path,
|
11
|
+
File.join(Berkshelf.berkshelf_path, "cookbooks")
|
11
12
|
end
|
12
13
|
|
13
14
|
# @return [Berkshelf::CookbookStore]
|
@@ -48,7 +49,7 @@ module Berkshelf
|
|
48
49
|
|
49
50
|
# Destroy the contents of the initialized storage path.
|
50
51
|
def clean!
|
51
|
-
FileUtils.rm_rf(Dir.glob(
|
52
|
+
FileUtils.rm_rf(Dir.glob("#{storage_path}/*"))
|
52
53
|
end
|
53
54
|
|
54
55
|
# Import a cookbook found on the local filesystem into this instance of the cookbook store.
|
@@ -65,7 +66,7 @@ module Berkshelf
|
|
65
66
|
destination = cookbook_path(name, version)
|
66
67
|
FileUtils.mv(path, destination)
|
67
68
|
cookbook(name, version)
|
68
|
-
rescue
|
69
|
+
rescue
|
69
70
|
FileUtils.rm_f(destination)
|
70
71
|
raise
|
71
72
|
end
|
@@ -106,7 +107,7 @@ module Berkshelf
|
|
106
107
|
|
107
108
|
begin
|
108
109
|
CachedCookbook.from_store_path(path)
|
109
|
-
rescue
|
110
|
+
rescue Chef::Exceptions::MetadataNotValid
|
110
111
|
# Skip cached cookbooks that do not have a name attribute.
|
111
112
|
skipped_cookbooks << File.basename(path)
|
112
113
|
next
|
@@ -162,7 +163,7 @@ module Berkshelf
|
|
162
163
|
graph = Solve::Graph.new
|
163
164
|
cookbooks(name).each { |cookbook| graph.artifact(name, cookbook.version) }
|
164
165
|
|
165
|
-
name, version = Solve.it!(graph, [[name, constraint]], ENV[
|
166
|
+
name, version = Solve.it!(graph, [[name, constraint]], ENV["DEBUG_RESOLVER"] ? { ui: Berkshelf.ui } : {}).first
|
166
167
|
|
167
168
|
cookbook(name, version)
|
168
169
|
rescue Solve::Errors::NoSolutionError
|
@@ -7,7 +7,7 @@ class File
|
|
7
7
|
#
|
8
8
|
# @return [Boolean]
|
9
9
|
def cookbook?(path)
|
10
|
-
File.
|
10
|
+
File.exist?(File.join(path, "metadata.json")) || File.exist?(File.join(path, "metadata.rb"))
|
11
11
|
end
|
12
12
|
alias_method :chef_cookbook?, :cookbook?
|
13
13
|
end
|