chef 11.6.0.rc.0 → 11.6.0.rc.1
Sign up to get free protection for your applications and to get access to all the features.
- data/distro/common/html/chef-client.8.html +4 -4
- data/distro/common/html/chef-expander.8.html +4 -4
- data/distro/common/html/chef-expanderctl.8.html +4 -4
- data/distro/common/html/chef-server-webui.8.html +4 -4
- data/distro/common/html/chef-server.8.html +4 -4
- data/distro/common/html/chef-shell.1.html +4 -4
- data/distro/common/html/chef-solo.8.html +4 -4
- data/distro/common/html/chef-solr.8.html +4 -4
- data/distro/common/html/knife-bootstrap.1.html +4 -4
- data/distro/common/html/knife-client.1.html +4 -4
- data/distro/common/html/knife-configure.1.html +4 -4
- data/distro/common/html/knife-cookbook-site.1.html +4 -4
- data/distro/common/html/knife-cookbook.1.html +4 -4
- data/distro/common/html/knife-data-bag.1.html +4 -4
- data/distro/common/html/knife-environment.1.html +4 -4
- data/distro/common/html/knife-exec.1.html +4 -4
- data/distro/common/html/knife-index.1.html +4 -4
- data/distro/common/html/knife-node.1.html +4 -4
- data/distro/common/html/knife-role.1.html +4 -4
- data/distro/common/html/knife-search.1.html +4 -4
- data/distro/common/html/knife-ssh.1.html +4 -4
- data/distro/common/html/knife-status.1.html +4 -4
- data/distro/common/html/knife-tag.1.html +4 -4
- data/distro/common/html/knife.1.html +4 -4
- data/distro/common/man/man1/chef-shell.1 +1 -1
- data/distro/common/man/man1/knife-bootstrap.1 +1 -1
- data/distro/common/man/man1/knife-client.1 +1 -1
- data/distro/common/man/man1/knife-configure.1 +1 -1
- data/distro/common/man/man1/knife-cookbook-site.1 +1 -1
- data/distro/common/man/man1/knife-cookbook.1 +1 -1
- data/distro/common/man/man1/knife-data-bag.1 +1 -1
- data/distro/common/man/man1/knife-environment.1 +1 -1
- data/distro/common/man/man1/knife-exec.1 +1 -1
- data/distro/common/man/man1/knife-index.1 +1 -1
- data/distro/common/man/man1/knife-node.1 +1 -1
- data/distro/common/man/man1/knife-role.1 +1 -1
- data/distro/common/man/man1/knife-search.1 +1 -1
- data/distro/common/man/man1/knife-ssh.1 +1 -1
- data/distro/common/man/man1/knife-status.1 +1 -1
- data/distro/common/man/man1/knife-tag.1 +1 -1
- data/distro/common/man/man1/knife.1 +1 -1
- data/distro/common/man/man8/chef-client.8 +1 -1
- data/distro/common/man/man8/chef-expander.8 +1 -1
- data/distro/common/man/man8/chef-expanderctl.8 +1 -1
- data/distro/common/man/man8/chef-server-webui.8 +1 -1
- data/distro/common/man/man8/chef-server.8 +1 -1
- data/distro/common/man/man8/chef-solo.8 +1 -1
- data/distro/common/man/man8/chef-solr.8 +1 -1
- data/lib/chef/cookbook/cookbook_version_loader.rb +10 -19
- data/lib/chef/cookbook/file_system_file_vendor.rb +4 -7
- data/lib/chef/cookbook/metadata.rb +1 -10
- data/lib/chef/cookbook/syntax_check.rb +4 -4
- data/lib/chef/cookbook_uploader.rb +1 -1
- data/lib/chef/cookbook_version.rb +6 -10
- data/lib/chef/provider/file.rb +2 -1
- data/lib/chef/provider/package/yum.rb +1 -1
- data/lib/chef/resource/file.rb +2 -0
- data/lib/chef/scan_access_control.rb +6 -1
- data/lib/chef/util/diff.rb +31 -5
- data/lib/chef/version.rb +1 -1
- data/spec/functional/knife/exec_spec.rb +2 -2
- data/spec/spec_helper.rb +3 -0
- data/spec/support/platform_helpers.rb +12 -0
- data/spec/support/shared/functional/file_resource.rb +50 -10
- data/spec/support/shared/unit/provider/file.rb +4 -2
- data/spec/unit/cookbook/metadata_spec.rb +50 -56
- data/spec/unit/cookbook_loader_spec.rb +1 -22
- data/spec/unit/provider/package/yum_spec.rb +17 -36
- data/spec/unit/scan_access_control_spec.rb +4 -2
- data/spec/unit/util/diff_spec.rb +351 -11
- metadata +53 -9
- checksums.yaml +0 -15
- data/spec/data/cookbooks/not-nginx/attributes/default.rb +0 -1
- data/spec/data/cookbooks/not-nginx/metadata.rb +0 -1
- data/spec/data/kitchen/no-really-not-nginx/attributes/default.rb +0 -1
- data/spec/data/kitchen/no-really-not-nginx/metadata.rb +0 -1
@@ -37,17 +37,14 @@ class Chef
|
|
37
37
|
raise ArgumentError, "You must specify at least one repo path" if @repo_paths.empty?
|
38
38
|
end
|
39
39
|
|
40
|
-
def cookbooks
|
41
|
-
@cookbooks ||= Chef::CookbookLoader.new(@repo_paths).load_cookbooks
|
42
|
-
end
|
43
|
-
|
44
40
|
# Implements abstract base's requirement. It looks in the
|
45
41
|
# Chef::Config.cookbook_path file hierarchy for the requested
|
46
42
|
# file.
|
47
43
|
def get_filename(filename)
|
48
|
-
|
49
|
-
|
50
|
-
|
44
|
+
location = @repo_paths.inject(nil) do |memo, basepath|
|
45
|
+
candidate_location = File.join(basepath, @cookbook_name, filename)
|
46
|
+
memo = candidate_location if File.exist?(candidate_location)
|
47
|
+
memo
|
51
48
|
end
|
52
49
|
raise "File #{filename} does not exist for cookbook #{@cookbook_name}" unless location
|
53
50
|
|
@@ -91,7 +91,7 @@ class Chef
|
|
91
91
|
# metadata<Chef::Cookbook::Metadata>
|
92
92
|
def initialize(cookbook=nil, maintainer='YOUR_COMPANY_NAME', maintainer_email='YOUR_EMAIL', license='none')
|
93
93
|
@cookbook = cookbook
|
94
|
-
@name = cookbook ? cookbook.name :
|
94
|
+
@name = cookbook ? cookbook.name : ""
|
95
95
|
@long_description = ""
|
96
96
|
self.maintainer(maintainer)
|
97
97
|
self.maintainer_email(maintainer_email)
|
@@ -468,15 +468,6 @@ class Chef
|
|
468
468
|
@groupings = o[GROUPINGS] if o.has_key?(GROUPINGS)
|
469
469
|
@recipes = o[RECIPES] if o.has_key?(RECIPES)
|
470
470
|
@version = o[VERSION] if o.has_key?(VERSION)
|
471
|
-
#
|
472
|
-
# XXX: When a client (berkshelf in particular) uploads metadata without a name field, the hosted chef
|
473
|
-
# ruby server will subsequently return empty string ("") for the metadata.name. In erchef uploading
|
474
|
-
# metadata without a name field will simply not store or retrieve a name field so we get @name = nil.
|
475
|
-
# During the migration from ruby to erchef, metadata.name of "" was migrated faithfully even though it
|
476
|
-
# fails validation, and erchef will return this, so we still have to handle this case unless the
|
477
|
-
# database is sanitized to remove metadata.name == "".
|
478
|
-
#
|
479
|
-
@name = nil if !@name.nil? && @name.empty?
|
480
471
|
self
|
481
472
|
end
|
482
473
|
|
@@ -85,14 +85,14 @@ class Chef
|
|
85
85
|
# validated.
|
86
86
|
attr_reader :validated_files
|
87
87
|
|
88
|
-
# Creates a new SyntaxCheck given the +
|
88
|
+
# Creates a new SyntaxCheck given the +cookbook_name+ and a +cookbook_path+.
|
89
89
|
# If no +cookbook_path+ is given, +Chef::Config.cookbook_path+ is used.
|
90
|
-
def self.for_cookbook(
|
90
|
+
def self.for_cookbook(cookbook_name, cookbook_path=nil)
|
91
91
|
cookbook_path ||= Chef::Config.cookbook_path
|
92
92
|
unless cookbook_path
|
93
|
-
raise ArgumentError, "Cannot find cookbook #{
|
93
|
+
raise ArgumentError, "Cannot find cookbook #{cookbook_name} unless Chef::Config.cookbook_path is set or an explicit cookbook path is given"
|
94
94
|
end
|
95
|
-
new(File.join(cookbook_path,
|
95
|
+
new(File.join(cookbook_path, cookbook_name.to_s))
|
96
96
|
end
|
97
97
|
|
98
98
|
# Create a new SyntaxCheck object
|
@@ -159,7 +159,7 @@ class Chef
|
|
159
159
|
|
160
160
|
def validate_cookbooks
|
161
161
|
cookbooks.each do |cb|
|
162
|
-
syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cb.
|
162
|
+
syntax_checker = Chef::Cookbook::SyntaxCheck.for_cookbook(cb.name, @user_cookbook_path)
|
163
163
|
Chef::Log.info("Validating ruby files")
|
164
164
|
exit(1) unless syntax_checker.validate_ruby_files
|
165
165
|
Chef::Log.info("Validating templates")
|
@@ -50,7 +50,7 @@ class Chef
|
|
50
50
|
attr_accessor :resource_filenames
|
51
51
|
attr_accessor :provider_filenames
|
52
52
|
attr_accessor :root_filenames
|
53
|
-
attr_accessor :
|
53
|
+
attr_accessor :name
|
54
54
|
attr_accessor :metadata
|
55
55
|
attr_accessor :metadata_filenames
|
56
56
|
attr_accessor :status
|
@@ -83,8 +83,8 @@ class Chef
|
|
83
83
|
#
|
84
84
|
# === Returns
|
85
85
|
# object<Chef::CookbookVersion>:: Duh. :)
|
86
|
-
def initialize(
|
87
|
-
@
|
86
|
+
def initialize(name)
|
87
|
+
@name = name
|
88
88
|
@frozen = false
|
89
89
|
@attribute_filenames = Array.new
|
90
90
|
@definition_filenames = Array.new
|
@@ -104,10 +104,6 @@ class Chef
|
|
104
104
|
@metadata = Chef::Cookbook::Metadata.new
|
105
105
|
end
|
106
106
|
|
107
|
-
def name
|
108
|
-
metadata.name || @pathname
|
109
|
-
end
|
110
|
-
|
111
107
|
def version
|
112
108
|
metadata.version
|
113
109
|
end
|
@@ -602,11 +598,11 @@ class Chef
|
|
602
598
|
specificity = "default"
|
603
599
|
|
604
600
|
if segment == :root_files
|
605
|
-
matcher = segment_file.match(".+/#{Regexp.escape(
|
601
|
+
matcher = segment_file.match(".+/#{Regexp.escape(name.to_s)}/(.+)")
|
606
602
|
file_name = matcher[1]
|
607
603
|
path = file_name
|
608
604
|
elsif segment == :templates || segment == :files
|
609
|
-
matcher = segment_file.match("/#{Regexp.escape(
|
605
|
+
matcher = segment_file.match("/#{Regexp.escape(name.to_s)}/(#{Regexp.escape(segment.to_s)}/(.+?)/(.+))")
|
610
606
|
unless matcher
|
611
607
|
Chef::Log.debug("Skipping file #{segment_file}, as it isn't in any of the proper directories (platform-version, platform or default)")
|
612
608
|
Chef::Log.debug("You probably need to move #{segment_file} into the 'default' sub-directory")
|
@@ -616,7 +612,7 @@ class Chef
|
|
616
612
|
specificity = matcher[2]
|
617
613
|
file_name = matcher[3]
|
618
614
|
else
|
619
|
-
matcher = segment_file.match("/#{Regexp.escape(
|
615
|
+
matcher = segment_file.match("/#{Regexp.escape(name.to_s)}/(#{Regexp.escape(segment.to_s)}/(.+))")
|
620
616
|
path = matcher[1]
|
621
617
|
file_name = matcher[2]
|
622
618
|
end
|
data/lib/chef/provider/file.rb
CHANGED
@@ -74,7 +74,7 @@ class Chef
|
|
74
74
|
# Let children resources override constructing the @current_resource
|
75
75
|
@current_resource ||= Chef::Resource::File.new(@new_resource.name)
|
76
76
|
@current_resource.path(@new_resource.path)
|
77
|
-
if
|
77
|
+
if ::File.exists?(@current_resource.path) && ::File.file?(::File.realpath(@current_resource.path))
|
78
78
|
if @action != :create_if_missing && @current_resource.respond_to?(:checksum)
|
79
79
|
@current_resource.checksum(checksum(@current_resource.path))
|
80
80
|
end
|
@@ -292,6 +292,7 @@ class Chef
|
|
292
292
|
converge_by(description) do
|
293
293
|
unlink(@new_resource.path)
|
294
294
|
end
|
295
|
+
@current_resource.checksum = nil
|
295
296
|
@file_unlinked = true
|
296
297
|
end
|
297
298
|
end
|
data/lib/chef/resource/file.rb
CHANGED
@@ -127,7 +127,12 @@ class Chef
|
|
127
127
|
end
|
128
128
|
|
129
129
|
def stat
|
130
|
-
@stat ||= @new_resource.instance_of?(Chef::Resource::Link)
|
130
|
+
@stat ||= if @new_resource.instance_of?(Chef::Resource::Link)
|
131
|
+
::File.lstat(@new_resource.path)
|
132
|
+
else
|
133
|
+
realpath = ::File.realpath(@new_resource.path)
|
134
|
+
::File.stat(realpath)
|
135
|
+
end
|
131
136
|
end
|
132
137
|
end
|
133
138
|
end
|
data/lib/chef/util/diff.rb
CHANGED
@@ -22,6 +22,10 @@ class Chef
|
|
22
22
|
class Diff
|
23
23
|
include Chef::Mixin::ShellOut
|
24
24
|
|
25
|
+
# @todo: to_a, to_s, to_json, inspect defs, accessors for @diff and @error
|
26
|
+
# @todo: move coercion to UTF-8 into to_json
|
27
|
+
# @todo: replace shellout to diff -u with diff-lcs gem
|
28
|
+
|
25
29
|
def for_output
|
26
30
|
# formatted output to a terminal uses arrays of strings and returns error strings
|
27
31
|
@diff.nil? ? [ @error ] : @diff
|
@@ -75,8 +79,13 @@ class Chef
|
|
75
79
|
|
76
80
|
begin
|
77
81
|
# -u: Unified diff format
|
82
|
+
# LC_ALL: in ruby 1.9 we want to set nil which is a magic option to mixlib-shellout to
|
83
|
+
# pass through the LC_ALL locale. in ruby 1.8 we force to 7-bit 'C' locale
|
84
|
+
# (which is the mixlib-shellout default for all rubies all the time).
|
78
85
|
Chef::Log.debug("running: diff -u #{old_file} #{new_file}")
|
79
|
-
|
86
|
+
locale = ( Object.const_defined? :Encoding ) ? nil : 'C'
|
87
|
+
result = shell_out("diff -u #{old_file} #{new_file}", :env => {'LC_ALL' => locale})
|
88
|
+
|
80
89
|
rescue Exception => e
|
81
90
|
# Should *not* receive this, but in some circumstances it seems that
|
82
91
|
# an exception can be thrown even using shell_out instead of shell_out!
|
@@ -94,7 +103,18 @@ class Chef
|
|
94
103
|
if result.stdout.length > diff_output_threshold
|
95
104
|
return "(long diff of over #{diff_output_threshold} characters, diff output suppressed)"
|
96
105
|
else
|
97
|
-
|
106
|
+
diff_str = result.stdout
|
107
|
+
if Object.const_defined? :Encoding # ruby >= 1.9
|
108
|
+
if ( diff_str.encoding == Encoding::ASCII_8BIT &&
|
109
|
+
diff_str.encoding != Encoding.default_external &&
|
110
|
+
RUBY_VERSION.to_f < 2.0 )
|
111
|
+
# @todo mixlib-shellout under ruby 1.9 hands back an ASCII-8BIT encoded string, which needs to
|
112
|
+
# be fixed to the default external encoding -- this should be moved into mixlib-shellout
|
113
|
+
diff_str = diff_str.force_encoding(Encoding.default_external)
|
114
|
+
end
|
115
|
+
diff_str.encode!('UTF-8', :invalid => :replace, :undef => :replace, :replace => '?')
|
116
|
+
end
|
117
|
+
@diff = diff_str.split("\n")
|
98
118
|
@diff.delete("\")
|
99
119
|
return "(diff available)"
|
100
120
|
end
|
@@ -106,10 +126,16 @@ class Chef
|
|
106
126
|
end
|
107
127
|
|
108
128
|
def is_binary?(path)
|
109
|
-
|
110
|
-
|
129
|
+
File.open(path) do |file|
|
130
|
+
# XXX: this slurps into RAM, but we should have already checked our diff has a reasonable size
|
131
|
+
buff = file.read
|
111
132
|
buff = "" if buff.nil?
|
112
|
-
|
133
|
+
begin
|
134
|
+
return buff !~ /\A[\s[:print:]]*\z/m
|
135
|
+
rescue ArgumentError => e
|
136
|
+
return true if e.message =~ /invalid byte sequence/
|
137
|
+
raise
|
138
|
+
end
|
113
139
|
end
|
114
140
|
end
|
115
141
|
|
data/lib/chef/version.rb
CHANGED
@@ -46,12 +46,12 @@ describe Chef::Knife::Exec do
|
|
46
46
|
|
47
47
|
pending "executes a script in the context of the chef-shell main context", :ruby_18_only
|
48
48
|
|
49
|
-
it "executes a script in the context of the chef-shell main context", :
|
49
|
+
it "executes a script in the context of the chef-shell main context", :ruby_gte_19_only do
|
50
50
|
@node = Chef::Node.new
|
51
51
|
@node.name("ohai-world")
|
52
52
|
response = {"rows" => [@node],"start" => 0,"total" => 1}
|
53
53
|
@api.get(%r{^/search/node}, 200, response.to_json)
|
54
|
-
code = "$output.puts nodes.all
|
54
|
+
code = "$output.puts nodes.all"
|
55
55
|
@knife.config[:exec] = code
|
56
56
|
@knife.run
|
57
57
|
$output.string.should match(%r{node\[ohai-world\]})
|
data/spec/spec_helper.rb
CHANGED
@@ -104,6 +104,9 @@ RSpec.configure do |config|
|
|
104
104
|
config.filter_run_excluding :selinux_only => true unless selinux_enabled?
|
105
105
|
config.filter_run_excluding :ruby_18_only => true unless ruby_18?
|
106
106
|
config.filter_run_excluding :ruby_19_only => true unless ruby_19?
|
107
|
+
config.filter_run_excluding :ruby_gte_19_only => true unless ruby_gte_19?
|
108
|
+
config.filter_run_excluding :ruby_20_only => true unless ruby_20?
|
109
|
+
config.filter_run_excluding :ruby_gte_20_only => true unless ruby_gte_20?
|
107
110
|
config.filter_run_excluding :requires_root => true unless ENV['USER'] == 'root'
|
108
111
|
config.filter_run_excluding :requires_unprivileged_user => true if ENV['USER'] == 'root'
|
109
112
|
config.filter_run_excluding :uses_diff => true unless has_diff?
|
@@ -523,15 +523,8 @@ shared_examples_for "a configured file resource" do
|
|
523
523
|
resource.path(link_path)
|
524
524
|
# create symlinks for test context
|
525
525
|
File.symlink(path, link_path)
|
526
|
-
|
527
|
-
# Create source (real) file
|
528
|
-
File.open(path, "wb") { |f| f.write(wrong_content) }
|
529
526
|
end
|
530
527
|
|
531
|
-
include_context "setup broken permissions"
|
532
|
-
|
533
|
-
include_examples "a securable resource with existing target"
|
534
|
-
|
535
528
|
after(:each) do
|
536
529
|
# shared examples should not change our test setup of a file resource
|
537
530
|
# pointing at a symlink:
|
@@ -539,9 +532,56 @@ shared_examples_for "a configured file resource" do
|
|
539
532
|
FileUtils.rm_rf(link_path)
|
540
533
|
end
|
541
534
|
|
542
|
-
|
543
|
-
|
544
|
-
|
535
|
+
context "and the permissions are incorrect" do
|
536
|
+
before do
|
537
|
+
# Create source (real) file
|
538
|
+
File.open(path, "wb") { |f| f.write(expected_content) }
|
539
|
+
end
|
540
|
+
|
541
|
+
|
542
|
+
include_context "setup broken permissions"
|
543
|
+
|
544
|
+
include_examples "a securable resource with existing target"
|
545
|
+
|
546
|
+
it "does not replace the symlink with a real file" do
|
547
|
+
resource.run_action(:create)
|
548
|
+
File.should be_symlink(link_path)
|
549
|
+
end
|
550
|
+
|
551
|
+
end
|
552
|
+
|
553
|
+
context "and the content is incorrect" do
|
554
|
+
before do
|
555
|
+
# Create source (real) file
|
556
|
+
File.open(path, "wb") { |f| f.write(wrong_content) }
|
557
|
+
end
|
558
|
+
|
559
|
+
it "updates the source file content" do
|
560
|
+
pending
|
561
|
+
end
|
562
|
+
|
563
|
+
it "marks the resource as updated" do
|
564
|
+
resource.run_action(:create)
|
565
|
+
resource.should be_updated_by_last_action
|
566
|
+
end
|
567
|
+
|
568
|
+
it "does not replace the symlink with a real file" do
|
569
|
+
resource.run_action(:create)
|
570
|
+
File.should be_symlink(link_path)
|
571
|
+
end
|
572
|
+
end
|
573
|
+
|
574
|
+
context "and the content and permissions are correct" do
|
575
|
+
let(:expect_updated?) { false }
|
576
|
+
|
577
|
+
before do
|
578
|
+
# Create source (real) file
|
579
|
+
File.open(path, "wb") { |f| f.write(expected_content) }
|
580
|
+
end
|
581
|
+
include_context "setup correct permissions"
|
582
|
+
|
583
|
+
include_examples "a securable resource with existing target"
|
584
|
+
|
545
585
|
end
|
546
586
|
|
547
587
|
end
|
@@ -146,7 +146,8 @@ shared_examples_for Chef::Provider::File do
|
|
146
146
|
# mock up the filesystem to behave like unix
|
147
147
|
setup_normal_file
|
148
148
|
stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
|
149
|
-
File.
|
149
|
+
resource_real_path = File.realpath(resource.path)
|
150
|
+
File.should_receive(:stat).with(resource_real_path).at_least(:once).and_return(stat_struct)
|
150
151
|
Etc.stub!(:getgrgid).with(0).and_return(mock("Group Ent", :name => "wheel"))
|
151
152
|
Etc.stub!(:getpwuid).with(0).and_return(mock("User Ent", :name => "root"))
|
152
153
|
end
|
@@ -270,7 +271,8 @@ shared_examples_for Chef::Provider::File do
|
|
270
271
|
# mock up the filesystem to behave like unix
|
271
272
|
setup_normal_file
|
272
273
|
stat_struct = mock("::File.stat", :mode => 0600, :uid => 0, :gid => 0, :mtime => 10000)
|
273
|
-
File.
|
274
|
+
resource_real_path = File.realpath(resource.path)
|
275
|
+
File.stub!(:stat).with(resource_real_path).and_return(stat_struct)
|
274
276
|
Etc.stub!(:getgrgid).with(0).and_return(mock("Group Ent", :name => "wheel"))
|
275
277
|
Etc.stub!(:getpwuid).with(0).and_return(mock("User Ent", :name => "root"))
|
276
278
|
provider.send(:load_resource_attributes_from_file, resource)
|
@@ -7,9 +7,9 @@
|
|
7
7
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
8
8
|
# you may not use this file except in compliance with the License.
|
9
9
|
# You may obtain a copy of the License at
|
10
|
-
#
|
10
|
+
#
|
11
11
|
# http://www.apache.org/licenses/LICENSE-2.0
|
12
|
-
#
|
12
|
+
#
|
13
13
|
# Unless required by applicable law or agreed to in writing, software
|
14
14
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
15
15
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
@@ -20,7 +20,7 @@
|
|
20
20
|
require 'spec_helper'
|
21
21
|
require 'chef/cookbook/metadata'
|
22
22
|
|
23
|
-
describe Chef::Cookbook::Metadata do
|
23
|
+
describe Chef::Cookbook::Metadata do
|
24
24
|
before(:each) do
|
25
25
|
@cookbook = Chef::CookbookVersion.new('test_cookbook')
|
26
26
|
@meta = Chef::Cookbook::Metadata.new(@cookbook)
|
@@ -86,7 +86,7 @@ describe Chef::Cookbook::Metadata do
|
|
86
86
|
it "should return a Chef::Cookbook::Metadata object" do
|
87
87
|
@meta.should be_a_kind_of(Chef::Cookbook::Metadata)
|
88
88
|
end
|
89
|
-
|
89
|
+
|
90
90
|
it "should allow a cookbook as the first argument" do
|
91
91
|
lambda { Chef::Cookbook::Metadata.new(@cookbook) }.should_not raise_error
|
92
92
|
end
|
@@ -96,7 +96,7 @@ describe Chef::Cookbook::Metadata do
|
|
96
96
|
end
|
97
97
|
|
98
98
|
it "should set the maintainer name from the second argument" do
|
99
|
-
md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown')
|
99
|
+
md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown')
|
100
100
|
md.maintainer.should == 'Bobo T. Clown'
|
101
101
|
end
|
102
102
|
|
@@ -105,7 +105,7 @@ describe Chef::Cookbook::Metadata do
|
|
105
105
|
end
|
106
106
|
|
107
107
|
it "should set the maintainer email from the third argument" do
|
108
|
-
md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co')
|
108
|
+
md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co')
|
109
109
|
md.maintainer_email.should == 'bobo@clown.co'
|
110
110
|
end
|
111
111
|
|
@@ -114,10 +114,10 @@ describe Chef::Cookbook::Metadata do
|
|
114
114
|
end
|
115
115
|
|
116
116
|
it "should set the license from the fourth argument" do
|
117
|
-
md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co', 'Clown License v1')
|
117
|
+
md = Chef::Cookbook::Metadata.new(@cookbook, 'Bobo T. Clown', 'bobo@clown.co', 'Clown License v1')
|
118
118
|
md.license.should == 'Clown License v1'
|
119
119
|
end
|
120
|
-
end
|
120
|
+
end
|
121
121
|
|
122
122
|
describe "cookbook" do
|
123
123
|
it "should return the cookbook we were initialized with" do
|
@@ -133,7 +133,7 @@ describe Chef::Cookbook::Metadata do
|
|
133
133
|
|
134
134
|
describe "platforms" do
|
135
135
|
it "should return the current platform hash" do
|
136
|
-
@meta.platforms.should be_a_kind_of(Hash)
|
136
|
+
@meta.platforms.should be_a_kind_of(Hash)
|
137
137
|
end
|
138
138
|
end
|
139
139
|
|
@@ -235,7 +235,7 @@ describe Chef::Cookbook::Metadata do
|
|
235
235
|
end
|
236
236
|
end
|
237
237
|
end
|
238
|
-
|
238
|
+
|
239
239
|
describe "attribute groupings" do
|
240
240
|
it "should allow you set a grouping" do
|
241
241
|
group = {
|
@@ -312,7 +312,7 @@ describe Chef::Cookbook::Metadata do
|
|
312
312
|
@meta.attribute("db/mysql/databases", {})
|
313
313
|
@meta.attributes["db/mysql/databases"][:choice].should == []
|
314
314
|
end
|
315
|
-
|
315
|
+
|
316
316
|
it "should let calculated be true or false" do
|
317
317
|
lambda {
|
318
318
|
@meta.attribute("db/mysql/databases", :calculated => true)
|
@@ -324,7 +324,7 @@ describe Chef::Cookbook::Metadata do
|
|
324
324
|
@meta.attribute("db/mysql/databases", :calculated => Hash.new)
|
325
325
|
}.should raise_error(ArgumentError)
|
326
326
|
end
|
327
|
-
|
327
|
+
|
328
328
|
it "should set calculated to false by default" do
|
329
329
|
@meta.attribute("db/mysql/databases", {})
|
330
330
|
@meta.attributes["db/mysql/databases"][:calculated].should == false
|
@@ -350,7 +350,7 @@ describe Chef::Cookbook::Metadata do
|
|
350
350
|
@meta.attribute("db/mysql/databases", :type => "symbol")
|
351
351
|
}.should_not raise_error(ArgumentError)
|
352
352
|
end
|
353
|
-
|
353
|
+
|
354
354
|
it "should let type be hash (backwards compatability only)" do
|
355
355
|
lambda {
|
356
356
|
@meta.attribute("db/mysql/databases", :type => "hash")
|
@@ -375,7 +375,7 @@ describe Chef::Cookbook::Metadata do
|
|
375
375
|
}.should_not raise_error(ArgumentError)
|
376
376
|
#attrib = @meta.attributes["db/mysql/databases"][:required].should == "required"
|
377
377
|
end
|
378
|
-
|
378
|
+
|
379
379
|
it "should convert required false to optional" do
|
380
380
|
lambda {
|
381
381
|
@meta.attribute("db/mysql/databases", :required => false)
|
@@ -387,7 +387,7 @@ describe Chef::Cookbook::Metadata do
|
|
387
387
|
@meta.attribute("db/mysql/databases", {})
|
388
388
|
@meta.attributes["db/mysql/databases"][:required].should == 'optional'
|
389
389
|
end
|
390
|
-
|
390
|
+
|
391
391
|
it "should make sure recipes is an array" do
|
392
392
|
lambda {
|
393
393
|
@meta.attribute("db/mysql/databases", :recipes => [])
|
@@ -399,7 +399,7 @@ describe Chef::Cookbook::Metadata do
|
|
399
399
|
|
400
400
|
it "should set recipes to an empty array by default" do
|
401
401
|
@meta.attribute("db/mysql/databases", {})
|
402
|
-
@meta.attributes["db/mysql/databases"][:recipes].should == []
|
402
|
+
@meta.attributes["db/mysql/databases"][:recipes].should == []
|
403
403
|
end
|
404
404
|
|
405
405
|
it "should allow the default value to be a string, array, or hash" do
|
@@ -438,14 +438,14 @@ describe Chef::Cookbook::Metadata do
|
|
438
438
|
lambda {
|
439
439
|
attrs = {
|
440
440
|
:choice => [ "a", "b", "c"],
|
441
|
-
:default => "b"
|
441
|
+
:default => "b"
|
442
442
|
}
|
443
443
|
@meta.attribute("db/mysql/databases", attrs)
|
444
444
|
}.should_not raise_error(ArgumentError)
|
445
445
|
lambda {
|
446
446
|
attrs = {
|
447
447
|
:choice => [ "a", "b", "c", "d", "e"],
|
448
|
-
:default => ["b", "d"]
|
448
|
+
:default => ["b", "d"]
|
449
449
|
}
|
450
450
|
@meta.attribute("db/mysql/databases", attrs)
|
451
451
|
}.should_not raise_error(ArgumentError)
|
@@ -455,7 +455,7 @@ describe Chef::Cookbook::Metadata do
|
|
455
455
|
lambda {
|
456
456
|
attrs = {
|
457
457
|
:choice => [ "a", "b", "c"],
|
458
|
-
:default => "d"
|
458
|
+
:default => "d"
|
459
459
|
}
|
460
460
|
@meta.attribute("db/mysql/databases", attrs)
|
461
461
|
}.should raise_error(ArgumentError)
|
@@ -470,11 +470,11 @@ describe Chef::Cookbook::Metadata do
|
|
470
470
|
end
|
471
471
|
|
472
472
|
describe "recipes" do
|
473
|
-
before(:each) do
|
473
|
+
before(:each) do
|
474
474
|
@cookbook.recipe_files = [ "default.rb", "enlighten.rb" ]
|
475
475
|
@meta = Chef::Cookbook::Metadata.new(@cookbook)
|
476
476
|
end
|
477
|
-
|
477
|
+
|
478
478
|
it "should have the names of the recipes" do
|
479
479
|
@meta.recipes["test_cookbook"].should == ""
|
480
480
|
@meta.recipes["test_cookbook::enlighten"].should == ""
|
@@ -493,7 +493,7 @@ describe Chef::Cookbook::Metadata do
|
|
493
493
|
end
|
494
494
|
|
495
495
|
describe "json" do
|
496
|
-
before(:each) do
|
496
|
+
before(:each) do
|
497
497
|
@cookbook.recipe_files = [ "default.rb", "enlighten.rb" ]
|
498
498
|
@meta = Chef::Cookbook::Metadata.new(@cookbook)
|
499
499
|
@meta.version "1.0"
|
@@ -509,8 +509,8 @@ describe Chef::Cookbook::Metadata do
|
|
509
509
|
@meta.provides "foo(:bar, :baz)"
|
510
510
|
@meta.replaces "snarkitron"
|
511
511
|
@meta.recipe "test_cookbook::enlighten", "is your buddy"
|
512
|
-
@meta.attribute "bizspark/has_login",
|
513
|
-
:display_name => "You have nothing"
|
512
|
+
@meta.attribute "bizspark/has_login",
|
513
|
+
:display_name => "You have nothing"
|
514
514
|
@meta.version "1.2.3"
|
515
515
|
end
|
516
516
|
|
@@ -524,23 +524,23 @@ describe Chef::Cookbook::Metadata do
|
|
524
524
|
end
|
525
525
|
|
526
526
|
%w{
|
527
|
-
name
|
528
|
-
description
|
529
|
-
long_description
|
530
|
-
maintainer
|
531
|
-
maintainer_email
|
527
|
+
name
|
528
|
+
description
|
529
|
+
long_description
|
530
|
+
maintainer
|
531
|
+
maintainer_email
|
532
532
|
license
|
533
|
-
platforms
|
534
|
-
dependencies
|
535
|
-
suggestions
|
536
|
-
recommendations
|
537
|
-
conflicting
|
533
|
+
platforms
|
534
|
+
dependencies
|
535
|
+
suggestions
|
536
|
+
recommendations
|
537
|
+
conflicting
|
538
538
|
providing
|
539
|
-
replacing
|
540
|
-
attributes
|
539
|
+
replacing
|
540
|
+
attributes
|
541
541
|
recipes
|
542
542
|
version
|
543
|
-
}.each do |t|
|
543
|
+
}.each do |t|
|
544
544
|
it "should include '#{t}'" do
|
545
545
|
@serial[t].should == @meta.send(t.to_sym)
|
546
546
|
end
|
@@ -557,23 +557,23 @@ describe Chef::Cookbook::Metadata do
|
|
557
557
|
end
|
558
558
|
|
559
559
|
%w{
|
560
|
-
name
|
561
|
-
description
|
562
|
-
long_description
|
563
|
-
maintainer
|
564
|
-
maintainer_email
|
560
|
+
name
|
561
|
+
description
|
562
|
+
long_description
|
563
|
+
maintainer
|
564
|
+
maintainer_email
|
565
565
|
license
|
566
|
-
platforms
|
567
|
-
dependencies
|
568
|
-
suggestions
|
569
|
-
recommendations
|
570
|
-
conflicting
|
566
|
+
platforms
|
567
|
+
dependencies
|
568
|
+
suggestions
|
569
|
+
recommendations
|
570
|
+
conflicting
|
571
571
|
providing
|
572
|
-
replacing
|
573
|
-
attributes
|
572
|
+
replacing
|
573
|
+
attributes
|
574
574
|
recipes
|
575
575
|
version
|
576
|
-
}.each do |t|
|
576
|
+
}.each do |t|
|
577
577
|
it "should match '#{t}'" do
|
578
578
|
@deserial.send(t.to_sym).should == @meta.send(t.to_sym)
|
579
579
|
end
|
@@ -585,12 +585,6 @@ describe Chef::Cookbook::Metadata do
|
|
585
585
|
@hash = @meta.to_hash
|
586
586
|
end
|
587
587
|
|
588
|
-
it "should convert a name field containing the empty string to nil" do
|
589
|
-
@hash['name'] = ""
|
590
|
-
deserial = Chef::Cookbook::Metadata.from_hash(@hash)
|
591
|
-
deserial.name.should be_nil
|
592
|
-
end
|
593
|
-
|
594
588
|
[:dependencies,
|
595
589
|
:recommendations,
|
596
590
|
:suggestions,
|