diff options
-rw-r--r-- | CHANGELOG.md | 5 | ||||
-rw-r--r-- | RELEASE_NOTES.md | 25 | ||||
-rw-r--r-- | lib/chef/provider/group/dscl.rb | 36 | ||||
-rw-r--r-- | spec/unit/provider/group/dscl_spec.rb | 39 |
4 files changed, 95 insertions, 10 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md index d69eb3308b..92247d9d3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,9 +2,14 @@ ## 11.14.4: + * Fix RPM package version detection (Issue 1554) +* [**Phil Dibowitz**](https://github.com/jaymzh): + 'group' provider on OSX properly uses 'dscl' to determine existing groups + + ## Last Release: 11.14.2 * [**Phil Dibowitz**](https://github.com/jaymzh): diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index a863b37970..f56e10cc95 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -122,6 +122,7 @@ automatic_attribute_whitelist = ["network/interfaces/eth0"] ```` then the entire `filesystem` and `eth1` subtrees will not be saved by the node. To save the `/dev/disk0s2` subtree, you must write `automatic_attribute_whitelist = [ ["filesystem", "/dev/disk0s2"] ]`. +<<<<<<< HEAD If your config file looks like `automatic_attribute_whitelist = []`, then none of your automatic attribute data will be saved by the node. The default behavior is for the node to save all the attribute data. This can be ensured by setting your whitelist filter to `nil`. @@ -183,3 +184,27 @@ attribute :home, default: lazy do |new_resource| end end ``` + +These changes do not impact any cookbook code, but may impact tools that +use the code base as a library. Authors of tools that rely on Chef +internals should review these changes carefully and update their +applications. + +## Changes to CookbookUpload + +`Chef::CookbookUpload.new` previously took a path as the second +argument, but due to internal changes, this parameter was not used, and +it has been removed. See: https://github.com/opscode/chef/commit/12c9bed3a5a7ab86ff78cb660d96f8b77ad6395d + +## Changes to FileVendor + +`Chef::Cookbook::FileVendor` was previously configured by passing a +block to the `on_create` method; it is now configured by calling either +`fetch_from_remote` or `fetch_from_disk`. See: https://github.com/opscode/chef/commit/3b2b4de8e7f0d55524f2a0ccaf3e1aa9f2d371eb + +## 'group' provider on OSX properly uses 'dscl' to determine existing groups + +On OSX, the 'group' provider would use 'etc' to determine existing groups, +but 'dscl' to add groups, causing broken idempotency if something existed +in /etc/group. The provider now uses 'dscl' for both idempotenty checks and +modifications. diff --git a/lib/chef/provider/group/dscl.rb b/lib/chef/provider/group/dscl.rb index c204c09321..04ca9bc929 100644 --- a/lib/chef/provider/group/dscl.rb +++ b/lib/chef/provider/group/dscl.rb @@ -39,11 +39,33 @@ class Chef return result[2] end - # This is handled in providers/group.rb by Etc.getgrnam() - # def group_exists?(group) - # groups = safe_dscl("list /Groups") - # !! ( groups =~ Regexp.new("\n#{group}\n") ) - # end + def load_current_resource + @current_resource = Chef::Resource::Group.new(@new_resource.name) + @current_resource.group_name(@new_resource.name) + group_info = nil + begin + group_info = safe_dscl("read /Groups/#{@new_resource.name}") + rescue Chef::Exceptions::Group + @group_exists = false + Chef::Log.debug("#{@new_resource} group does not exist") + end + + if group_info + group_info.each_line do |line| + key, val = line.split(': ') + val.strip! if val + case key.downcase + when 'primarygroupid' + @new_resource.gid(val) unless @new_resource.gid + @current_resource.gid(val) + when 'groupmembership' + @current_resource.members(val.split(' ')) + end + end + end + + @current_resource + end # get a free GID greater than 200 def get_free_gid(search_limit=1000) @@ -115,10 +137,6 @@ class Chef end end - def load_current_resource - super - end - def create_group dscl_create_group set_gid diff --git a/spec/unit/provider/group/dscl_spec.rb b/spec/unit/provider/group/dscl_spec.rb index 5a02ee8dfb..8848a01bf2 100644 --- a/spec/unit/provider/group/dscl_spec.rb +++ b/spec/unit/provider/group/dscl_spec.rb @@ -240,6 +240,7 @@ describe Chef::Provider::Group::Dscl do @provider.load_current_resource @provider.define_resource_requirements end + it "raises an error if the required binary /usr/bin/dscl doesn't exist" do File.should_receive(:exists?).with("/usr/bin/dscl").and_return(false) @@ -251,7 +252,7 @@ describe Chef::Provider::Group::Dscl do lambda { @provider.process_resource_requirements }.should_not raise_error end end - + describe "when creating the group" do it "creates the group, password field, gid, and sets group membership" do @provider.should_receive(:set_gid).and_return(true) @@ -294,3 +295,39 @@ describe Chef::Provider::Group::Dscl do end end end + +describe 'Test DSCL loading' do + before do + @node = Chef::Node.new + @events = Chef::EventDispatch::Dispatcher.new + @run_context = Chef::RunContext.new(@node, {}, @events) + @new_resource = Chef::Resource::Group.new("aj") + @provider = Chef::Provider::Group::Dscl.new(@new_resource, @run_context) + @output = <<-EOF +AppleMetaNodeLocation: /Local/Default +Comment: + Test Group +GeneratedUID: AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAA +NestedGroups: AAAAAAAA-AAAA-AAAA-AAAA-AAAAAAAAAAAB +Password: * +PrimaryGroupID: 999 +RealName: + TestGroup +RecordName: com.apple.aj +RecordType: dsRecTypeStandard:Groups +GroupMembership: waka bar +EOF + @provider.stub(:safe_dscl).with("read /Groups/aj").and_return(@output) + @current_resource = @provider.load_current_resource + + end + + it 'should parse gid properly' do + File.stub(:exists?).and_return(true) + @current_resource.gid.should eq("999") + end + it 'should parse members properly' do + File.stub(:exists?).and_return(true) + @current_resource.members.should eq(['waka', 'bar']) + end +end |