berkshelf 2.0.18 → 3.0.0.beta1
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.
- data/.ruby-version +1 -1
- data/.travis.yml +4 -1
- data/CHANGELOG.md +2 -26
- data/Gemfile +12 -2
- data/README.md +9 -1
- data/berkshelf.gemspec +9 -18
- data/bin/berks +3 -13
- data/features/apply_command.feature +11 -9
- data/features/berksfile.feature +8 -10
- data/features/config.feature +1 -2
- data/features/configure_command.feature +13 -14
- data/features/contingent_command.feature +13 -1
- data/features/cookbook_command.feature +2 -4
- data/features/groups_install.feature +10 -2
- data/features/help.feature +1 -1
- data/features/init_command.feature +5 -7
- data/features/install_command.feature +157 -228
- data/features/json_formatter.feature +27 -15
- data/features/licenses.feature +18 -12
- data/features/list_command.feature +6 -1
- data/features/lockfile.feature +116 -72
- data/features/outdated_command.feature +3 -47
- data/features/package_command.feature +10 -7
- data/features/shelf/show.feature +2 -2
- data/features/shelf/uninstall.feature +2 -2
- data/features/show_command.feature +10 -3
- data/features/step_definitions/chef/config_steps.rb +12 -0
- data/features/step_definitions/chef_server_steps.rb +16 -16
- data/features/step_definitions/cli_steps.rb +3 -79
- data/features/step_definitions/config_steps.rb +43 -0
- data/features/step_definitions/environment_steps.rb +7 -0
- data/features/step_definitions/filesystem_steps.rb +12 -57
- data/features/step_definitions/gem_steps.rb +1 -2
- data/features/step_definitions/json_steps.rb +3 -1
- data/features/step_definitions/lockfile_steps.rb +4 -0
- data/features/step_definitions/utility_steps.rb +0 -19
- data/features/support/aruba.rb +12 -0
- data/features/support/env.rb +52 -57
- data/features/update_command.feature +37 -23
- data/features/upload_command.feature +96 -160
- data/generator_files/Berksfile.erb +2 -1
- data/generator_files/Vagrantfile.erb +3 -0
- data/generator_files/default_test.rb.erb +1 -1
- data/generator_files/helpers.rb.erb +1 -1
- data/lib/berkshelf.rb +43 -24
- data/lib/berkshelf/api_client.rb +67 -0
- data/lib/berkshelf/api_client/remote_cookbook.rb +42 -0
- data/lib/berkshelf/berksfile.rb +232 -420
- data/lib/berkshelf/cached_cookbook.rb +22 -10
- data/lib/berkshelf/chef/config.rb +1 -0
- data/lib/berkshelf/cli.rb +66 -68
- data/lib/berkshelf/commands/shelf.rb +1 -1
- data/lib/berkshelf/community_rest.rb +10 -17
- data/lib/berkshelf/config.rb +23 -27
- data/lib/berkshelf/cookbook_generator.rb +3 -4
- data/lib/berkshelf/cookbook_store.rb +74 -17
- data/lib/berkshelf/core_ext/file.rb +2 -2
- data/lib/berkshelf/core_ext/pathname.rb +7 -5
- data/lib/berkshelf/{cookbook_source.rb → dependency.rb} +47 -67
- data/lib/berkshelf/downloader.rb +49 -106
- data/lib/berkshelf/errors.rb +64 -71
- data/lib/berkshelf/formatters.rb +11 -9
- data/lib/berkshelf/formatters/human_readable.rb +9 -9
- data/lib/berkshelf/formatters/json.rb +14 -4
- data/lib/berkshelf/init_generator.rb +3 -3
- data/lib/berkshelf/installer.rb +136 -0
- data/lib/berkshelf/location.rb +91 -131
- data/lib/berkshelf/locations/git_location.rb +9 -11
- data/lib/berkshelf/locations/github_location.rb +1 -1
- data/lib/berkshelf/locations/path_location.rb +10 -27
- data/lib/berkshelf/lockfile.rb +92 -70
- data/lib/berkshelf/logger.rb +4 -7
- data/lib/berkshelf/mixin/config.rb +21 -4
- data/lib/berkshelf/resolver.rb +60 -150
- data/lib/berkshelf/resolver/graph.rb +44 -0
- data/lib/berkshelf/source.rb +55 -0
- data/lib/berkshelf/source_uri.rb +38 -0
- data/lib/berkshelf/version.rb +1 -1
- data/spec/config/knife.rb +1 -1
- data/spec/fixtures/cassettes/Berkshelf_Resolver/_initialize/adds_the_dependencies_of_the_dependency_as_dependencies.yml +3694 -0
- data/spec/fixtures/cookbooks/example_cookbook/Berksfile.lock +1 -1
- data/spec/fixtures/lockfiles/default.lock +1 -1
- data/spec/spec_helper.rb +20 -121
- data/spec/support/chef_api.rb +3 -4
- data/spec/support/chef_server.rb +20 -11
- data/spec/support/git.rb +127 -0
- data/spec/support/kitchen.rb +12 -0
- data/spec/support/path_helpers.rb +69 -0
- data/spec/unit/berkshelf/api_client/remote_cookbook_spec.rb +23 -0
- data/spec/unit/berkshelf/api_client_spec.rb +57 -0
- data/spec/unit/berkshelf/berksfile_spec.rb +206 -324
- data/spec/unit/berkshelf/cached_cookbook_spec.rb +73 -38
- data/spec/unit/berkshelf/community_rest_spec.rb +30 -71
- data/spec/unit/berkshelf/config_spec.rb +3 -14
- data/spec/unit/berkshelf/cookbook_generator_spec.rb +1 -2
- data/spec/unit/berkshelf/cookbook_store_spec.rb +12 -7
- data/spec/unit/berkshelf/dependency_spec.rb +285 -0
- data/spec/unit/berkshelf/downloader_spec.rb +4 -183
- data/spec/unit/berkshelf/formatters/null_spec.rb +1 -1
- data/spec/unit/berkshelf/formatters_spec.rb +4 -2
- data/spec/unit/berkshelf/git_spec.rb +15 -15
- data/spec/unit/berkshelf/installer_spec.rb +39 -0
- data/spec/unit/berkshelf/location_spec.rb +87 -114
- data/spec/unit/berkshelf/locations/git_location_spec.rb +41 -53
- data/spec/unit/berkshelf/locations/path_location_spec.rb +13 -23
- data/spec/unit/berkshelf/lockfile_spec.rb +38 -40
- data/spec/unit/berkshelf/resolver/graph_spec.rb +44 -0
- data/spec/unit/berkshelf/resolver_spec.rb +34 -83
- data/spec/unit/berkshelf/source_spec.rb +23 -0
- data/spec/unit/berkshelf/source_uri_spec.rb +29 -0
- metadata +149 -188
- checksums.yaml +0 -7
- data/features/default_locations.feature +0 -127
- data/features/step_definitions/berksfile_steps.rb +0 -8
- data/features/step_definitions/configure_cli_steps.rb +0 -19
- data/features/vendor_install.feature +0 -19
- data/lib/berkshelf/core_ext/openuri.rb +0 -36
- data/lib/berkshelf/core_ext/rbzip2.rb +0 -8
- data/lib/berkshelf/locations/chef_api_location.rb +0 -228
- data/lib/berkshelf/locations/site_location.rb +0 -92
- data/lib/berkshelf/test.rb +0 -35
- data/spec/knife.rb.sample +0 -12
- data/spec/support/test_generators.rb +0 -27
- data/spec/unit/berkshelf/cli_spec.rb +0 -16
- data/spec/unit/berkshelf/cookbook_source_spec.rb +0 -358
- data/spec/unit/berkshelf/core_ext/pathname_spec.rb +0 -46
- data/spec/unit/berkshelf/locations/chef_api_location_spec.rb +0 -139
- data/spec/unit/berkshelf/locations/site_location_spec.rb +0 -19
checksums.yaml
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
SHA1:
|
|
3
|
-
metadata.gz: 4c1cb4c285df553eb0ef7571a584ab308d35f278
|
|
4
|
-
data.tar.gz: 66452c03b102b78cdf440841f99a644307677a3f
|
|
5
|
-
SHA512:
|
|
6
|
-
metadata.gz: 85bdfe1f3dd22b69af3343868ad5ae07ad17d457daf94cea5c267fa47dd3273f232efcd80ad358490b6bed94f6981f5453d459e7604121b1ef271aa4e12aaf91
|
|
7
|
-
data.tar.gz: 5525092c4221b4b32452cb214e50cbe7e6f0bc7e8b012a0403dbdf7875635797b707f99ea41f0d12e018f07b08d8b91d60698d71704bfe0565ada1e122e5df08
|
|
@@ -1,127 +0,0 @@
|
|
|
1
|
-
Feature: Berksfile default locations
|
|
2
|
-
As a Berkshelf user
|
|
3
|
-
I want to be able to define default locations in my Berksfile
|
|
4
|
-
So I can set the precedence of where cookbook sources are downloaded from or define an alternate location for all
|
|
5
|
-
cookbook sources to attempt to retrieve from
|
|
6
|
-
|
|
7
|
-
@chef_server
|
|
8
|
-
Scenario: with a default chef_api(1) and site(2) location with a cookbook source that is satisfied by the chef_api(1) location
|
|
9
|
-
Given I write to "Berksfile" with:
|
|
10
|
-
"""
|
|
11
|
-
chef_api :config
|
|
12
|
-
site :opscode
|
|
13
|
-
|
|
14
|
-
cookbook 'berkshelf-cookbook-fixture', '1.0.0'
|
|
15
|
-
"""
|
|
16
|
-
And the Chef server has cookbooks:
|
|
17
|
-
| berkshelf-cookbook-fixture | 1.0.0 |
|
|
18
|
-
When I successfully run `berks install`
|
|
19
|
-
Then the output should contain:
|
|
20
|
-
"""
|
|
21
|
-
Installing berkshelf-cookbook-fixture (1.0.0) from chef_api:
|
|
22
|
-
"""
|
|
23
|
-
And the cookbook store should have the cookbooks:
|
|
24
|
-
| berkshelf-cookbook-fixture | 1.0.0 |
|
|
25
|
-
And the exit status should be 0
|
|
26
|
-
|
|
27
|
-
@chef_server
|
|
28
|
-
Scenario: with a default chef_api(1) and site(2) location with a cookbook source that is not satisfied by the chef_api(1) location
|
|
29
|
-
Given I write to "Berksfile" with:
|
|
30
|
-
"""
|
|
31
|
-
chef_api :config
|
|
32
|
-
site :opscode
|
|
33
|
-
|
|
34
|
-
cookbook 'berkshelf-cookbook-fixture', '1.0.0'
|
|
35
|
-
"""
|
|
36
|
-
And the Chef server does not have the cookbooks:
|
|
37
|
-
| berkshelf-cookbook-fixture | 1.0.0 |
|
|
38
|
-
When I successfully run `berks install`
|
|
39
|
-
Then the output should contain:
|
|
40
|
-
"""
|
|
41
|
-
Installing berkshelf-cookbook-fixture (1.0.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
|
42
|
-
"""
|
|
43
|
-
And the cookbook store should have the cookbooks:
|
|
44
|
-
| berkshelf-cookbook-fixture | 1.0.0 |
|
|
45
|
-
And the exit status should be 0
|
|
46
|
-
|
|
47
|
-
@chef_server
|
|
48
|
-
Scenario: with a default site(1) and chef_api(2) location with a cookbook source that is satisfied by the site(1) location
|
|
49
|
-
Given I write to "Berksfile" with:
|
|
50
|
-
"""
|
|
51
|
-
site :opscode
|
|
52
|
-
chef_api :config
|
|
53
|
-
|
|
54
|
-
cookbook 'berkshelf-cookbook-fixture', '1.0.0'
|
|
55
|
-
"""
|
|
56
|
-
And the Chef server has cookbooks:
|
|
57
|
-
| berkshelf-cookbook-fixture | 1.0.0 |
|
|
58
|
-
When I run the install command
|
|
59
|
-
Then the output should contain:
|
|
60
|
-
"""
|
|
61
|
-
Installing berkshelf-cookbook-fixture (1.0.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
|
62
|
-
"""
|
|
63
|
-
And the cookbook store should have the cookbooks:
|
|
64
|
-
| berkshelf-cookbook-fixture | 1.0.0 |
|
|
65
|
-
And the exit status should be 0
|
|
66
|
-
|
|
67
|
-
@chef_server
|
|
68
|
-
Scenario: with a default chef_api(1) location and a cookbook source that is satisfied by the chef_api(1) location but has an explicit location set
|
|
69
|
-
Given I write to "Berksfile" with:
|
|
70
|
-
"""
|
|
71
|
-
chef_api :config
|
|
72
|
-
|
|
73
|
-
cookbook 'berkshelf-cookbook-fixture', '1.0.0', site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
|
74
|
-
"""
|
|
75
|
-
And the Chef server has cookbooks:
|
|
76
|
-
| berkshelf-cookbook-fixture | 1.0.0 |
|
|
77
|
-
When I run the install command
|
|
78
|
-
Then the output should contain:
|
|
79
|
-
"""
|
|
80
|
-
Installing berkshelf-cookbook-fixture (1.0.0) from site: 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
|
81
|
-
"""
|
|
82
|
-
And the cookbook store should have the cookbooks:
|
|
83
|
-
| berkshelf-cookbook-fixture | 1.0.0 |
|
|
84
|
-
And the exit status should be 0
|
|
85
|
-
|
|
86
|
-
@chef_server
|
|
87
|
-
Scenario: with a defualt chef_api(1) location and a cookbook source that is not satisfied by it
|
|
88
|
-
Given I write to "Berksfile" with:
|
|
89
|
-
"""
|
|
90
|
-
chef_api :config
|
|
91
|
-
|
|
92
|
-
cookbook 'berkshelf-cookbook-fixture', '1.0.0'
|
|
93
|
-
"""
|
|
94
|
-
And the Chef server does not have the cookbooks:
|
|
95
|
-
| berkshelf-cookbook-fixture | 1.0.0 |
|
|
96
|
-
When I run the install command
|
|
97
|
-
Then the output should contain:
|
|
98
|
-
"""
|
|
99
|
-
Cookbook 'berkshelf-cookbook-fixture' not found in any of the default locations
|
|
100
|
-
"""
|
|
101
|
-
And the CLI should exit with the status code for error "CookbookNotFound"
|
|
102
|
-
|
|
103
|
-
Scenario: with two duplicate locations definitions
|
|
104
|
-
Given I write to "Berksfile" with:
|
|
105
|
-
"""
|
|
106
|
-
site 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
|
107
|
-
site 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
|
108
|
-
|
|
109
|
-
cookbook 'berkshelf-cookbook-fixture', '1.0.0'
|
|
110
|
-
"""
|
|
111
|
-
When I run the install command
|
|
112
|
-
Then the output should contain:
|
|
113
|
-
"""
|
|
114
|
-
A default 'site' location with the value 'http://cookbooks.opscode.com/api/v1/cookbooks' is already defined
|
|
115
|
-
"""
|
|
116
|
-
And the CLI should exit with the status code for error "DuplicateLocationDefined"
|
|
117
|
-
|
|
118
|
-
Scenario: with two locations of the same type but different values
|
|
119
|
-
Given I write to "Berksfile" with:
|
|
120
|
-
"""
|
|
121
|
-
site 'http://cookbooks.opscode.com/api/v1/cookbooks'
|
|
122
|
-
site 'http://cookbooks.opscode.com/api/v2/cookbooks'
|
|
123
|
-
|
|
124
|
-
cookbook 'berkshelf-cookbook-fixture', '1.0.0'
|
|
125
|
-
"""
|
|
126
|
-
When I run the install command
|
|
127
|
-
Then the exit status should be 0
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
Given /^a Berksfile with path location sources to fixtures:$/ do |cookbooks|
|
|
2
|
-
lines = []
|
|
3
|
-
cookbooks.raw.each do |name, fixture|
|
|
4
|
-
fixture_path = fixtures_path.join("cookbooks", fixture)
|
|
5
|
-
lines << "cookbook '#{name}', path: '#{fixture_path}'"
|
|
6
|
-
end
|
|
7
|
-
write_file("Berksfile", lines.join("\n"))
|
|
8
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
Given /^I have a default Chef config$/ do
|
|
2
|
-
path = tmp_path.join('chef_config').to_s
|
|
3
|
-
generate_chef_config(path)
|
|
4
|
-
ENV['BERKSHELF_CHEF_CONFIG'] = path
|
|
5
|
-
end
|
|
6
|
-
|
|
7
|
-
Then /^a Berkshelf config file should exist and contain:$/ do |table|
|
|
8
|
-
config = Berkshelf::Config.from_file(Berkshelf::Config.path)
|
|
9
|
-
table.raw.each do |key, value|
|
|
10
|
-
expect(config.get_attribute(key)).to eq(value)
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
|
|
14
|
-
Then /^a Berkshelf config file should exist at "(.+)" and contain:$/ do |path, table|
|
|
15
|
-
config = Berkshelf::Config.from_file(File.expand_path("tmp/aruba/#{path}"))
|
|
16
|
-
table.raw.each do |key, value|
|
|
17
|
-
config.get_attribute(key).should eql(value)
|
|
18
|
-
end
|
|
19
|
-
end
|
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
Feature: Vendoring cookbooks to a specific path
|
|
2
|
-
As a user of Berkshelf
|
|
3
|
-
I want to be able to install cookbooks to a specific directory
|
|
4
|
-
So I vendor my cookbooks and package them with my application
|
|
5
|
-
|
|
6
|
-
Scenario: With a path option
|
|
7
|
-
Given the cookbook store has the cookbooks:
|
|
8
|
-
| fake | 1.0.0 |
|
|
9
|
-
Given I write to "Berksfile" with:
|
|
10
|
-
"""
|
|
11
|
-
site :opscode
|
|
12
|
-
cookbook 'fake', '1.0.0'
|
|
13
|
-
"""
|
|
14
|
-
When I run the install command with flags:
|
|
15
|
-
| --path vendor/cookbooks |
|
|
16
|
-
Then the following directories should exist:
|
|
17
|
-
| vendor/cookbooks |
|
|
18
|
-
| vendor/cookbooks/fake |
|
|
19
|
-
And the exit status should be 0
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
#
|
|
2
|
-
# Patch to allow open-uri to follow safe (http to https) and unsafe
|
|
3
|
-
# redirections (https to http).
|
|
4
|
-
#
|
|
5
|
-
# Original gist URL:
|
|
6
|
-
# https://gist.github.com/1271420
|
|
7
|
-
#
|
|
8
|
-
# Relevant issue:
|
|
9
|
-
# http://redmine.ruby-lang.org/issues/3719
|
|
10
|
-
#
|
|
11
|
-
# Source here:
|
|
12
|
-
# https://github.com/ruby/ruby/blob/trunk/lib/open-uri.rb
|
|
13
|
-
#
|
|
14
|
-
module OpenURI
|
|
15
|
-
class <<self
|
|
16
|
-
alias_method :open_uri_original, :open_uri
|
|
17
|
-
|
|
18
|
-
def redirectable_safe?(uri1, uri2)
|
|
19
|
-
uri1.scheme.downcase == uri2.scheme.downcase || (uri1.scheme.downcase == "http" && uri2.scheme.downcase == "https")
|
|
20
|
-
end
|
|
21
|
-
|
|
22
|
-
def redirectable_all?(uri1, uri2)
|
|
23
|
-
redirectable_safe?(uri1, uri2) || (uri1.scheme.downcase == "https" && uri2.scheme.downcase == "http")
|
|
24
|
-
end
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# Patches the original open_uri method to follow all redirects
|
|
28
|
-
def self.open_uri(name, *rest, &block)
|
|
29
|
-
class << self
|
|
30
|
-
remove_method :redirectable?
|
|
31
|
-
alias_method :redirectable?, :redirectable_all?
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
self.open_uri_original(name, *rest, &block)
|
|
35
|
-
end
|
|
36
|
-
end
|
|
@@ -1,228 +0,0 @@
|
|
|
1
|
-
module Berkshelf
|
|
2
|
-
class ChefAPILocation
|
|
3
|
-
class << self
|
|
4
|
-
# @return [Proc]
|
|
5
|
-
def finalizer
|
|
6
|
-
proc { conn.terminate if defined?(conn) && conn.alive? }
|
|
7
|
-
end
|
|
8
|
-
|
|
9
|
-
# @param [String] node_name
|
|
10
|
-
#
|
|
11
|
-
# @return [Boolean]
|
|
12
|
-
def validate_node_name(node_name)
|
|
13
|
-
node_name.is_a?(String) && !node_name.empty?
|
|
14
|
-
end
|
|
15
|
-
|
|
16
|
-
# @raise [InvalidChefAPILocation]
|
|
17
|
-
#
|
|
18
|
-
# @see validate_node_name
|
|
19
|
-
def validate_node_name!(node_name)
|
|
20
|
-
unless validate_node_name(node_name)
|
|
21
|
-
raise InvalidChefAPILocation
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
true
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
# @param [String] client_key
|
|
28
|
-
#
|
|
29
|
-
# @return [Boolean]
|
|
30
|
-
def validate_client_key(client_key)
|
|
31
|
-
File.exists?(client_key)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# @raise [InvalidChefAPILocation]
|
|
35
|
-
#
|
|
36
|
-
# @see validate_client_key
|
|
37
|
-
def validate_client_key!(client_key)
|
|
38
|
-
unless validate_client_key(client_key)
|
|
39
|
-
raise InvalidChefAPILocation
|
|
40
|
-
end
|
|
41
|
-
|
|
42
|
-
true
|
|
43
|
-
end
|
|
44
|
-
|
|
45
|
-
# @param [String] uri
|
|
46
|
-
#
|
|
47
|
-
# @return [Boolean]
|
|
48
|
-
def validate_uri(uri)
|
|
49
|
-
uri =~ URI.regexp(['http', 'https'])
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
# @raise [InvalidChefAPILocation] if the given object is not a String containing a
|
|
53
|
-
# valid Chef API URI
|
|
54
|
-
#
|
|
55
|
-
# @see validate_uri
|
|
56
|
-
def validate_uri!(uri)
|
|
57
|
-
unless validate_uri(uri)
|
|
58
|
-
raise InvalidChefAPILocation, "'#{uri}' is not a valid Chef API URI."
|
|
59
|
-
end
|
|
60
|
-
|
|
61
|
-
true
|
|
62
|
-
end
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
include Location
|
|
66
|
-
|
|
67
|
-
set_location_key :chef_api
|
|
68
|
-
set_valid_options :node_name, :client_key
|
|
69
|
-
|
|
70
|
-
attr_reader :uri
|
|
71
|
-
attr_reader :node_name
|
|
72
|
-
attr_reader :client_key
|
|
73
|
-
|
|
74
|
-
# @param [#to_s] name
|
|
75
|
-
# @param [Solve::Constraint] version_constraint
|
|
76
|
-
# @param [Hash] options
|
|
77
|
-
#
|
|
78
|
-
# @option options [String, Symbol] :chef_api
|
|
79
|
-
# a URL to a Chef API. Alternatively the symbol :config can be provided
|
|
80
|
-
# which will instantiate this location with the values found in your
|
|
81
|
-
# Berkshelf configuration.
|
|
82
|
-
# @option options [String] :node_name (Berkshelf::Config.instance.chef.node_name)
|
|
83
|
-
# the name of the client to use to communicate with the Chef API.
|
|
84
|
-
# @option options [String] :client_key (Berkshelf::Config.instance.chef.client_key)
|
|
85
|
-
# the filepath to the authentication key for the client
|
|
86
|
-
# @option options [Boolean] :verify_ssl (Berkshelf::Config.instance.chef.ssl.verify)
|
|
87
|
-
#
|
|
88
|
-
# @raise [ClientKeyFileNotFound] if the value for :client_key does not contain a filepath
|
|
89
|
-
# pointing to a readable file containing a Chef client key.
|
|
90
|
-
#
|
|
91
|
-
# If the :chef_api option is given the symbol :config and your Berkshelf config does not
|
|
92
|
-
# have a value for chef.client_key which points to a readable file containing a Chef
|
|
93
|
-
# client key.
|
|
94
|
-
def initialize(name, version_constraint, options = {})
|
|
95
|
-
options = options.reverse_merge(
|
|
96
|
-
client_key: Berkshelf::Config.instance.chef.client_key,
|
|
97
|
-
node_name: Berkshelf::Config.instance.chef.node_name,
|
|
98
|
-
verify_ssl: Berkshelf::Config.instance.ssl.verify
|
|
99
|
-
)
|
|
100
|
-
|
|
101
|
-
@name = name
|
|
102
|
-
@version_constraint = version_constraint
|
|
103
|
-
@downloaded_status = false
|
|
104
|
-
|
|
105
|
-
if options[:chef_api] == :knife
|
|
106
|
-
Berkshelf.formatter.deprecation "specifying 'chef_api :knife' is deprecated. Please use 'chef_api :config'."
|
|
107
|
-
options[:chef_api] = :config
|
|
108
|
-
end
|
|
109
|
-
|
|
110
|
-
validate_options!(options)
|
|
111
|
-
|
|
112
|
-
if options[:chef_api] == :config
|
|
113
|
-
unless Berkshelf::Config.instance.chef.node_name.present? &&
|
|
114
|
-
Berkshelf::Config.instance.chef.client_key.present? &&
|
|
115
|
-
Berkshelf::Config.instance.chef.chef_server_url.present?
|
|
116
|
-
|
|
117
|
-
msg = "A Berkshelf configuration is required with a 'chef.client_key', 'chef.chef_server_Url',"
|
|
118
|
-
msg << " and 'chef.node_name' setting to install or upload cookbooks using 'chef_api :config'."
|
|
119
|
-
|
|
120
|
-
raise Berkshelf::ConfigurationError, msg
|
|
121
|
-
end
|
|
122
|
-
@node_name = Berkshelf::Config.instance.chef.node_name
|
|
123
|
-
@client_key = Berkshelf::Config.instance.chef.client_key
|
|
124
|
-
@uri = Berkshelf::Config.instance.chef.chef_server_url
|
|
125
|
-
else
|
|
126
|
-
@node_name = options[:node_name]
|
|
127
|
-
@client_key = options[:client_key]
|
|
128
|
-
@uri = options[:chef_api]
|
|
129
|
-
end
|
|
130
|
-
|
|
131
|
-
@conn = Ridley.new(
|
|
132
|
-
server_url: uri,
|
|
133
|
-
client_name: node_name,
|
|
134
|
-
client_key: client_key,
|
|
135
|
-
ssl: {
|
|
136
|
-
verify: options[:verify_ssl]
|
|
137
|
-
}
|
|
138
|
-
)
|
|
139
|
-
|
|
140
|
-
# Why do we use a class function for defining our finalizer?
|
|
141
|
-
# http://www.mikeperham.com/2010/02/24/the-trouble-with-ruby-finalizers/
|
|
142
|
-
ObjectSpace.define_finalizer(self, self.class.finalizer)
|
|
143
|
-
rescue Ridley::Errors::ClientKeyFileNotFoundOrInvalid => ex
|
|
144
|
-
raise ClientKeyFileNotFound, ex
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
# @param [#to_s] destination
|
|
148
|
-
#
|
|
149
|
-
# @return [Berkshelf::CachedCookbook]
|
|
150
|
-
def download(destination)
|
|
151
|
-
berks_path = File.join(destination, "#{name}-#{target_cookbook.version}")
|
|
152
|
-
|
|
153
|
-
temp_path = target_cookbook.download
|
|
154
|
-
FileUtils.mv(temp_path, berks_path)
|
|
155
|
-
|
|
156
|
-
cached = CachedCookbook.from_store_path(berks_path)
|
|
157
|
-
validate_cached(cached)
|
|
158
|
-
|
|
159
|
-
cached
|
|
160
|
-
end
|
|
161
|
-
|
|
162
|
-
# Returns a Ridley::CookbookResource representing the cookbook that should be downloaded
|
|
163
|
-
# for this location
|
|
164
|
-
#
|
|
165
|
-
# @return [Ridley::CookbookResource]
|
|
166
|
-
def target_cookbook
|
|
167
|
-
return @target_cookbook unless @target_cookbook.nil?
|
|
168
|
-
|
|
169
|
-
begin
|
|
170
|
-
@target_cookbook = if version_constraint
|
|
171
|
-
conn.cookbook.satisfy(name, version_constraint)
|
|
172
|
-
else
|
|
173
|
-
conn.cookbook.latest_version(name)
|
|
174
|
-
end
|
|
175
|
-
rescue Ridley::Errors::HTTPNotFound,
|
|
176
|
-
Ridley::Errors::ResourceNotFound
|
|
177
|
-
@target_cookbook = nil
|
|
178
|
-
end
|
|
179
|
-
|
|
180
|
-
if @target_cookbook.nil?
|
|
181
|
-
msg = "Cookbook '#{name}' found at #{self}"
|
|
182
|
-
msg << " that would satisfy constraint (#{version_constraint})" if version_constraint
|
|
183
|
-
raise CookbookNotFound, msg
|
|
184
|
-
end
|
|
185
|
-
|
|
186
|
-
@target_cookbook
|
|
187
|
-
end
|
|
188
|
-
|
|
189
|
-
def to_hash
|
|
190
|
-
super.merge(value: self.uri)
|
|
191
|
-
end
|
|
192
|
-
|
|
193
|
-
def to_s
|
|
194
|
-
"#{self.class.location_key}: '#{uri}'"
|
|
195
|
-
end
|
|
196
|
-
|
|
197
|
-
private
|
|
198
|
-
|
|
199
|
-
# @return [Ridley::Client]
|
|
200
|
-
attr_reader :conn
|
|
201
|
-
|
|
202
|
-
# Validates the options hash given to the constructor.
|
|
203
|
-
#
|
|
204
|
-
# @param [Hash] options
|
|
205
|
-
#
|
|
206
|
-
# @raise [InvalidChefAPILocation] if any of the options are missing or their values do not
|
|
207
|
-
# pass validation
|
|
208
|
-
def validate_options!(options)
|
|
209
|
-
if options[:chef_api] == :config
|
|
210
|
-
return true
|
|
211
|
-
end
|
|
212
|
-
|
|
213
|
-
missing_options = [:node_name, :client_key] - options.keys
|
|
214
|
-
|
|
215
|
-
unless missing_options.empty?
|
|
216
|
-
missing_options.collect! { |opt| "'#{opt}'" }
|
|
217
|
-
msg = "Source '#{name}' is a 'chef_api' location with a URL for it's value"
|
|
218
|
-
msg << " but is missing options: #{missing_options.join(', ')}."
|
|
219
|
-
|
|
220
|
-
raise Berkshelf::InvalidChefAPILocation, msg
|
|
221
|
-
end
|
|
222
|
-
|
|
223
|
-
self.class.validate_node_name!(options[:node_name])
|
|
224
|
-
self.class.validate_client_key!(options[:client_key])
|
|
225
|
-
self.class.validate_uri!(options[:chef_api])
|
|
226
|
-
end
|
|
227
|
-
end
|
|
228
|
-
end
|