diff options
author | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-09-07 05:28:58 +0000 |
---|---|---|
committer | luke <luke@980ebf18-57e1-0310-9a29-db15c13687c0> | 2005-09-07 05:28:58 +0000 |
commit | 4cc12a85baf2617ad9d60d521249e24ffdefcd53 (patch) | |
tree | 3873e349624c4ad157d18a10195401ae0982dddd /lib | |
parent | 9e4ed0ca8887c99cd5f29b6f7d0a9eaa950c0693 (diff) | |
download | puppet-4cc12a85baf2617ad9d60d521249e24ffdefcd53.tar.gz puppet-4cc12a85baf2617ad9d60d521249e24ffdefcd53.tar.xz puppet-4cc12a85baf2617ad9d60d521249e24ffdefcd53.zip |
finishing up user and group support for now
git-svn-id: https://reductivelabs.com/svn/puppet/trunk@633 980ebf18-57e1-0310-9a29-db15c13687c0
Diffstat (limited to 'lib')
-rw-r--r-- | lib/puppet/statechange.rb | 6 | ||||
-rw-r--r-- | lib/puppet/transaction.rb | 1 | ||||
-rwxr-xr-x | lib/puppet/type/group.rb | 9 | ||||
-rwxr-xr-x | lib/puppet/type/user.rb | 210 |
4 files changed, 140 insertions, 86 deletions
diff --git a/lib/puppet/statechange.rb b/lib/puppet/statechange.rb index ac10dc301..af066a773 100644 --- a/lib/puppet/statechange.rb +++ b/lib/puppet/statechange.rb @@ -48,7 +48,7 @@ module Puppet if event.nil? #event = @state.parent.class.name.id2name + "_changed" # they didn't actually change anything - return + return nil elsif ! event.is_a?(Symbol) Puppet.warning "State '%s' returned invalid event '%s'; resetting to default" % [@state.class,event] @@ -111,6 +111,10 @@ module Puppet unless @state.insync? Puppet.notice "Rolling %s backward" % self return self.go + else + Puppet.debug "rollback is already in sync: %s vs. %s" % + [@state.is.inspect, @state.should.inspect] + return nil end #raise "Moving statechanges backward is currently unsupported" diff --git a/lib/puppet/transaction.rb b/lib/puppet/transaction.rb index 2e726df0b..f0ef8469d 100644 --- a/lib/puppet/transaction.rb +++ b/lib/puppet/transaction.rb @@ -115,6 +115,7 @@ class Transaction def rollback events = @changes.collect { |change| if change.is_a?(Puppet::StateChange) + # skip changes that were never actually run next unless change.run #change.transaction = self begin diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb index 38a56dc31..fc8b7555d 100755 --- a/lib/puppet/type/group.rb +++ b/lib/puppet/type/group.rb @@ -100,7 +100,12 @@ module Puppet :name ] - @doc = " " + @doc = "Manage groups. This type can only create groups. Group + membership must be managed on individual users." + + @paramdoc[:name] = "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." @name = :group @namevar = :name @@ -109,7 +114,7 @@ module Puppet begin @groupinfo = Etc.getgrnam(self[:name]) rescue ArgumentError => detail - # leave groupinfo as nil + @groupinfo = nil end end diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb index cc7bbadaa..c4b31ed3e 100755 --- a/lib/puppet/type/user.rb +++ b/lib/puppet/type/user.rb @@ -7,43 +7,95 @@ require 'puppet/type/state' module Puppet class State class UserState < Puppet::State - @@userinfo = nil - class << self - attr_accessor :infomethod - - def getinfo(refresh = false) - if @@userinfo.nil? or refresh == true - begin - @@userinfo = Etc.getpwnam(@parent[:name]) - rescue ArgumentError => detail - @@userinfo = :notfound - end + attr_accessor :flag + def infomethod + if defined? @infomethod and @infomethod + return @infomethod + else + return @name + end + end + end + + def create + obj = @parent.getinfo + + cmd = nil + event = nil + if @should == :notfound + # we need to remove the object... + if obj.nil? + # the user already doesn't exist + return nil end - @@userinfo + cmd = ["userdel", @parent.name] + type = "delete" + else + unless obj.nil? + raise Puppet::DevError, + "Got told to create a user that already exists" + end + # we're creating the user + + # i can just tell i'm going to regret this + # why doesn't POSIX include interfaces for adding users + # and groups? it's stupid + cmd = ["useradd"] + @parent.eachstate { |state| + # the value needs to be quoted, mostly because -c might + # have spaces in it + cmd << state.class.flag << "'%s'" % state.should + } + cmd << @parent.name + type = "create" + end + + output = %x{#{cmd.join(" ")} 2>&1} + + unless $? == 0 + raise Puppet::Error, "Could not %s group %s: %s" % + [type, @parent.name, output] end + + return "user_#{type}d".intern end def retrieve - info = self.class.getinfo(true) + if info = @parent.getinfo(true) + @is = info.send(self.class.infomethod) + else + @is = :notfound + end + end - method = self.class.infomethod || self.class.name + def sync + obj = @parent.getinfo - unless method - raise Puppet::DevError, - "Could not retrieve info method for state %s" % self.class.name + # if the user either does not or should not exist... + # yes, it's a badly named method + if obj.nil? or @should == :notfound + return self.create end - unless info.respond_to?(method) - raise Puppet::DevError, "UserInfo object does not respond to %s" % - method + # there's a possibility that we created the user in this session + # so verify that we're actually out of sync + if self.insync? + return nil end + cmd = [ + "usermod", self.class.flag, "'%s'" % @should, @parent.name + ].join(" ") - @is = info.send(method) - end + output = %x{#{cmd} 2>&1} - def sync + unless $? == 0 + raise Puppet::Error, "Could not modify %s on user %s: %s" % + [self.class.name, @parent.name, output] + end + + return :user_modified end end @@ -53,11 +105,13 @@ module Puppet automatically, which will likely result in the same user having different IDs on different systems, which is not recommended." @name = :uid + @flag = "-u" end class UserGID < UserState @doc = "The user's primary group. Can be specified numerically or by name." @name = :gid + @flag = "-g" def should=(gid) method = :getgrgid @@ -79,88 +133,54 @@ module Puppet @should = ginfo.gid end - - def sync - return :executed_command - end end class UserComment < UserState - @doc = "The expected return code. An error will be returned if the - executed command returns something else." + @doc = "A description of the user. Generally is a user's full name." @name = :comment - - def retrieve - end - - def sync - return :executed_command - end + @infomethod = :gecos + @flag = "-c" end class UserHome < UserState - @doc = "The expected return code. An error will be returned if the - executed command returns something else." + @doc = "The home directory of the user. The directory must be created + separately and is not currently checked for existence." @name = :home - - def retrieve - end - - def sync - return :executed_command - end + @infomethod = :dir + @flag = "-d" end class UserShell < UserState - @doc = "The expected return code. An error will be returned if the - executed command returns something else." + @doc = "The user's login shell. The shell must exist and be + executable." @name = :shell - - def retrieve - end - - def sync - return :executed_command - end + @flag = "-s" end + # these three states are all implemented differently on each platform, so i'm + # disabling them for now + + # FIXME Puppet::State::UserLocked is currently non-functional class UserLocked < UserState @doc = "The expected return code. An error will be returned if the executed command returns something else." @name = :locked - - def retrieve - end - - def sync - return :executed_command - end end + # FIXME Puppet::State::UserExpire is currently non-functional class UserExpire < UserState @doc = "The expected return code. An error will be returned if the executed command returns something else." @name = :expire - - def retrieve - end - - def sync - return :executed_command - end + @flag = "-e" end + # FIXME Puppet::State::UserInactive is currently non-functional class UserInactive < UserState @doc = "The expected return code. An error will be returned if the executed command returns something else." @name = :inactive - - def retrieve - end - - def sync - return :executed_command - end + @flag = "-f" end end @@ -172,25 +192,49 @@ module Puppet Puppet::State::UserGID, Puppet::State::UserComment, Puppet::State::UserHome, - Puppet::State::UserShell, - Puppet::State::UserLocked, - Puppet::State::UserExpire, - Puppet::State::UserInactive + Puppet::State::UserShell ] @parameters = [ :name ] - @doc = " - " + @paramdoc[:name] = "User name. While limitations are determined for + each operating system, it is generally a good idea to keep to the + degenerate 8 characters, beginning with a letter." + + @doc = "Manage users. Currently can create and modify users, but cannot + delete them. Theoretically all of the parameters are optional, + but if no parameters are specified the comment will be set to the + user name in order to make the internals work out correctly." @name = :user @namevar = :name + def getinfo(refresh = false) + if @userinfo.nil? or refresh == true + begin + @userinfo = Etc.getpwnam(self[:name]) + rescue ArgumentError => detail + @userinfo = nil + end + end + + @userinfo + end + + def initialize(hash) + @userinfo = nil + super + + if @states.empty? + self[:comment] = self[:name] + end + end + def retrieve - info = Puppet::State::UserState.getinfo + info = self.getinfo(true) - if info == :notfound + if info.nil? # the user does not exist @states.each { |name, state| state.is = :notfound |