berkshelf 0.6.0.beta4 → 1.0.0.rc1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|