diff --git a/lib/puppet/provider/group/groupadd.rb b/lib/puppet/provider/group/groupadd.rb index 82ed4c0c7..bcc08d9f7 100644 --- a/lib/puppet/provider/group/groupadd.rb +++ b/lib/puppet/provider/group/groupadd.rb @@ -1,29 +1,32 @@ require 'puppet/provider/nameservice/objectadd' Puppet::Type.type(:group).provide :groupadd, :parent => Puppet::Provider::NameService::ObjectAdd do desc "Group management via `groupadd` and its ilk. The default for most platforms " commands :add => "groupadd", :delete => "groupdel", :modify => "groupmod" + has_feature :system_groups + verify :gid, "GID must be an integer" do |value| value.is_a? Integer end def addcmd cmd = [command(:add)] if gid = @resource.should(:gid) unless gid == :absent cmd << flag(:gid) << gid end end cmd << "-o" if @resource.allowdupe? + cmd << "-r" if @resource.system? cmd << @resource[:name] cmd end end diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb index cde1cfd65..066bd49df 100755 --- a/lib/puppet/type/group.rb +++ b/lib/puppet/type/group.rb @@ -1,99 +1,109 @@ - require 'etc' require 'facter' module Puppet newtype(:group) do @doc = "Manage groups. On most platforms this can only create groups. Group membership must be managed on individual users. On some platforms such as OS X, group membership is managed as an attribute of the group, not the user record. Providers must have the feature 'manages_members' to manage the 'members' property of a group record." feature :manages_members, "For directories where membership is an attribute of groups not users." + feature :system_groups, + "The provider allows you to create system groups with lower GIDs." + ensurable do desc "Create or remove the group." newvalue(:present) do provider.create end newvalue(:absent) do provider.delete end end newproperty(:gid) do desc "The group ID. Must be specified numerically. If not specified, a number will be picked, which can result in ID differences across systems and thus is not recommended. The GID is picked according to local system standards." def retrieve provider.gid end def sync if self.should == :absent raise Puppet::DevError, "GID cannot be deleted" else provider.gid = self.should end end munge do |gid| case gid when String if gid =~ /^[-0-9]+$/ gid = Integer(gid) else self.fail "Invalid GID #{gid}" end when Symbol unless gid == :absent self.devfail "Invalid GID #{gid}" end end return gid end end newproperty(:members, :array_matching => :all, :required_features => :manages_members) do desc "The members of the group. For directory services where group membership is stored in the group objects, not the users." def change_to_s(currentvalue, newvalue) currentvalue = currentvalue.join(",") if currentvalue != :absent newvalue = newvalue.join(",") super(currentvalue, newvalue) end end newparam(:auth_membership) do desc "whether the provider is authoritative for group membership." defaultto true end newparam(:name) do desc "The group name. While naming limitations vary by system, it is advisable to keep the name to the degenerate limitations, which is a maximum of 8 characters beginning with a letter." isnamevar end newparam(:allowdupe, :boolean => true) do desc "Whether to allow duplicate GIDs. This option does not work on FreeBSD (contract to the `pw` man page)." newvalues(:true, :false) defaultto false end + + newparam(:system, :boolean => true) do + desc "Whether the group is a system group with lower GID." + + newvalues(:true, :false) + + defaultto false + end end end diff --git a/spec/unit/provider/group/groupadd_spec.rb b/spec/unit/provider/group/groupadd_spec.rb index 33d9acd98..65cc887e4 100755 --- a/spec/unit/provider/group/groupadd_spec.rb +++ b/spec/unit/provider/group/groupadd_spec.rb @@ -1,31 +1,41 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../../spec_helper' provider_class = Puppet::Type.type(:group).provider(:groupadd) describe provider_class do before do @resource = stub("resource", :name => "mygroup") @provider = provider_class.new(@resource) end - # #1360 it "should add -o when allowdupe is enabled and the group is being created" do @resource.stubs(:should).returns "fakeval" @resource.stubs(:[]).returns "fakeval" + @resource.stubs(:system?).returns true @resource.expects(:allowdupe?).returns true @provider.expects(:execute).with { |args| args.include?("-o") } @provider.create end it "should add -o when allowdupe is enabled and the gid is being modified" do @resource.stubs(:should).returns "fakeval" @resource.stubs(:[]).returns "fakeval" @resource.expects(:allowdupe?).returns true @provider.expects(:execute).with { |args| args.include?("-o") } @provider.gid = 150 end + + it "should add -r when system is enabled and the group is being created" do + @resource.stubs(:should).returns "fakeval" + @resource.stubs(:[]).returns "fakeval" + @resource.expects(:system?).returns true + @resource.stubs(:allowdupe?).returns true + @provider.expects(:execute).with { |args| args.include?("-r") } + + @provider.create + end end diff --git a/spec/unit/type/group_spec.rb b/spec/unit/type/group_spec.rb index b41ce71a0..e373dac6e 100755 --- a/spec/unit/type/group_spec.rb +++ b/spec/unit/type/group_spec.rb @@ -1,57 +1,64 @@ #!/usr/bin/env ruby require File.dirname(__FILE__) + '/../../spec_helper' describe Puppet::Type.type(:group) do before do ENV["PATH"] += File::PATH_SEPARATOR + "/usr/sbin" unless ENV["PATH"].split(File::PATH_SEPARATOR).include?("/usr/sbin") @class = Puppet::Type.type(:group) end it "should have a default provider" do @class.defaultprovider.should_not be_nil end it "should have a default provider inheriting from Puppet::Provider" do @class.defaultprovider.ancestors.should be_include(Puppet::Provider) end + it "should have a system_groups feature" do + @class.provider_feature(:system_groups).should_not be_nil + end + describe "when validating attributes" do [:name, :allowdupe].each do |param| it "should have a #{param} parameter" do @class.attrtype(param).should == :param end end [:ensure, :gid].each do |param| it "should have a #{param} property" do @class.attrtype(param).should == :property end end it "should convert gids provided as strings into integers" do @class.new(:name => "foo", :gid => "15")[:gid].should == 15 end it "should accepts gids provided as integers" do @class.new(:name => "foo", :gid => 15)[:gid].should == 15 end end - # #1407 - we need to declare the allowdupe param as boolean. it "should have a boolean method for determining if duplicates are allowed" do @class.new(:name => "foo").methods.should be_include("allowdupe?") end + it "should have a boolean method for determining if system groups are allowed" do + @class.new(:name => "foo").methods.should be_include("system?") + end + it "should call 'create' to create the group" do group = @class.new(:name => "foo", :ensure => :present) group.provider.expects(:create) group.parameter(:ensure).sync end it "should call 'delete' to remove the group" do group = @class.new(:name => "foo", :ensure => :absent) group.provider.expects(:delete) group.parameter(:ensure).sync end end