berkshelf 0.4.0 → 0.5.0.rc1
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/berkshelf.gemspec +8 -3
- data/bin/berks +1 -1
- data/features/groups_install.feature +67 -0
- data/features/install.feature +1 -71
- data/features/json_formatter.feature +0 -17
- data/features/step_definitions/filesystem_steps.rb +1 -3
- data/features/update.feature +3 -6
- data/features/vendor_install.feature +20 -0
- data/generator_files/Vagrantfile.erb +25 -3
- data/lib/berkshelf.rb +27 -17
- data/lib/berkshelf/base_generator.rb +5 -0
- data/lib/berkshelf/berksfile.rb +82 -77
- data/lib/berkshelf/cli.rb +37 -26
- data/lib/berkshelf/cookbook_source.rb +14 -4
- data/lib/berkshelf/errors.rb +4 -1
- data/lib/berkshelf/formatters.rb +69 -5
- data/lib/berkshelf/formatters/human_readable.rb +26 -8
- data/lib/berkshelf/formatters/json.rb +51 -23
- data/lib/berkshelf/init_generator.rb +4 -4
- data/lib/berkshelf/location.rb +29 -6
- data/lib/berkshelf/locations/chef_api_location.rb +23 -5
- data/lib/berkshelf/locations/git_location.rb +13 -6
- data/lib/berkshelf/locations/path_location.rb +8 -4
- data/lib/berkshelf/locations/site_location.rb +9 -3
- data/lib/berkshelf/ui.rb +34 -0
- data/lib/berkshelf/uploader.rb +37 -103
- data/lib/berkshelf/vagrant.rb +65 -0
- data/lib/berkshelf/vagrant/action/clean.rb +24 -0
- data/lib/berkshelf/vagrant/action/install.rb +47 -0
- data/lib/berkshelf/vagrant/action/set_ui.rb +17 -0
- data/lib/berkshelf/vagrant/action/upload.rb +40 -0
- data/lib/berkshelf/vagrant/config.rb +70 -0
- data/lib/berkshelf/vagrant/middleware.rb +52 -0
- data/lib/berkshelf/version.rb +1 -1
- data/lib/thor/monkies.rb +3 -0
- data/lib/thor/monkies/hash_with_indifferent_access.rb +13 -0
- data/lib/vagrant_init.rb +2 -0
- data/spec/spec_helper.rb +5 -0
- data/spec/support/chef_api.rb +6 -1
- data/spec/unit/berkshelf/berksfile_spec.rb +93 -55
- data/spec/unit/berkshelf/formatters_spec.rb +99 -1
- data/spec/unit/berkshelf/init_generator_spec.rb +1 -1
- data/spec/unit/berkshelf/location_spec.rb +44 -7
- data/spec/unit/berkshelf/lockfile_spec.rb +2 -2
- data/spec/unit/berkshelf/uploader_spec.rb +2 -20
- data/spec/unit/berkshelf_spec.rb +2 -2
- metadata +100 -14
- data/features/without.feature +0 -26
- data/lib/berkshelf/core_ext/fileutils.rb +0 -90
- data/lib/berkshelf/core_ext/kernel.rb +0 -33
- data/spec/unit/berkshelf/core_ext/fileutils_spec.rb +0 -20
data/berkshelf.gemspec
CHANGED
@@ -16,10 +16,14 @@ Gem::Specification.new do |s|
|
|
16
16
|
s.version = Berkshelf::VERSION
|
17
17
|
s.required_ruby_version = ">= 1.9.1"
|
18
18
|
|
19
|
-
s.add_runtime_dependency '
|
20
|
-
s.add_runtime_dependency '
|
19
|
+
s.add_runtime_dependency 'ridley', '>= 0.0.3'
|
20
|
+
s.add_runtime_dependency 'solve', '~> 0.2.1'
|
21
|
+
s.add_runtime_dependency 'chef', '~> 10.12.0'
|
21
22
|
s.add_runtime_dependency 'minitar'
|
22
|
-
s.add_runtime_dependency 'thor',
|
23
|
+
s.add_runtime_dependency 'thor', '~> 0.16.0'
|
24
|
+
s.add_runtime_dependency 'vagrant', '~> 1.0.3'
|
25
|
+
s.add_runtime_dependency 'activesupport'
|
26
|
+
s.add_runtime_dependency 'multi_json'
|
23
27
|
|
24
28
|
s.add_development_dependency 'redcarpet'
|
25
29
|
s.add_development_dependency 'cucumber'
|
@@ -38,4 +42,5 @@ Gem::Specification.new do |s|
|
|
38
42
|
s.add_development_dependency 'guard-spork'
|
39
43
|
s.add_development_dependency 'guard-yard'
|
40
44
|
s.add_development_dependency 'coolline'
|
45
|
+
s.add_development_dependency 'rb-fsevent', '~> 0.9.1'
|
41
46
|
end
|
data/bin/berks
CHANGED
@@ -0,0 +1,67 @@
|
|
1
|
+
Feature: installing groups
|
2
|
+
As a user
|
3
|
+
I want to be able specify groups of cookbooks to include or exclude
|
4
|
+
So I don't install cookbooks that are part of a group that I do not want to install
|
5
|
+
|
6
|
+
Scenario: except groups
|
7
|
+
Given I write to "Berksfile" with:
|
8
|
+
"""
|
9
|
+
group :notme do
|
10
|
+
cookbook "nginx", "= 0.101.2"
|
11
|
+
end
|
12
|
+
|
13
|
+
cookbook "artifact", "= 0.10.0"
|
14
|
+
|
15
|
+
group :takeme do
|
16
|
+
cookbook "ntp", "= 1.1.8"
|
17
|
+
end
|
18
|
+
"""
|
19
|
+
When I run the install command with flags:
|
20
|
+
| --except notme |
|
21
|
+
Then the cookbook store should have the cookbooks:
|
22
|
+
| artifact | 0.10.0 |
|
23
|
+
| ntp | 1.1.8 |
|
24
|
+
And the cookbook store should not have the cookbooks:
|
25
|
+
| nginx | 0.101.2 |
|
26
|
+
|
27
|
+
Scenario: only groups
|
28
|
+
Given I write to "Berksfile" with:
|
29
|
+
"""
|
30
|
+
group :notme do
|
31
|
+
cookbook "nginx", "= 0.101.2"
|
32
|
+
end
|
33
|
+
|
34
|
+
cookbook "artifact", "= 0.10.0"
|
35
|
+
|
36
|
+
group :takeme do
|
37
|
+
cookbook "ntp", "= 1.1.8"
|
38
|
+
end
|
39
|
+
"""
|
40
|
+
When I run the install command with flags:
|
41
|
+
| --only takeme |
|
42
|
+
Then the cookbook store should have the cookbooks:
|
43
|
+
| ntp | 1.1.8 |
|
44
|
+
And the cookbook store should not have the cookbooks:
|
45
|
+
| nginx | 0.101.2 |
|
46
|
+
| artifact | 0.10.0 |
|
47
|
+
|
48
|
+
Scenario: attempting to provide an only and except option
|
49
|
+
Given I write to "Berksfile" with:
|
50
|
+
"""
|
51
|
+
group :notme do
|
52
|
+
cookbook "nginx", "= 0.101.2"
|
53
|
+
end
|
54
|
+
|
55
|
+
cookbook "artifact", "= 0.10.0"
|
56
|
+
|
57
|
+
group :takeme do
|
58
|
+
cookbook "ntp", "= 1.1.8"
|
59
|
+
end
|
60
|
+
"""
|
61
|
+
When I run the install command with flags:
|
62
|
+
| --only takeme --except notme |
|
63
|
+
Then the output should contain:
|
64
|
+
"""
|
65
|
+
Cannot specify both :except and :only
|
66
|
+
"""
|
67
|
+
And the CLI should exit with the status code for error "ArgumentError"
|
data/features/install.feature
CHANGED
@@ -65,21 +65,6 @@ Feature: install cookbooks from a Berksfile
|
|
65
65
|
"""
|
66
66
|
And the exit status should be 0
|
67
67
|
|
68
|
-
@no_run
|
69
|
-
Scenario: installing a Berksfile that contains a path location which contains a broken symlink
|
70
|
-
Given a Berksfile with path location sources to fixtures:
|
71
|
-
| example_cookbook_broken_link | example_cookbook_broken_link |
|
72
|
-
When I run the install command with flags:
|
73
|
-
| --shims |
|
74
|
-
Then the following directories should exist:
|
75
|
-
| cookbooks |
|
76
|
-
| cookbooks/example_cookbook |
|
77
|
-
And the output should contain:
|
78
|
-
"""
|
79
|
-
Shims written to:
|
80
|
-
"""
|
81
|
-
And the exit status should be 0
|
82
|
-
|
83
68
|
Scenario: installing a Berksfile that contains a Git location
|
84
69
|
Given I write to "Berksfile" with:
|
85
70
|
"""
|
@@ -146,61 +131,6 @@ Feature: install cookbooks from a Berksfile
|
|
146
131
|
"""
|
147
132
|
And the CLI should exit with the status code for error "CookbookNotFound"
|
148
133
|
|
149
|
-
Scenario: running install command with the --shims flag to create a directory of shims
|
150
|
-
Given I write to "Berksfile" with:
|
151
|
-
"""
|
152
|
-
cookbook "mysql", "1.2.4"
|
153
|
-
"""
|
154
|
-
When I run the install command with flags:
|
155
|
-
| --shims |
|
156
|
-
Then the following directories should exist:
|
157
|
-
| cookbooks |
|
158
|
-
| cookbooks/mysql |
|
159
|
-
And the output should contain:
|
160
|
-
"""
|
161
|
-
Shims written to:
|
162
|
-
"""
|
163
|
-
And the exit status should be 0
|
164
|
-
|
165
|
-
Scenario: running install command with the --shims flag and a relative path
|
166
|
-
Given I write to "Berksfile" with:
|
167
|
-
"""
|
168
|
-
cookbook "mysql", "1.2.4"
|
169
|
-
"""
|
170
|
-
When I run the install command with flags:
|
171
|
-
| --shims relativepath |
|
172
|
-
Then the following directories should exist:
|
173
|
-
| relativepath |
|
174
|
-
| relativepath/mysql |
|
175
|
-
And the output should contain:
|
176
|
-
"""
|
177
|
-
Shims written to:
|
178
|
-
"""
|
179
|
-
And the exit status should be 0
|
180
|
-
|
181
|
-
Scenario: running install with --shims when current project is a cookbook and the 'metadata' is specified
|
182
|
-
Given a cookbook named "sparkle_motion"
|
183
|
-
And the cookbook "sparkle_motion" has the file "Berksfile" with:
|
184
|
-
"""
|
185
|
-
metadata
|
186
|
-
"""
|
187
|
-
When I cd to "sparkle_motion"
|
188
|
-
And I run the install command with flags:
|
189
|
-
| --shims |
|
190
|
-
Then the following directories should exist:
|
191
|
-
| cookbooks |
|
192
|
-
| cookbooks/sparkle_motion |
|
193
|
-
And the output should contain:
|
194
|
-
"""
|
195
|
-
Shims written to:
|
196
|
-
"""
|
197
|
-
And the output should contain:
|
198
|
-
"""
|
199
|
-
Using sparkle_motion (0.0.0) at path:
|
200
|
-
"""
|
201
|
-
And the exit status should be 0
|
202
|
-
|
203
|
-
|
204
134
|
Scenario: installing a Berksfile that has a Git location source with an invalid Git URI
|
205
135
|
Given I write to "Berksfile" with:
|
206
136
|
"""
|
@@ -267,7 +197,7 @@ Feature: install cookbooks from a Berksfile
|
|
267
197
|
Scenario: with a cookbook definition containing a chef_api source location
|
268
198
|
Given I write to "Berksfile" with:
|
269
199
|
"""
|
270
|
-
cookbook "artifact", chef_api: :knife
|
200
|
+
cookbook "artifact", "= 0.10.2", chef_api: :knife
|
271
201
|
"""
|
272
202
|
And the Chef server has cookbooks:
|
273
203
|
| artifact | 0.10.2 |
|
@@ -43,20 +43,3 @@ Feature: --format json
|
|
43
43
|
And the JSON should have "cookbooks/0/uploaded_to"
|
44
44
|
And the Chef server should have the cookbooks:
|
45
45
|
| example_cookbook | 0.5.0 |
|
46
|
-
|
47
|
-
Scenario: JSON output when running install command with the --shims flag
|
48
|
-
Given I write to "Berksfile" with:
|
49
|
-
"""
|
50
|
-
cookbook "mysql", "1.2.4"
|
51
|
-
"""
|
52
|
-
When I run the install command with flags:
|
53
|
-
| --shims |
|
54
|
-
| --format json|
|
55
|
-
Then the following directories should exist:
|
56
|
-
| cookbooks |
|
57
|
-
| cookbooks/mysql |
|
58
|
-
And the output should be JSON
|
59
|
-
And the JSON should have "shims_dir"
|
60
|
-
|
61
|
-
|
62
|
-
|
@@ -107,11 +107,9 @@ Then /^I should have a new cookbook skeleton "(.*?)" with Vagrant support$/ do |
|
|
107
107
|
contains "gem 'vagrant'"
|
108
108
|
end
|
109
109
|
file "Vagrantfile" do
|
110
|
+
contains "require 'berkshelf/vagrant'"
|
110
111
|
contains "recipe[#{name}::default]"
|
111
112
|
end
|
112
|
-
directory "cookbooks" do
|
113
|
-
directory name
|
114
|
-
end
|
115
113
|
}
|
116
114
|
end
|
117
115
|
|
data/features/update.feature
CHANGED
@@ -6,17 +6,14 @@ Feature: update
|
|
6
6
|
Scenario: knife berkshelf update
|
7
7
|
Given I write to "Berksfile" with:
|
8
8
|
"""
|
9
|
-
cookbook "
|
9
|
+
cookbook "artifact", "0.10.0"
|
10
10
|
"""
|
11
11
|
Given I write to "Berksfile.lock" with:
|
12
12
|
"""
|
13
|
-
cookbook '
|
14
|
-
cookbook 'openssl', :locked_version => '0.0.1'
|
13
|
+
cookbook 'artifact', :locked_version => '0.0.1'
|
15
14
|
"""
|
16
15
|
When I run the update command
|
17
16
|
Then the file "Berksfile.lock" should contain exactly:
|
18
17
|
"""
|
19
|
-
cookbook '
|
20
|
-
cookbook 'openssl', :locked_version => '1.0.0'
|
21
|
-
cookbook 'build-essential', :locked_version => '1.1.0'
|
18
|
+
cookbook 'artifact', :locked_version => '0.10.0'
|
22
19
|
"""
|
@@ -0,0 +1,20 @@
|
|
1
|
+
Feature: install cookbooks to a given vendor 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: default
|
7
|
+
Given I write to "Berksfile" with:
|
8
|
+
"""
|
9
|
+
site :opscode
|
10
|
+
|
11
|
+
cookbook "artifact", "0.10.0"
|
12
|
+
"""
|
13
|
+
When I run the install command with flags:
|
14
|
+
| --path vendor/cookbooks |
|
15
|
+
Then the cookbook store should have the cookbooks:
|
16
|
+
| artifact | 0.10.0 |
|
17
|
+
Then the following directories should exist:
|
18
|
+
| vendor/cookbooks |
|
19
|
+
| vendor/cookbooks/artifact |
|
20
|
+
And the exit status should be 0
|
@@ -1,8 +1,32 @@
|
|
1
|
+
require 'berkshelf/vagrant'
|
2
|
+
|
1
3
|
Vagrant::Config.run do |config|
|
2
4
|
# All Vagrant configuration is done here. The most common configuration
|
3
5
|
# options are documented and commented below. For a complete reference,
|
4
6
|
# please see the online documentation at vagrantup.com.
|
5
7
|
|
8
|
+
# The path to the Berksfile to use with Vagrant Berkshelf
|
9
|
+
# config.berkshelf.berksfile_path = "./Berksfile"
|
10
|
+
|
11
|
+
# The path to the Knife config to use with Vagrant Berkshelf
|
12
|
+
# config.berkshelf.config_path = "~/.chef/knife.rb"
|
13
|
+
|
14
|
+
# A client name (node_name) to use with the Chef Client provisioner to upload
|
15
|
+
# cookbooks installed by Berkshelf.
|
16
|
+
# config.berkshelf.node_name = "reset"
|
17
|
+
|
18
|
+
# A path to a client key on disk to use with the Chef Client provisioner to
|
19
|
+
# upload cookbooks installed by Berkshelf.
|
20
|
+
# config.berkshelf.client_key = "~/.chef/reset.pem"
|
21
|
+
|
22
|
+
# An array of symbols representing groups of cookbook described in the Vagrantfile
|
23
|
+
# to skip installing and copying to Vagrant's shelf.
|
24
|
+
# config.berkshelf.only = []
|
25
|
+
|
26
|
+
# An array of symbols representing groups of cookbook described in the Vagrantfile
|
27
|
+
# to skip installing and copying to Vagrant's shelf.
|
28
|
+
# config.berkshelf.except = []
|
29
|
+
|
6
30
|
config.vm.host_name = "<%= cookbook_name %>-berkshelf"
|
7
31
|
|
8
32
|
# CentOS 6.3
|
@@ -35,9 +59,7 @@ Vagrant::Config.run do |config|
|
|
35
59
|
config.ssh.max_tries = 40
|
36
60
|
config.ssh.timeout = 120
|
37
61
|
|
38
|
-
config.vm.provision :chef_solo do |chef|
|
39
|
-
chef.cookbooks_path = ["cookbooks"]
|
40
|
-
|
62
|
+
config.vm.provision :chef_solo do |chef|
|
41
63
|
chef.json = {
|
42
64
|
:mysql => {
|
43
65
|
:server_root_password => 'rootpass',
|
data/lib/berkshelf.rb
CHANGED
@@ -1,14 +1,16 @@
|
|
1
1
|
require 'forwardable'
|
2
2
|
require 'uri'
|
3
3
|
require 'pathname'
|
4
|
+
require 'tmpdir'
|
4
5
|
require 'zlib'
|
5
6
|
require 'archive/tar/minitar'
|
6
7
|
require 'solve'
|
8
|
+
require 'ridley'
|
7
9
|
require 'chef/knife'
|
8
|
-
require 'chef/rest'
|
9
10
|
require 'chef/platform'
|
10
11
|
require 'chef/cookbook/metadata'
|
11
12
|
require 'chef/cookbook_version'
|
13
|
+
require 'active_support/core_ext'
|
12
14
|
|
13
15
|
require 'berkshelf/version'
|
14
16
|
require 'berkshelf/core_ext'
|
@@ -21,6 +23,7 @@ module Berkshelf
|
|
21
23
|
DEFAULT_STORE_PATH = File.expand_path("~/.berkshelf").freeze
|
22
24
|
DEFAULT_FILENAME = 'Berksfile'.freeze
|
23
25
|
|
26
|
+
autoload :UI, 'berkshelf/ui'
|
24
27
|
autoload :Cli, 'berkshelf/cli'
|
25
28
|
autoload :Git, 'berkshelf/git'
|
26
29
|
autoload :Berksfile, 'berkshelf/berksfile'
|
@@ -43,12 +46,14 @@ module Berkshelf
|
|
43
46
|
attr_writer :config_path
|
44
47
|
attr_writer :cookbook_store
|
45
48
|
|
49
|
+
# @return [Pathname]
|
46
50
|
def root
|
47
51
|
@root ||= Pathname.new(File.expand_path('../', File.dirname(__FILE__)))
|
48
52
|
end
|
49
53
|
|
54
|
+
# @return [Berkshelf::UI]
|
50
55
|
def ui
|
51
|
-
@ui ||=
|
56
|
+
@ui ||= Berkshelf::UI.new
|
52
57
|
end
|
53
58
|
|
54
59
|
# Returns the filepath to the location Berskhelf will use for
|
@@ -62,18 +67,30 @@ module Berkshelf
|
|
62
67
|
ENV["BERKSHELF_PATH"] || DEFAULT_STORE_PATH
|
63
68
|
end
|
64
69
|
|
70
|
+
# @return [String]
|
65
71
|
def tmp_dir
|
66
72
|
File.join(berkshelf_path, "tmp")
|
67
73
|
end
|
68
74
|
|
75
|
+
# Creates a temporary directory within the Berkshelf path
|
76
|
+
#
|
77
|
+
# @return [String]
|
78
|
+
# path to the created temporary directory
|
79
|
+
def mktmpdir
|
80
|
+
FileUtils.mkdir_p(File.join(berkshelf_path, "tmp"))
|
81
|
+
Dir.mktmpdir(nil, File.join(berkshelf_path, "tmp"))
|
82
|
+
end
|
83
|
+
|
69
84
|
def cookbooks_dir
|
70
85
|
File.join(berkshelf_path, "cookbooks")
|
71
86
|
end
|
72
87
|
|
88
|
+
# @return [Berkshelf::CookbookStore]
|
73
89
|
def cookbook_store
|
74
90
|
@cookbook_store ||= CookbookStore.new(cookbooks_dir)
|
75
91
|
end
|
76
92
|
|
93
|
+
# @return [String]
|
77
94
|
def config_path
|
78
95
|
@config_path ||= DEFAULT_CONFIG
|
79
96
|
end
|
@@ -108,26 +125,19 @@ module Berkshelf
|
|
108
125
|
#
|
109
126
|
# @return [~Formatter]
|
110
127
|
def formatter
|
111
|
-
@formatter ||=
|
128
|
+
@formatter ||= Formatters::HumanReadable.new
|
112
129
|
end
|
113
130
|
|
114
|
-
# Specify
|
131
|
+
# Specify the format for output
|
115
132
|
#
|
116
|
-
# @param [
|
117
|
-
#
|
133
|
+
# @param [#to_sym] format_id
|
134
|
+
# the ID of the registered formatter to use
|
118
135
|
#
|
119
|
-
# @example Berkshelf.set_format
|
120
|
-
def set_format(format)
|
121
|
-
@_format = format
|
122
|
-
@formatter = nil
|
123
|
-
end
|
124
|
-
|
125
|
-
# Access the formatters map that links string symbols to Formatter
|
126
|
-
# implementations
|
136
|
+
# @example Berkshelf.set_format :json
|
127
137
|
#
|
128
|
-
# @return [
|
129
|
-
def
|
130
|
-
@
|
138
|
+
# @return [~Formatter]
|
139
|
+
def set_format(format_id)
|
140
|
+
@formatter = Formatters[format_id].new
|
131
141
|
end
|
132
142
|
|
133
143
|
private
|
data/lib/berkshelf/berksfile.rb
CHANGED
@@ -16,19 +16,29 @@ module Berkshelf
|
|
16
16
|
raise BerksfileNotFound, "No Berksfile or Berksfile.lock found at: #{file}"
|
17
17
|
end
|
18
18
|
|
19
|
-
#
|
20
|
-
#
|
21
|
-
# @param [Array, Symbol] excluded
|
22
|
-
# an array of symbols or a symbol representing the group or group(s)
|
23
|
-
# to exclude
|
19
|
+
# Copy all cached_cookbooks to the given directory. Each cookbook will be contained in
|
20
|
+
# a directory named after the name of the cookbook.
|
24
21
|
#
|
25
|
-
# @
|
26
|
-
# an array of
|
27
|
-
|
28
|
-
|
29
|
-
|
22
|
+
# @param [Array<CachedCookbook>] cookbooks
|
23
|
+
# an array of CachedCookbooks to be copied to a vendor directory
|
24
|
+
# @param [String] path
|
25
|
+
# filepath to vendor cookbooks to
|
26
|
+
#
|
27
|
+
# @return [String]
|
28
|
+
# expanded filepath to the vendor directory
|
29
|
+
def vendor(cookbooks, path)
|
30
|
+
path = File.expand_path(path)
|
31
|
+
FileUtils.mkdir_p(path)
|
32
|
+
|
33
|
+
scratch = Berkshelf.mktmpdir
|
34
|
+
cookbooks.each do |cb|
|
35
|
+
FileUtils.cp_r(cb.path, File.join(scratch, cb.cookbook_name))
|
36
|
+
end
|
30
37
|
|
31
|
-
|
38
|
+
FileUtils.remove_dir(path, force: true)
|
39
|
+
File.rename(scratch, path)
|
40
|
+
|
41
|
+
path
|
32
42
|
end
|
33
43
|
end
|
34
44
|
|
@@ -41,6 +51,9 @@ module Berkshelf
|
|
41
51
|
# @return [Berkshelf::Downloader]
|
42
52
|
attr_reader :downloader
|
43
53
|
|
54
|
+
# @return [Array<Berkshelf::CachedCookbook>]
|
55
|
+
attr_reader :cached_cookbooks
|
56
|
+
|
44
57
|
def_delegator :downloader, :add_location
|
45
58
|
def_delegator :downloader, :locations
|
46
59
|
|
@@ -48,6 +61,7 @@ module Berkshelf
|
|
48
61
|
@filepath = path
|
49
62
|
@sources = Hash.new
|
50
63
|
@downloader = Downloader.new(Berkshelf.cookbook_store)
|
64
|
+
@cached_cookbooks = nil
|
51
65
|
end
|
52
66
|
|
53
67
|
# Add a cookbook source to the Berksfile to be retrieved and have it's dependencies recurisvely retrieved
|
@@ -130,7 +144,6 @@ module Berkshelf
|
|
130
144
|
add_source(name, constraint, options)
|
131
145
|
end
|
132
146
|
|
133
|
-
|
134
147
|
def group(*args)
|
135
148
|
@@active_group = args
|
136
149
|
yield
|
@@ -245,16 +258,29 @@ module Berkshelf
|
|
245
258
|
@sources.has_key?(source.to_s)
|
246
259
|
end
|
247
260
|
|
248
|
-
# @option options [Symbol, Array] :
|
261
|
+
# @option options [Symbol, Array] :except
|
249
262
|
# Group(s) to exclude to exclude from the returned Array of sources
|
250
263
|
# group to not be installed
|
264
|
+
# @option options [Symbol, Array] :only
|
265
|
+
# Group(s) to include which will cause any sources marked as a member of the
|
266
|
+
# group to be installed and all others to be ignored
|
267
|
+
#
|
268
|
+
# @raise [Berkshelf::ArgumentError] if a value for both :except and :only is provided
|
251
269
|
#
|
252
270
|
# @return [Array<Berkshelf::CookbookSource>]
|
253
271
|
def sources(options = {})
|
254
272
|
l_sources = @sources.collect { |name, source| source }.flatten
|
255
273
|
|
256
|
-
|
257
|
-
|
274
|
+
except = Array(options.fetch(:except, nil)).collect(&:to_sym)
|
275
|
+
only = Array(options.fetch(:only, nil)).collect(&:to_sym)
|
276
|
+
|
277
|
+
case
|
278
|
+
when !except.empty? && !only.empty?
|
279
|
+
raise Berkshelf::ArgumentError, "Cannot specify both :except and :only"
|
280
|
+
when !except.empty?
|
281
|
+
l_sources.select { |source| (except & source.groups).empty? }
|
282
|
+
when !only.empty?
|
283
|
+
l_sources.select { |source| !(only & source.groups).empty? }
|
258
284
|
else
|
259
285
|
l_sources
|
260
286
|
end
|
@@ -294,101 +320,80 @@ module Berkshelf
|
|
294
320
|
end
|
295
321
|
alias_method :get_source, :[]
|
296
322
|
|
297
|
-
# @option options [Symbol, Array] :
|
323
|
+
# @option options [Symbol, Array] :except
|
298
324
|
# Group(s) to exclude which will cause any sources marked as a member of the
|
299
325
|
# group to not be installed
|
300
|
-
# @option options [
|
301
|
-
#
|
302
|
-
#
|
326
|
+
# @option options [Symbol, Array] :only
|
327
|
+
# Group(s) to include which will cause any sources marked as a member of the
|
328
|
+
# group to be installed and all others to be ignored
|
329
|
+
# @option options [String] :path
|
330
|
+
# a path to "vendor" the cached_cookbooks resolved by the resolver. Vendoring
|
331
|
+
# is a technique for packaging all cookbooks resolved by a Berksfile.
|
332
|
+
#
|
333
|
+
# @return [Array<Berkshelf::CachedCookbook>]
|
303
334
|
def install(options = {})
|
304
335
|
resolver = Resolver.new(
|
305
336
|
self.downloader,
|
306
|
-
sources: sources(
|
337
|
+
sources: sources(options)
|
307
338
|
)
|
308
339
|
|
309
|
-
|
310
|
-
if options[:shims]
|
311
|
-
write_shims(options[:shims], solution)
|
312
|
-
Berkshelf.formatter.shims_written options[:shims]
|
313
|
-
end
|
340
|
+
@cached_cookbooks = resolver.resolve
|
314
341
|
write_lockfile(resolver.sources) unless lockfile_present?
|
342
|
+
|
343
|
+
if options[:path]
|
344
|
+
self.class.vendor(@cached_cookbooks, options[:path])
|
345
|
+
end
|
346
|
+
|
347
|
+
self.cached_cookbooks
|
315
348
|
end
|
316
349
|
|
317
|
-
# @
|
318
|
-
#
|
319
|
-
#
|
320
|
-
#
|
321
|
-
#
|
322
|
-
# @option options [Symbol, Array] :without
|
323
|
-
# Group(s) to exclude which will cause any sources marked as a member of the
|
324
|
-
# group to not be installed
|
325
|
-
# @option options [String] :node_name
|
326
|
-
# the name of the client used to sign REST requests to the Chef Server
|
350
|
+
# @option options [String] :server_url
|
351
|
+
# URL to the Chef API
|
352
|
+
# @option options [String] :client_name
|
353
|
+
# name of the client used to authenticate with the Chef API
|
327
354
|
# @option options [String] :client_key
|
328
|
-
#
|
329
|
-
#
|
355
|
+
# filepath to the client's private key used to authenticate with
|
356
|
+
# the Chef API
|
357
|
+
# @option options [String] :organization
|
358
|
+
# the Organization to connect to. This is only used if you are connecting to
|
359
|
+
# private Chef or hosted Chef
|
330
360
|
# @option options [Boolean] :force Upload the Cookbook even if the version
|
331
361
|
# already exists and is frozen on the target Chef Server
|
332
362
|
# @option options [Boolean] :freeze Freeze the uploaded Cookbook on the Chef
|
333
363
|
# Server so that it cannot be overwritten
|
334
|
-
|
335
|
-
|
364
|
+
# @option options [Symbol, Array] :except
|
365
|
+
# Group(s) to exclude which will cause any sources marked as a member of the
|
366
|
+
# group to not be installed
|
367
|
+
# @option options [Symbol, Array] :only
|
368
|
+
# Group(s) to include which will cause any sources marked as a member of the
|
369
|
+
# group to be installed and all others to be ignored
|
370
|
+
def upload(options = {})
|
371
|
+
uploader = Uploader.new(options)
|
336
372
|
solution = resolve(options)
|
337
373
|
|
338
374
|
solution.each do |cb|
|
339
|
-
Berkshelf.formatter.upload cb.cookbook_name, cb.version,
|
375
|
+
Berkshelf.formatter.upload cb.cookbook_name, cb.version, options[:server_url]
|
340
376
|
uploader.upload(cb, options)
|
341
377
|
end
|
342
378
|
end
|
343
379
|
|
344
380
|
# Finds a solution for the Berksfile and returns an array of CachedCookbooks.
|
345
381
|
#
|
346
|
-
# @option options [Symbol, Array] :
|
382
|
+
# @option options [Symbol, Array] :except
|
347
383
|
# Group(s) to exclude which will cause any sources marked as a member of the
|
348
|
-
# group to not be
|
384
|
+
# group to not be installed
|
385
|
+
# @option options [Symbol, Array] :only
|
386
|
+
# Group(s) to include which will cause any sources marked as a member of the
|
387
|
+
# group to be installed and all others to be ignored
|
349
388
|
#
|
350
389
|
# @return [Array<Berkshelf::CachedCookbooks]
|
351
390
|
def resolve(options = {})
|
352
391
|
Resolver.new(
|
353
392
|
self.downloader,
|
354
|
-
sources: sources(
|
393
|
+
sources: sources(options)
|
355
394
|
).resolve
|
356
395
|
end
|
357
396
|
|
358
|
-
# Write a collection of hard links to the given path representing the given
|
359
|
-
# CachedCookbooks. Useful for getting Cookbooks in a single location for
|
360
|
-
# consumption by Vagrant, or another tool that expect this structure.
|
361
|
-
#
|
362
|
-
# @example
|
363
|
-
# Given the path: '/Users/reset/code/pvpnet/cookbooks'
|
364
|
-
# And a CachedCookbook: 'nginx' verison '0.100.5' at '/Users/reset/.berkshelf/nginx-0.100.5'
|
365
|
-
#
|
366
|
-
# A hardlink will be created at: '/Users/reset/code/pvpnet/cookbooks/nginx'
|
367
|
-
#
|
368
|
-
# @param [Pathname, String] path
|
369
|
-
# @param [Array<Berkshelf::CachedCookbook>] cached_cookbooks
|
370
|
-
def write_shims(path, cached_cookbooks)
|
371
|
-
path = File.expand_path(path)
|
372
|
-
actual_path = nil
|
373
|
-
|
374
|
-
if descendant_directory?(path, Dir.pwd)
|
375
|
-
actual_path = path
|
376
|
-
FileUtils.rm_rf(actual_path)
|
377
|
-
path = File.join(Berkshelf.tmp_dir, "shims")
|
378
|
-
end
|
379
|
-
|
380
|
-
FileUtils.mkdir_p(path)
|
381
|
-
cached_cookbooks.each do |cached_cookbook|
|
382
|
-
destination = File.expand_path(File.join(path, cached_cookbook.cookbook_name))
|
383
|
-
FileUtils.rm_rf(destination)
|
384
|
-
FileUtils.ln_r(cached_cookbook.path, destination, force: true)
|
385
|
-
end
|
386
|
-
|
387
|
-
if actual_path
|
388
|
-
FileUtils.mv(path, actual_path)
|
389
|
-
end
|
390
|
-
end
|
391
|
-
|
392
397
|
# Reload this instance of Berksfile with the given content. The content
|
393
398
|
# is a string that may contain terms from the included DSL.
|
394
399
|
#
|