diff options
-rwxr-xr-x | bin/puppetmasterd | 11 | ||||
-rw-r--r-- | lib/puppet.rb | 3 | ||||
-rw-r--r-- | lib/puppet/config.rb | 16 | ||||
-rw-r--r-- | lib/puppet/log.rb | 3 | ||||
-rwxr-xr-x | lib/puppet/sslcertificates.rb | 19 | ||||
-rw-r--r-- | lib/puppet/statechange.rb | 3 | ||||
-rw-r--r-- | lib/puppet/type.rb | 1 | ||||
-rwxr-xr-x | lib/puppet/type/group.rb | 69 | ||||
-rwxr-xr-x | lib/puppet/type/nameservice.rb | 22 | ||||
-rw-r--r-- | lib/puppet/type/nameservice/objectadd.rb | 4 | ||||
-rwxr-xr-x | lib/puppet/type/pfile/ensure.rb | 8 | ||||
-rwxr-xr-x | lib/puppet/type/user.rb | 69 | ||||
-rw-r--r-- | lib/puppet/util.rb | 20 | ||||
-rwxr-xr-x | test/language/snippets.rb | 9 | ||||
-rwxr-xr-x | test/puppet/utiltest.rb | 12 | ||||
-rw-r--r-- | test/types/file.rb | 15 | ||||
-rwxr-xr-x | test/types/group.rb | 19 | ||||
-rwxr-xr-x | test/types/user.rb | 19 |
18 files changed, 267 insertions, 55 deletions
diff --git a/bin/puppetmasterd b/bin/puppetmasterd index 3ae74f73b..fed55d89f 100755 --- a/bin/puppetmasterd +++ b/bin/puppetmasterd @@ -164,8 +164,6 @@ Puppet.genmanifest require 'etc' -Puppet::Util.chuser - if Puppet::Log.level == :debug or Puppet::Log.level == :info or parseonly args[:Daemonize] = false else @@ -212,6 +210,15 @@ rescue => detail exit(1) end +if Process.uid == 0 + begin + Puppet::Util.chuser + rescue => detail + $stderr.puts "Could not change user to %s: %s" % [Puppet[:user], detail] + exit(39) + end +end + if Puppet[:parseonly] # we would have already exited if the file weren't syntactically correct exit(0) diff --git a/lib/puppet.rb b/lib/puppet.rb index a3ff166bc..289320776 100644 --- a/lib/puppet.rb +++ b/lib/puppet.rb @@ -124,8 +124,7 @@ module Puppet }, :statefile => { :default => "$statedir/state.yaml", :mode => 0660, - :owner => "$user", - :owner => "$group", + :group => "$group", :desc => "Where puppetd and puppetmasterd store state associated with the running configuration. In the case of puppetmasterd, this file reflects the state discovered through interacting diff --git a/lib/puppet/config.rb b/lib/puppet/config.rb index 06aebb893..e38e26517 100644 --- a/lib/puppet/config.rb +++ b/lib/puppet/config.rb @@ -326,6 +326,7 @@ class Config newobj.tag(section) else newobj = TransObject.new(name, type.to_s) + newobj.tags = ["puppet", "configuration", section] newobj[:ensure] = "present" done[type][name] = newobj objects << newobj @@ -476,8 +477,11 @@ Generated on #{Time.now}. bucket = Puppet::TransBucket.new bucket.type = "puppetconfig" bucket.top = true + + # Create a hash to keep track of what we've done so far. + @done = Hash.new { |hash, key| hash[key] = {} } runners.each do |section| - bucket.push section_to_transportable(section, nil, false) + bucket.push section_to_transportable(section, @done, false) end objects = bucket.to_type @@ -486,15 +490,11 @@ Generated on #{Time.now}. trans = objects.evaluate trans.evaluate - # And then clean up. We're now a tree of objects, so we have to - # use delve, instead of each. - #objects.delve do |object| + # Remove is a recursive process, so it's sufficient to just call + # it on the component. objects.remove - #trans.objects.each do |object| - # object.remove(true) - #end - sections.each { |s| @used << s } + runners.each { |s| @used << s } end end diff --git a/lib/puppet/log.rb b/lib/puppet/log.rb index ec7ec9e8b..6b8a55c18 100644 --- a/lib/puppet/log.rb +++ b/lib/puppet/log.rb @@ -28,7 +28,8 @@ module Puppet } #@destinations = {:syslog => Syslog.open("puppet")} - @destinations = {:console => :console} + #@destinations = {:console => :console} + @destinations = {} # Reset all logs to basics. Basically just closes all files and undefs # all of the other objects. diff --git a/lib/puppet/sslcertificates.rb b/lib/puppet/sslcertificates.rb index 88a9193d1..a56e64add 100755 --- a/lib/puppet/sslcertificates.rb +++ b/lib/puppet/sslcertificates.rb @@ -12,12 +12,19 @@ module Puppet::SSLCertificates Puppet.setdefaults("certificates", :certdir => ["$ssldir/certs", "The certificate directory."], :publickeydir => ["$ssldir/public_keys", "The public key directory."], - :privatekeydir => ["$ssldir/private_keys", "The private key directory."], - :privatedir => ["$ssldir/private", - "Where the client stores private certificate information."], - :passfile => ["$privatedir/password", - "Where puppetd stores the password for its private key. Generally - unused."] + :privatekeydir => { :default => "$ssldir/private_keys", + :mode => 0750, + :desc => "The private key directory." + }, + :privatedir => { :default => "$ssldir/private", + :mode => 0750, + :desc => "Where the client stores private certificate information." + }, + :passfile => { :default => "$privatedir/password", + :mode => 0640, + :desc => "Where puppetd stores the password for its private key. + Generally unused." + } ) #def self.mkcert(type, name, days, issuercert, issuername, serial, publickey) diff --git a/lib/puppet/statechange.rb b/lib/puppet/statechange.rb index 5fdf407d2..c18cdd25c 100644 --- a/lib/puppet/statechange.rb +++ b/lib/puppet/statechange.rb @@ -131,9 +131,6 @@ module Puppet [@state.is.inspect, @state.should.inspect] return nil end - - #raise "Moving statechanges backward is currently unsupported" - #@type.change(@path,@should,@is) end def noop diff --git a/lib/puppet/type.rb b/lib/puppet/type.rb index 4dda52c06..0e163adaf 100644 --- a/lib/puppet/type.rb +++ b/lib/puppet/type.rb @@ -1073,6 +1073,7 @@ class Type < Puppet::Element # necessary. FIXME This method should be responsible for most of the # error handling. def self.create(hash) + #Puppet.warning "Creating %s" % hash.inspect # Handle this new object being implicit implicit = hash[:implicit] || false if hash.include?(:implicit) diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb index 344614190..4e0bc4344 100755 --- a/lib/puppet/type/group.rb +++ b/lib/puppet/type/group.rb @@ -35,6 +35,75 @@ module Puppet @parentmodule = Puppet::NameService::ObjectAdd end + newstate(:ensure, @parentstate) do + newvalue(:present) do + self.syncname(:present) + end + + newvalue(:absent) do + self.syncname(:absent) + end + + desc "The basic state that the object should be in." + + # If they're talking about the thing at all, they generally want to + # say it should exist. + #defaultto :present + defaultto do + if @parent.managed? + :present + else + nil + end + end + + def change_to_s + begin + if @is == :absent + return "created" + elsif self.should == :absent + return "removed" + else + return "%s changed '%s' to '%s'" % + [self.name, self.is_to_s, self.should_to_s] + end + rescue Puppet::Error, Puppet::DevError + raise + rescue => detail + raise Puppet::DevError, + "Could not convert change %s to string: %s" % + [self.name, detail] + end + end + + def retrieve + if @parent.exists? + @is = :present + else + @is = :absent + end + end + + # The default 'sync' method only selects among a list of registered + # values. + def sync + if self.insync? + self.info "already in sync" + return nil + #else + #self.info "%s vs %s" % [self.is.inspect, self.should.inspect] + end + unless self.class.values + self.devfail "No values defined for %s" % + self.class.name + end + + # Set ourselves to whatever our should value is. + self.set + end + + end + newstate(:gid, @parentstate) do desc "The group ID. Must be specified numerically. If not specified, a number will be picked, which can result in ID diff --git a/lib/puppet/type/nameservice.rb b/lib/puppet/type/nameservice.rb index 9a9b280e5..3d323d138 100755 --- a/lib/puppet/type/nameservice.rb +++ b/lib/puppet/type/nameservice.rb @@ -19,22 +19,6 @@ class Type end end end - - # Create the object. We have to call the 'syncname' method - # on one of the non-ensure states, because the ensure state is not - # a subclass of NSSState. Just find the first one and call it. - def create - @states.find { |name, state| - state.is_a?(Puppet::State::NSSState) - }[1].syncname(:present) - end - - # Remove it - def destroy - @states.find { |name, state| - state.is_a?(Puppet::State::NSSState) - }[1].syncname(:absent) - end end end @@ -175,7 +159,7 @@ class State when :absent # we need to remove the object... unless @parent.exists? - @parent.info "already absent" + self.info "already absent" # the object already doesn't exist return nil end @@ -186,7 +170,7 @@ class State type = "delete" when :present if @parent.exists? - @parent.info "already exists" + self.info "already exists" # The object already exists return nil end @@ -207,7 +191,7 @@ class State # we want object creation to show up as one event, # not many unless self.class.allatonce? - Puppet.debug "%s is not allatonce" % self.class.name + Puppet.debug "%s is not allatonce" % @parent.class.name if type == "create" @parent.eachstate { |state| state.sync diff --git a/lib/puppet/type/nameservice/objectadd.rb b/lib/puppet/type/nameservice/objectadd.rb index 2d88d24f1..fc866f193 100644 --- a/lib/puppet/type/nameservice/objectadd.rb +++ b/lib/puppet/type/nameservice/objectadd.rb @@ -17,7 +17,7 @@ module Puppet # Does the object already exist? def self.exists?(obj) - if obj.getinfo + if obj.getinfo(true) return true else return false @@ -62,7 +62,7 @@ module Puppet cmd = ["groupadd"] if gid = @parent.should(:gid) unless gid == :auto - cmd << self.class.objectaddflag << gid + cmd << @parent.state(:gid).class.objectaddflag << gid end end cmd << @parent[:name] diff --git a/lib/puppet/type/pfile/ensure.rb b/lib/puppet/type/pfile/ensure.rb index dfef404db..6d0da89e7 100755 --- a/lib/puppet/type/pfile/ensure.rb +++ b/lib/puppet/type/pfile/ensure.rb @@ -27,7 +27,9 @@ module Puppet Puppet::Util.asuser(asuser(), @parent.should(:group)) { f = nil if mode - f = File.open(@parent[:path],"w", mode) + Puppet::Util.withumask(000) do + f = File.open(@parent[:path],"w", mode) + end else f = File.open(@parent[:path],"w") end @@ -52,7 +54,9 @@ module Puppet end Puppet::Util.asuser(asuser()) { if mode - Dir.mkdir(@parent[:path],mode) + Puppet::Util.withumask(000) do + Dir.mkdir(@parent[:path],mode) + end else Dir.mkdir(@parent[:path]) end diff --git a/lib/puppet/type/user.rb b/lib/puppet/type/user.rb index ed9c79211..ea80f7f0b 100755 --- a/lib/puppet/type/user.rb +++ b/lib/puppet/type/user.rb @@ -17,8 +17,73 @@ module Puppet @parentmodule = Puppet::NameService::ObjectAdd end - # The 'create' and 'destroy' methods are defined in type/nameservice.rb - self.ensurable() + newstate(:ensure, @parentstate) do + newvalue(:present) do + self.syncname(:present) + end + + newvalue(:absent) do + self.syncname(:absent) + end + + desc "The basic state that the object should be in." + + # If they're talking about the thing at all, they generally want to + # say it should exist. + #defaultto :present + defaultto do + if @parent.managed? + :present + else + nil + end + end + + def change_to_s + begin + if @is == :absent + return "created" + elsif self.should == :absent + return "removed" + else + return "%s changed '%s' to '%s'" % + [self.name, self.is_to_s, self.should_to_s] + end + rescue Puppet::Error, Puppet::DevError + raise + rescue => detail + raise Puppet::DevError, + "Could not convert change %s to string: %s" % + [self.name, detail] + end + end + + def retrieve + if @parent.exists? + @is = :present + else + @is = :absent + end + end + # The default 'sync' method only selects among a list of registered + # values. + def sync + if self.insync? + self.info "already in sync" + return nil + #else + #self.info "%s vs %s" % [self.is.inspect, self.should.inspect] + end + unless self.class.values + self.devfail "No values defined for %s" % + self.class.name + end + + # Set ourselves to whatever our should value is. + self.set + end + + end newstate(:uid, @parentstate) do desc "The user ID. Must be specified numerically. For new users diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb index 419b4892e..fd283539b 100644 --- a/lib/puppet/util.rb +++ b/lib/puppet/util.rb @@ -164,13 +164,15 @@ module Util end end else - unless obj = Puppet.type(:group)[group] + if obj = Puppet.type(:group)[group] + obj[:check] = [:gid] + else obj = Puppet.type(:group).create( :name => group, :check => [:gid] ) - obj.retrieve end + obj.retrieve end if obj gid = obj.should(:gid) || obj.is(:gid) @@ -207,10 +209,10 @@ module Util else unless obj = Puppet.type(:user)[user] obj = Puppet.type(:user).create( - :name => user, - :check => [:uid, :gid] + :name => user ) end + obj[:check] = [:uid, :gid] end if obj @@ -281,6 +283,16 @@ module Util raise ArgumentError, "'%s' must be a string or symbol" % value end end + + def self.withumask(mask) + cur = File.umask(mask) + + begin + yield + ensure + File.umask(cur) + end + end end end diff --git a/test/language/snippets.rb b/test/language/snippets.rb index 8cc9ace40..bba1537c2 100755 --- a/test/language/snippets.rb +++ b/test/language/snippets.rb @@ -466,10 +466,11 @@ class TestSnippets < Test::Unit::TestCase Puppet::Type.eachtype { |type| type.each { |obj| - unless obj.name == "puppet[top]" or - obj.is_a?(Puppet.type(:schedule)) - assert(obj.parent, "%s has no parent" % obj.name) - end + # don't worry about this for now + #unless obj.name == "puppet[top]" or + # obj.is_a?(Puppet.type(:schedule)) + # assert(obj.parent, "%s has no parent" % obj.name) + #end assert(obj.name) if obj.is_a?(Puppet.type(:file)) diff --git a/test/puppet/utiltest.rb b/test/puppet/utiltest.rb index ec398d8b9..68b55b1ff 100755 --- a/test/puppet/utiltest.rb +++ b/test/puppet/utiltest.rb @@ -143,6 +143,18 @@ class TestPuppetUtil < Test::Unit::TestCase assert_equal(user, uid, "Got mismatched ids") end + def test_withumask + File.umask(022) + + path = tempfile() + Puppet::Util.withumask(000) do + Dir.mkdir(path, 01777) + end + + assert(File.stat(path).mode & 007777 == 01777) + assert_equal(022, File.umask) + end + unless Process.uid == 0 $stderr.puts "Run as root to perform Utility tests" def test_nothing diff --git a/test/types/file.rb b/test/types/file.rb index 25fc82781..513d7cca8 100644 --- a/test/types/file.rb +++ b/test/types/file.rb @@ -766,6 +766,21 @@ class TestFile < Test::Unit::TestCase assert(file.state(:group), "Group state failed") end + + def test_modecreation + path = tempfile() + file = Puppet.type(:file).create( + :path => path, + :ensure => "file", + :mode => "0777" + ) + assert_apply(file) + assert_equal(0777, File.stat(path).mode & 007777) + File.unlink(path) + file[:ensure] = "directory" + assert_apply(file) + assert_equal(0777, File.stat(path).mode & 007777) + end end # $Id$ diff --git a/test/types/group.rb b/test/types/group.rb index e044949e6..372b35cb3 100755 --- a/test/types/group.rb +++ b/test/types/group.rb @@ -90,6 +90,25 @@ class TestGroup < Test::Unit::TestCase Process.groups end + def attrtest_ensure(group) + old = group.is(:ensure) + group[:ensure] = :absent + + comp = newcomp("ensuretest", group) + assert_apply(group) + assert(missing?(group.name), "User is still present") + group[:ensure] = :present + assert_events([:group_created], comp) + assert(!missing?(group.name), "User is absent") + group[:ensure] = :absent + trans = assert_events([:group_removed], comp) + + assert_rollback_events(trans, [:group_created], "group") + + group[:ensure] = old + assert_apply(group) + end + def attrtest_gid(group) obj = nil #assert_nothing_raised { diff --git a/test/types/user.rb b/test/types/user.rb index acd7aba1d..18da94ff6 100755 --- a/test/types/user.rb +++ b/test/types/user.rb @@ -125,6 +125,25 @@ class TestUser < Test::Unit::TestCase return user end + def attrtest_ensure(user) + old = user.is(:ensure) + user[:ensure] = :absent + + comp = newcomp("ensuretest", user) + assert_apply(user) + assert(missing?(user.name), "User is still present") + user[:ensure] = :present + assert_events([:user_created], comp) + assert(!missing?(user.name), "User is absent") + user[:ensure] = :absent + trans = assert_events([:user_removed], comp) + + assert_rollback_events(trans, [:user_created], "user") + + user[:ensure] = old + assert_apply(user) + end + def attrtest_comment(user) old = user.is(:comment) user[:comment] = "A different comment" |