summaryrefslogtreecommitdiffstats
path: root/lib/puppet/util
diff options
context:
space:
mode:
Diffstat (limited to 'lib/puppet/util')
-rw-r--r--lib/puppet/util/backups.rb3
-rwxr-xr-xlib/puppet/util/filetype.rb46
-rw-r--r--lib/puppet/util/log.rb28
-rw-r--r--lib/puppet/util/log_paths.rb14
-rw-r--r--lib/puppet/util/rdoc/generators/puppet_generator.rb8
-rw-r--r--lib/puppet/util/reference.rb9
-rw-r--r--lib/puppet/util/selinux.rb12
-rw-r--r--lib/puppet/util/settings.rb55
8 files changed, 117 insertions, 58 deletions
diff --git a/lib/puppet/util/backups.rb b/lib/puppet/util/backups.rb
index 4ab67771d..470d6d1bb 100644
--- a/lib/puppet/util/backups.rb
+++ b/lib/puppet/util/backups.rb
@@ -26,8 +26,9 @@ module Puppet::Util::Backups
info "Recursively backing up to filebucket"
Find.find(self[:path]) { |f| backup_file_with_filebucket(f) if File.file?(f) }
when "file"; backup_file_with_filebucket(file)
- when "link"; return true
+ when "link";
end
+ true
end
def perform_backup_with_backuplocal(fileobj, backup)
diff --git a/lib/puppet/util/filetype.rb b/lib/puppet/util/filetype.rb
index 93c002fa9..8e8b8dd5c 100755
--- a/lib/puppet/util/filetype.rb
+++ b/lib/puppet/util/filetype.rb
@@ -251,4 +251,50 @@ class Puppet::Util::FileType
output_file.delete
end
end
+
+ # Support for AIX crontab with output different than suntab's crontab command.
+ newfiletype(:aixtab) do
+ # Read a specific @path's cron tab.
+ def read
+ begin
+ output = Puppet::Util.execute(%w{crontab -l}, :uid => @path)
+ if output.include?("You are not authorized to use the cron command")
+ raise Puppet::Error, "User %s not authorized to use cron" % @path
+ end
+ return output
+ rescue => detail
+ raise Puppet::Error, "Could not read crontab for %s: %s" % [@path, detail]
+ end
+ end
+
+ # Remove a specific @path's cron tab.
+ def remove
+ begin
+ Puppet::Util.execute(%w{crontab -r}, :uid => @path)
+ rescue => detail
+ raise Puppet::Error, "Could not remove crontab for %s: %s" % [@path, detail]
+ end
+ end
+
+ # Overwrite a specific @path's cron tab; must be passed the @path name
+ # and the text with which to create the cron tab.
+ def write(text)
+ require "tempfile"
+ output_file = Tempfile.new("puppet")
+ fh = output_file.open
+ fh.print text
+ fh.close
+
+ # We have to chown the stupid file to the user.
+ File.chown(Puppet::Util.uid(@path), nil, output_file.path)
+
+ begin
+ Puppet::Util.execute(["crontab", output_file.path], :uid => @path)
+ rescue => detail
+ raise Puppet::Error, "Could not write crontab for %s: %s" % [@path, detail]
+ ensure
+ output_file.delete
+ end
+ end
+ end
end
diff --git a/lib/puppet/util/log.rb b/lib/puppet/util/log.rb
index 4cdad700c..90d722900 100644
--- a/lib/puppet/util/log.rb
+++ b/lib/puppet/util/log.rb
@@ -511,11 +511,16 @@ class Puppet::Util::Log
# If they pass a source in to us, we make sure it is a string, and
# we retrieve any tags we can.
def source=(source)
- # We can't store the actual source, we just store the path.
- # We can't just check for whether it responds to :path, because
- # plenty of providers respond to that in their normal function.
- if (source.is_a?(Puppet::Type) or source.is_a?(Puppet::Parameter)) and source.respond_to?(:path)
- set_source_from_ral(source)
+ if source.respond_to?(:source_descriptors)
+ descriptors = source.source_descriptors
+ @source = descriptors[:path]
+
+ descriptors[:tags].each { |t| tag(t) }
+
+ [:file, :line, :version].each do |param|
+ next unless descriptors[param]
+ send(param.to_s + "=", descriptors[param])
+ end
else
@source = source.to_s
end
@@ -528,19 +533,6 @@ class Puppet::Util::Log
def to_s
return @message
end
-
- private
-
- def set_source_from_ral(source)
- @source = source.path
-
- source.tags.each { |t| tag(t) }
-
- [:file, :line, :version].each do |param|
- next unless value = source.send(param)
- send(param.to_s + "=", value)
- end
- end
end
# This is for backward compatibility from when we changed the constant to Puppet::Util::Log
diff --git a/lib/puppet/util/log_paths.rb b/lib/puppet/util/log_paths.rb
index 1a6bafc45..46f6c481d 100644
--- a/lib/puppet/util/log_paths.rb
+++ b/lib/puppet/util/log_paths.rb
@@ -11,5 +11,19 @@ module Puppet::Util::LogPaths
return "/" + @path.join("/")
end
+
+ def source_descriptors
+ descriptors = {}
+
+ descriptors[:tags] = tags
+
+ [:path, :file, :line, :version].each do |param|
+ next unless value = send(param)
+ descriptors[param] = value
+ end
+
+ return descriptors
+ end
+
end
diff --git a/lib/puppet/util/rdoc/generators/puppet_generator.rb b/lib/puppet/util/rdoc/generators/puppet_generator.rb
index 1a4219ff4..31181f05a 100644
--- a/lib/puppet/util/rdoc/generators/puppet_generator.rb
+++ b/lib/puppet/util/rdoc/generators/puppet_generator.rb
@@ -1,5 +1,7 @@
require 'rdoc/generators/html_generator'
require 'puppet/util/rdoc/code_objects'
+require 'digest/md5'
+
module Generators
# This module holds all the classes needed to generate the HTML documentation
@@ -364,7 +366,7 @@ module Generators
resources.each do |r|
res << {
"name" => CGI.escapeHTML(r.name),
- "aref" => "#{path_prefix}\##{r.aref}"
+ "aref" => CGI.escape(path_prefix)+"\#"+CGI.escape(r.aref)
}
end
res
@@ -465,7 +467,7 @@ module Generators
if path['<<']
path.gsub!(/<<\s*(\w*)/) { "from-#$1" }
end
- File.join(prefix, path.split("::")) + ".html"
+ File.join(prefix, path.split("::").collect { |p| Digest::MD5.hexdigest(p) }) + ".html"
end
def parent_name
@@ -568,7 +570,7 @@ module Generators
h_name = CGI.escapeHTML(name)
@values["classmod"] = "Node"
- @values["title"] = "#{@values['classmod']}: #{h_name}"
+ @values["title"] = CGI.escapeHTML("#{@values['classmod']}: #{h_name}")
c = @context
c = c.parent while c and !c.diagram
diff --git a/lib/puppet/util/reference.rb b/lib/puppet/util/reference.rb
index 7526e6566..93542df28 100644
--- a/lib/puppet/util/reference.rb
+++ b/lib/puppet/util/reference.rb
@@ -36,7 +36,7 @@ class Puppet::Util::Reference
def self.pdf(text)
puts "creating pdf"
- File.open("/tmp/puppetdoc.txt", "w") do |f|
+ Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
f.puts text
end
rst2latex = %x{which rst2latex}
@@ -48,6 +48,9 @@ class Puppet::Util::Reference
end
rst2latex.chomp!
cmd = %{#{rst2latex} /tmp/puppetdoc.txt > /tmp/puppetdoc.tex}
+ Puppet::Util.secure_open("/tmp/puppetdoc.tex","w") do |f|
+ # If we get here without an error, /tmp/puppetdoc.tex isn't a tricky cracker's symlink
+ end
output = %x{#{cmd}}
unless $? == 0
$stderr.puts "rst2latex failed"
@@ -67,7 +70,7 @@ class Puppet::Util::Reference
puts "Creating markdown for #{name} reference."
dir = "/tmp/" + Puppet::PUPPETVERSION
FileUtils.mkdir(dir) unless File.directory?(dir)
- File.open(dir + "/" + "#{name}.rst", "w") do |f|
+ Puppet::Util.secure_open(dir + "/" + "#{name}.rst", "w") do |f|
f.puts text
end
pandoc = %x{which pandoc}
@@ -190,7 +193,7 @@ class Puppet::Util::Reference
end
def trac
- File.open("/tmp/puppetdoc.txt", "w") do |f|
+ Puppet::Util.secure_open("/tmp/puppetdoc.txt", "w") do |f|
f.puts self.to_trac
end
diff --git a/lib/puppet/util/selinux.rb b/lib/puppet/util/selinux.rb
index 3eff03996..3801ecdb0 100644
--- a/lib/puppet/util/selinux.rb
+++ b/lib/puppet/util/selinux.rb
@@ -7,11 +7,7 @@
# was abysmal. At this time (2008-11-02) the only distribution providing
# these Ruby SELinux bindings which I am aware of is Fedora (in libselinux-ruby).
-begin
- require 'selinux'
-rescue LoadError
- # Nothing
-end
+Puppet.features.selinux? # check, but continue even if it's not
require 'pathname'
@@ -73,7 +69,7 @@ module Puppet::Util::SELinux
if context.nil? or context == "unlabeled"
return nil
end
- unless context =~ /^([a-z0-9_]+):([a-z0-9_]+):([a-z0-9_]+)(?::([a-zA-Z0-9:,._-]+))?/
+ unless context =~ /^([a-z0-9_]+):([a-z0-9_]+):([a-zA-Z0-9_]+)(?::([a-zA-Z0-9:,._-]+))?/
raise Puppet::Error, "Invalid context to parse: #{context}"
end
ret = {
@@ -170,8 +166,8 @@ module Puppet::Util::SELinux
# that's expected
rescue
return nil
- ensure
- mountfh.close
+ ensure
+ mountfh.close if mountfh
end
mntpoint = {}
diff --git a/lib/puppet/util/settings.rb b/lib/puppet/util/settings.rb
index f2c513b29..e6e13339b 100644
--- a/lib/puppet/util/settings.rb
+++ b/lib/puppet/util/settings.rb
@@ -64,20 +64,25 @@ class Puppet::Util::Settings
# Remove all set values, potentially skipping cli values.
def clear(exceptcli = false)
@sync.synchronize do
- @values.each do |name, values|
- @values.delete(name) unless exceptcli and name == :cli
- end
+ unsafe_clear(exceptcli)
+ end
+ end
+
+ # Remove all set values, potentially skipping cli values.
+ def unsafe_clear(exceptcli = false)
+ @values.each do |name, values|
+ @values.delete(name) unless exceptcli and name == :cli
+ end
- # Don't clear the 'used' in this case, since it's a config file reparse,
- # and we want to retain this info.
- unless exceptcli
- @used = []
- end
+ # Don't clear the 'used' in this case, since it's a config file reparse,
+ # and we want to retain this info.
+ unless exceptcli
+ @used = []
+ end
- @cache.clear
+ @cache.clear
- @name = nil
- end
+ @name = nil
end
# This is mostly just used for testing.
@@ -325,23 +330,25 @@ class Puppet::Util::Settings
# and reparsed if necessary.
set_filetimeout_timer()
- # Retrieve the value now, so that we don't lose it in the 'clear' call.
- file = self[:config]
-
- return unless FileTest.exist?(file)
-
- # We have to clear outside of the sync, because it's
- # also using synchronize().
- clear(true)
-
@sync.synchronize do
- unsafe_parse(file)
+ unsafe_parse(self[:config])
end
end
# Unsafely parse the file -- this isn't thread-safe and causes plenty of problems if used directly.
def unsafe_parse(file)
- parse_file(file).each do |area, values|
+ return unless FileTest.exist?(file)
+ begin
+ data = parse_file(file)
+ rescue => details
+ puts details.backtrace if Puppet[:trace]
+ Puppet.err "Could not parse #{file}: #{details}"
+ return
+ end
+
+ unsafe_clear(true)
+
+ data.each do |area, values|
@values[area] = values
end
@@ -433,9 +440,7 @@ class Puppet::Util::Settings
def reparse
if file and file.changed?
Puppet.notice "Reparsing %s" % file.file
- @sync.synchronize do
- parse
- end
+ parse
reuse()
end
end