berkshelf 0.6.0.beta4 → 1.0.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 +1 -1
- data/features/config.feature +10 -10
- data/features/configure_command.feature +60 -0
- data/features/install.feature +6 -6
- data/features/step_definitions/cli_steps.rb +2 -2
- data/features/step_definitions/configure_cli_steps.rb +6 -0
- data/features/step_definitions/filesystem_steps.rb +6 -10
- data/features/support/env.rb +1 -0
- data/generator_files/Vagrantfile.erb +18 -38
- data/lib/berkshelf.rb +0 -19
- data/lib/berkshelf/cli.rb +82 -17
- data/lib/berkshelf/config.rb +77 -28
- data/lib/berkshelf/errors.rb +5 -2
- data/lib/berkshelf/locations/chef_api_location.rb +16 -11
- data/lib/berkshelf/vagrant/action/install.rb +4 -8
- data/lib/berkshelf/vagrant/action/upload.rb +5 -11
- data/lib/berkshelf/vagrant/config.rb +4 -28
- data/lib/berkshelf/version.rb +1 -1
- data/spec/unit/berkshelf/config_spec.rb +28 -68
- data/spec/unit/berkshelf/locations/chef_api_location_spec.rb +0 -6
- data/spec/unit/berkshelf_spec.rb +0 -20
- metadata +7 -10
- data/features/config_command.feature +0 -10
- data/generator_files/config.json +0 -22
- data/lib/berkshelf/config_generator.rb +0 -8
- data/lib/berkshelf/config_validator.rb +0 -78
- data/spec/unit/berkshelf/config_validator_spec.rb +0 -68
data/lib/berkshelf/config.rb
CHANGED
@@ -1,31 +1,46 @@
|
|
1
|
+
require 'chozo/config'
|
2
|
+
|
1
3
|
module Berkshelf
|
2
4
|
# @author Justin Campbell <justin@justincampbell.me>
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
include ActiveModel::Validations
|
7
|
-
validates_with ConfigValidator
|
5
|
+
# @author Jamie Winsor <jamie@vialstudios.com>
|
6
|
+
class Config < Chozo::Config::JSON
|
7
|
+
FILENAME = "config.json".freeze
|
8
8
|
|
9
9
|
class << self
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
10
|
+
attr_writer :path
|
11
|
+
|
12
|
+
# @return [String]
|
13
|
+
def path
|
14
|
+
File.join(Berkshelf.berkshelf_path, FILENAME)
|
14
15
|
end
|
15
16
|
|
16
|
-
# @
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
hash = JSON.parse(json).to_hash
|
17
|
+
# @return [String]
|
18
|
+
def chef_config_path
|
19
|
+
@chef_config_path ||= File.expand_path(ENV["BERKSHELF_CHEF_CONFIG"] || "~/.chef/knife.rb")
|
20
|
+
end
|
21
21
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
22
|
+
# @param [String] value
|
23
|
+
def chef_config_path=(value)
|
24
|
+
@chef_config = nil
|
25
|
+
@chef_config_path = value
|
26
|
+
end
|
27
|
+
|
28
|
+
# @return [Chef::Config]
|
29
|
+
def chef_config
|
30
|
+
@chef_config ||= begin
|
31
|
+
Chef::Config.from_file(File.expand_path(chef_config_path))
|
32
|
+
Chef::Config
|
33
|
+
rescue
|
34
|
+
Chef::Config
|
26
35
|
end
|
27
36
|
end
|
28
37
|
|
38
|
+
# @return [String, nil]
|
39
|
+
# the contents of the file
|
40
|
+
def file
|
41
|
+
File.read(path) if File.exists?(path)
|
42
|
+
end
|
43
|
+
|
29
44
|
# @return [Config]
|
30
45
|
def instance
|
31
46
|
@instance ||= if file
|
@@ -34,18 +49,52 @@ module Berkshelf
|
|
34
49
|
new
|
35
50
|
end
|
36
51
|
end
|
37
|
-
|
38
|
-
# @return [String]
|
39
|
-
def path
|
40
|
-
File.expand_path DEFAULT_PATH
|
41
|
-
end
|
42
52
|
end
|
43
53
|
|
44
|
-
# @param [String
|
45
|
-
#
|
46
|
-
#
|
47
|
-
def
|
48
|
-
super
|
54
|
+
# @param [String] path
|
55
|
+
# @param [Hash] options
|
56
|
+
# @see {Chozo::Config::JSON}
|
57
|
+
def initialize(path = self.class.path, options = {})
|
58
|
+
super(path, options)
|
49
59
|
end
|
60
|
+
|
61
|
+
attribute 'chef.chef_server_url',
|
62
|
+
type: String,
|
63
|
+
default: chef_config[:chef_server_url]
|
64
|
+
attribute 'chef.validation_client_name',
|
65
|
+
type: String,
|
66
|
+
default: chef_config[:validation_client_name]
|
67
|
+
attribute 'chef.validation_key_path',
|
68
|
+
type: String,
|
69
|
+
default: chef_config[:validation_key]
|
70
|
+
attribute 'chef.client_key',
|
71
|
+
type: String,
|
72
|
+
default: chef_config[:client_key]
|
73
|
+
attribute 'chef.node_name',
|
74
|
+
type: String,
|
75
|
+
default: chef_config[:node_name]
|
76
|
+
attribute 'vagrant.vm.box',
|
77
|
+
type: String,
|
78
|
+
default: 'Berkshelf-CentOS-6.3-x86_64-minimal',
|
79
|
+
required: true
|
80
|
+
attribute 'vagrant.vm.box_url',
|
81
|
+
type: String,
|
82
|
+
default: 'https://dl.dropbox.com/u/31081437/Berkshelf-CentOS-6.3-x86_64-minimal.box',
|
83
|
+
required: true
|
84
|
+
attribute 'vagrant.vm.forward_port',
|
85
|
+
type: Hash,
|
86
|
+
default: Hash.new
|
87
|
+
attribute 'vagrant.vm.network.bridged',
|
88
|
+
type: Boolean,
|
89
|
+
default: true
|
90
|
+
attribute 'vagrant.vm.network.hostonly',
|
91
|
+
type: String,
|
92
|
+
default: '33.33.33.10'
|
93
|
+
attribute 'vagrant.vm.provision',
|
94
|
+
type: String,
|
95
|
+
default: 'chef_solo'
|
96
|
+
attribute 'ssl.verify',
|
97
|
+
type: Boolean,
|
98
|
+
default: true
|
50
99
|
end
|
51
100
|
end
|
data/lib/berkshelf/errors.rb
CHANGED
@@ -41,7 +41,7 @@ module Berkshelf
|
|
41
41
|
class NoSolution < BerkshelfError; status_code(106); end
|
42
42
|
class CookbookSyntaxError < BerkshelfError; status_code(107); end
|
43
43
|
class UploadFailure < BerkshelfError; status_code(108); end
|
44
|
-
class
|
44
|
+
class BerksConfigNotFound < BerkshelfError; status_code(109); end
|
45
45
|
|
46
46
|
class InvalidGitURI < BerkshelfError
|
47
47
|
status_code(110)
|
@@ -91,7 +91,7 @@ module Berkshelf
|
|
91
91
|
def to_s
|
92
92
|
strings = ["Invalid configuration:"]
|
93
93
|
|
94
|
-
@errors.
|
94
|
+
@errors.each do |key, errors|
|
95
95
|
errors.each do |error|
|
96
96
|
strings << " #{key} #{error}"
|
97
97
|
end
|
@@ -100,4 +100,7 @@ module Berkshelf
|
|
100
100
|
strings.join "\n"
|
101
101
|
end
|
102
102
|
end
|
103
|
+
|
104
|
+
class ConfigExists < BerkshelfError; status_code(116); end
|
105
|
+
class ConfigurationError < BerkshelfError; status_code(117); end
|
103
106
|
end
|
@@ -86,9 +86,9 @@ module Berkshelf
|
|
86
86
|
# @param [Hash] options
|
87
87
|
#
|
88
88
|
# @option options [String, Symbol] :chef_api
|
89
|
-
# a URL to a Chef API. Alternatively the symbol :
|
89
|
+
# a URL to a Chef API. Alternatively the symbol :config can be provided
|
90
90
|
# which will instantiate this location with the values found in your
|
91
|
-
#
|
91
|
+
# Berkshelf configuration.
|
92
92
|
# @option options [String] :node_name
|
93
93
|
# the name of the client to use to communicate with the Chef API.
|
94
94
|
# Default: Chef::Config[:node_name]
|
@@ -100,17 +100,22 @@ module Berkshelf
|
|
100
100
|
@version_constraint = version_constraint
|
101
101
|
@downloaded_status = false
|
102
102
|
|
103
|
+
if options[:chef_api] == :knife
|
104
|
+
Berkshelf.formatter.deprecation "specifying 'chef_api :knife' is deprecated. Please use 'chef_api :config'."
|
105
|
+
options[:chef_api] = :config
|
106
|
+
end
|
107
|
+
|
103
108
|
validate_options!(options)
|
104
109
|
|
105
|
-
if options[:chef_api] == :
|
106
|
-
|
107
|
-
Berkshelf.
|
108
|
-
|
109
|
-
raise
|
110
|
+
if options[:chef_api] == :config
|
111
|
+
unless Berkshelf::Config.instance.chef.node_name.present? &&
|
112
|
+
Berkshelf::Config.instance.chef.client_key.present? &&
|
113
|
+
Berkshelf::Config.instance.chef.chef_server_url.present?
|
114
|
+
raise ConfigurationError, "A Berkshelf configuration is required with a 'chef.client_key', 'chef.chef_server_Url', and 'chef.node_name' setting to install or upload cookbooks using 'chef_api :config'."
|
110
115
|
end
|
111
|
-
@node_name =
|
112
|
-
@client_key =
|
113
|
-
@uri =
|
116
|
+
@node_name = Berkshelf::Config.instance.chef.node_name
|
117
|
+
@client_key = Berkshelf::Config.instance.chef.client_key
|
118
|
+
@uri = Berkshelf::Config.instance.chef.chef_server_url
|
114
119
|
else
|
115
120
|
@node_name = options[:node_name]
|
116
121
|
@client_key = options[:client_key]
|
@@ -250,7 +255,7 @@ module Berkshelf
|
|
250
255
|
# @raise [InvalidChefAPILocation] if any of the options are missing or their values do not
|
251
256
|
# pass validation
|
252
257
|
def validate_options!(options)
|
253
|
-
if options[:chef_api] == :
|
258
|
+
if options[:chef_api] == :config
|
254
259
|
return true
|
255
260
|
end
|
256
261
|
|
@@ -4,17 +4,13 @@ module Berkshelf
|
|
4
4
|
# @author Jamie Winsor <jamie@vialstudios.com>
|
5
5
|
# @author Andrew Garson <andrew.garson@gmail.com>
|
6
6
|
class Install
|
7
|
-
attr_reader :config
|
8
7
|
attr_reader :shelf
|
9
8
|
attr_reader :berksfile
|
10
9
|
|
11
10
|
def initialize(app, env)
|
12
|
-
@app
|
13
|
-
@shelf
|
14
|
-
@
|
15
|
-
Berkshelf.config_path = @config.config_path
|
16
|
-
Berkshelf.load_config
|
17
|
-
@berksfile = Berksfile.from_file(@config.berksfile_path)
|
11
|
+
@app = app
|
12
|
+
@shelf = Berkshelf::Vagrant.shelf_for(env)
|
13
|
+
@berksfile = Berksfile.from_file(env[:vm].config.berkshelf.berksfile_path)
|
18
14
|
end
|
19
15
|
|
20
16
|
def call(env)
|
@@ -32,7 +28,7 @@ module Berkshelf
|
|
32
28
|
Berkshelf.formatter.msg "installing cookbooks..."
|
33
29
|
opts = {
|
34
30
|
path: self.shelf
|
35
|
-
}.merge(
|
31
|
+
}.merge(env[:vm].config.berkshelf.to_hash).symbolize_keys!
|
36
32
|
berksfile.install(opts)
|
37
33
|
end
|
38
34
|
|
@@ -4,16 +4,10 @@ module Berkshelf
|
|
4
4
|
# @author Jamie Winsor <jamie@vialstudios.com>
|
5
5
|
class Upload
|
6
6
|
attr_reader :berksfile
|
7
|
-
attr_reader :node_name
|
8
|
-
attr_reader :client_key
|
9
|
-
attr_reader :ssl_verify
|
10
7
|
|
11
8
|
def initialize(app, env)
|
12
|
-
@app
|
13
|
-
@
|
14
|
-
@client_key = env[:vm].config.berkshelf.client_key
|
15
|
-
@ssl_verify = env[:vm].config.berkshelf.ssl_verify
|
16
|
-
@berksfile = Berksfile.from_file(env[:vm].config.berkshelf.berksfile_path)
|
9
|
+
@app = app
|
10
|
+
@berksfile = Berksfile.from_file(env[:vm].config.berkshelf.berksfile_path)
|
17
11
|
end
|
18
12
|
|
19
13
|
def call(env)
|
@@ -31,10 +25,10 @@ module Berkshelf
|
|
31
25
|
Berkshelf.formatter.msg "uploading cookbooks to '#{provisioner.config.chef_server_url}'"
|
32
26
|
berksfile.upload(
|
33
27
|
server_url: provisioner.config.chef_server_url,
|
34
|
-
client_name:
|
35
|
-
client_key:
|
28
|
+
client_name: Berkshelf::Config.instance.chef.node_name,
|
29
|
+
client_key: Berkshelf::Config.instance.chef.client_key,
|
36
30
|
ssl: {
|
37
|
-
verify:
|
31
|
+
verify: Berkshelf::Config.instance.ssl.verify
|
38
32
|
}
|
39
33
|
)
|
40
34
|
end
|
@@ -3,24 +3,10 @@ module Berkshelf
|
|
3
3
|
# @author Jamie Winsor <jamie@vialstudios.com>
|
4
4
|
# @author Andrew Garson <andrew.garson@gmail.com>
|
5
5
|
class Config < ::Vagrant::Config::Base
|
6
|
-
# @return [String]
|
7
|
-
# path to a knife configuration file
|
8
|
-
attr_reader :config_path
|
9
|
-
|
10
6
|
# @return [String]
|
11
7
|
# path to the Berksfile to use with Vagrant
|
12
8
|
attr_reader :berksfile_path
|
13
9
|
|
14
|
-
# @return [String]
|
15
|
-
# A path to a client key on disk to use with the Chef Client provisioner to
|
16
|
-
# upload cookbooks installed by Berkshelf.
|
17
|
-
attr_reader :client_key
|
18
|
-
|
19
|
-
# @return [String]
|
20
|
-
# A client name (node_name) to use with the Chef Client provisioner to upload
|
21
|
-
# cookbooks installed by Berkshelf.
|
22
|
-
attr_accessor :node_name
|
23
|
-
|
24
10
|
# @return [Array<Symbol>]
|
25
11
|
# only cookbooks in these groups will be installed and copied to
|
26
12
|
# Vagrant's shelf
|
@@ -30,16 +16,11 @@ module Berkshelf
|
|
30
16
|
# cookbooks in all other groups except for these will be installed
|
31
17
|
# and copied to Vagrant's shelf
|
32
18
|
attr_accessor :except
|
33
|
-
attr_accessor :ssl_verify
|
34
19
|
|
35
20
|
def initialize
|
36
21
|
@berksfile_path = File.join(Dir.pwd, Berkshelf::DEFAULT_FILENAME)
|
37
|
-
@config_path = Berkshelf::DEFAULT_CONFIG
|
38
|
-
@node_name = nil
|
39
|
-
@client_key = nil
|
40
22
|
@except = Array.new
|
41
23
|
@only = Array.new
|
42
|
-
@ssl_verify = true
|
43
24
|
end
|
44
25
|
|
45
26
|
# @param [String] value
|
@@ -47,11 +28,6 @@ module Berkshelf
|
|
47
28
|
@berksfile_path = File.expand_path(value)
|
48
29
|
end
|
49
30
|
|
50
|
-
# @param [String] value
|
51
|
-
def config_path=(value)
|
52
|
-
@config_path = File.expand_path(value)
|
53
|
-
end
|
54
|
-
|
55
31
|
# @param [String] value
|
56
32
|
def client_key=(value)
|
57
33
|
@client_key = File.expand_path(value)
|
@@ -63,12 +39,12 @@ module Berkshelf
|
|
63
39
|
end
|
64
40
|
|
65
41
|
if Berkshelf::Vagrant.chef_client?(env.config.global)
|
66
|
-
if node_name.nil?
|
67
|
-
errors.add("A
|
42
|
+
if Berkshelf::Config.instance.chef.node_name.nil?
|
43
|
+
errors.add("A configuration must be set for chef.node_name when using the chef_client provisioner. Run 'berks configure' or edit your configuration.")
|
68
44
|
end
|
69
45
|
|
70
|
-
if client_key.nil?
|
71
|
-
errors.add("A
|
46
|
+
if Berkshelf::Config.instance.chef.client_key.nil?
|
47
|
+
errors.add("A configuration must be set for chef.client_key when using the chef_client provisioner. Run 'berks configure' or edit your configuration.")
|
72
48
|
end
|
73
49
|
end
|
74
50
|
end
|
data/lib/berkshelf/version.rb
CHANGED
@@ -1,91 +1,51 @@
|
|
1
1
|
require 'spec_helper'
|
2
2
|
|
3
3
|
describe Berkshelf::Config do
|
4
|
-
subject { config }
|
5
|
-
|
6
|
-
let(:config) { klass.new }
|
7
4
|
let(:klass) { described_class }
|
8
5
|
|
9
|
-
|
10
|
-
|
11
|
-
its(:present?) { should be_false }
|
12
|
-
|
13
|
-
it "set and gets hash keys" do
|
14
|
-
config[:a] = 1
|
15
|
-
config[:a].should == 1
|
16
|
-
end
|
6
|
+
describe "ClassMethods" do
|
7
|
+
subject { klass }
|
17
8
|
|
18
|
-
|
19
|
-
|
20
|
-
end
|
9
|
+
describe "::file" do
|
10
|
+
subject { klass.file }
|
21
11
|
|
22
|
-
|
23
|
-
|
24
|
-
|
12
|
+
context "when the file does not exist" do
|
13
|
+
before :each do
|
14
|
+
File.stub exists?: false
|
15
|
+
end
|
25
16
|
|
26
|
-
|
27
|
-
config[:b].should == 2
|
28
|
-
end
|
29
|
-
|
30
|
-
describe ".file" do
|
31
|
-
subject { klass.file }
|
32
|
-
|
33
|
-
context "when the file does not exist" do
|
34
|
-
before :each do
|
35
|
-
File.stub exists?: false
|
17
|
+
it { should be_nil }
|
36
18
|
end
|
37
|
-
|
38
|
-
it { should be_nil }
|
39
19
|
end
|
40
|
-
end
|
41
|
-
|
42
|
-
describe ".from_json" do
|
43
|
-
subject(:config) { klass.from_json json }
|
44
20
|
|
45
|
-
|
46
|
-
|
47
|
-
{
|
48
|
-
"a": 1,
|
49
|
-
"b": {
|
50
|
-
"c": 2
|
51
|
-
}
|
52
|
-
}
|
53
|
-
JSON
|
54
|
-
}
|
21
|
+
describe "::instance" do
|
22
|
+
subject { klass.instance }
|
55
23
|
|
56
|
-
|
57
|
-
config[:a].should == 1
|
24
|
+
it { should be_a klass }
|
58
25
|
end
|
59
26
|
|
60
|
-
|
61
|
-
|
62
|
-
end
|
63
|
-
|
64
|
-
it "does not raise an error for nested hash keys that have not been set" do
|
65
|
-
config[:d][:e]
|
66
|
-
end
|
27
|
+
describe "::path" do
|
28
|
+
subject { klass.path }
|
67
29
|
|
68
|
-
|
69
|
-
config['a'].should == 1
|
70
|
-
config[:a].should == 1
|
71
|
-
end
|
30
|
+
it { should be_a String }
|
72
31
|
|
73
|
-
|
74
|
-
|
32
|
+
it "points to a location within ENV['BERKSHELF_PATH']" do
|
33
|
+
ENV.stub(:[]).with('BERKSHELF_PATH').and_return('/tmp')
|
75
34
|
|
76
|
-
|
35
|
+
subject.should eql("/tmp/config.json")
|
36
|
+
end
|
77
37
|
end
|
78
|
-
end
|
79
38
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
39
|
+
describe "::chef_config" do
|
40
|
+
it "returns the Chef::Config" do
|
41
|
+
subject.chef_config.should eql(Chef::Config)
|
42
|
+
end
|
43
|
+
end
|
85
44
|
|
86
|
-
|
87
|
-
|
45
|
+
describe "::chef_config_path" do
|
46
|
+
subject { klass.chef_config_path }
|
88
47
|
|
89
|
-
|
48
|
+
it { should be_a String }
|
49
|
+
end
|
90
50
|
end
|
91
51
|
end
|