From d25c2b282cc4cd703bba3d2457f93431098ddc85 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 9 Jul 2008 10:29:45 -0500 Subject: Fixed #1407 - allowdupe is now a boolean group parameter. This just fixes a regression. Signed-off-by: Luke Kanies --- lib/puppet/type/group.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/type/group.rb b/lib/puppet/type/group.rb index 36a4d49fa..2a5ac30da 100755 --- a/lib/puppet/type/group.rb +++ b/lib/puppet/type/group.rb @@ -110,7 +110,7 @@ module Puppet isnamevar end - newparam(:allowdupe) do + newparam(:allowdupe, :boolean => true) do desc "Whether to allow duplicate GIDs. This option does not work on FreeBSD (contract to the ``pw`` man page)." -- cgit From 80436550a1e3040399e410be3edf7c44d29fc320 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 9 Jul 2008 17:41:21 -0700 Subject: Fixing #1408 - --loadclasses works again. The problem was that the mechanism I was using for passing the node to the compiler was conflicting with the Indirector::Request's method of handling node authentication. Signed-off-by: Luke Kanies --- lib/puppet/indirector/catalog/compiler.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/indirector/catalog/compiler.rb b/lib/puppet/indirector/catalog/compiler.rb index 455a92cc7..a6a812817 100644 --- a/lib/puppet/indirector/catalog/compiler.rb +++ b/lib/puppet/indirector/catalog/compiler.rb @@ -14,7 +14,7 @@ class Puppet::Node::Catalog::Compiler < Puppet::Indirector::Code # Compile a node's catalog. def find(request) - unless node = request.options[:node] || find_node(request.key) + unless node = request.options[:use_node] || find_node(request.key) raise ArgumentError, "Could not find node '%s'; cannot compile" % request.key end -- cgit From 4c5293b837807f61002365114fd7004d2f74ad57 Mon Sep 17 00:00:00 2001 From: Francois Deppierraz Date: Fri, 11 Jul 2008 14:39:52 +0200 Subject: Fix #1409, Move path expansion from the type into the provider This avoid exceptions during type instanciation when a user does not yet exist. The drawback is that we cannot use generated resources anymore and have to mkdir, chown and chmod directly in the provided which is somewhat hackish. --- lib/puppet/provider/ssh_authorized_key/parsed.rb | 36 ++++++++++++++++++++++++ lib/puppet/type/ssh_authorized_key.rb | 26 +---------------- 2 files changed, 37 insertions(+), 25 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/ssh_authorized_key/parsed.rb b/lib/puppet/provider/ssh_authorized_key/parsed.rb index 351ebcd1b..3bd22c06b 100644 --- a/lib/puppet/provider/ssh_authorized_key/parsed.rb +++ b/lib/puppet/provider/ssh_authorized_key/parsed.rb @@ -29,5 +29,41 @@ Puppet::Type.type(:ssh_authorized_key).provide(:parsed, record[:options] = record[:options].join(',') end } + + def prefetch + # This was done in the type class but path expansion was failing for + # not yet existing users, the only workaround I found was to move that + # in the provider. + if user = @resource.should(:user) + target = File.expand_path("~%s/.ssh/authorized_keys" % user) + @property_hash[:target] = target + @resource[:target] = target + end + + super + end + + def flush + # As path expansion had to be moved in the provider, we cannot generate new file + # resources and thus have to chown and chmod here. It smells hackish. + + # Create target's parent directory if nonexistant + if target = @property_hash[:target] + dir = File.dirname(@property_hash[:target]) + if not File.exist? dir + Puppet.debug("Creating directory %s which did not exist" % dir) + Dir.mkdir(dir, 0700) + end + end + + # Generate the file + super + + # Ensure correct permissions + if target and user = @property_hash[:user] + File.chown(Puppet::Util.uid(user), nil, dir) + File.chown(Puppet::Util.uid(user), nil, @property_hash[:target]) + end + end end diff --git a/lib/puppet/type/ssh_authorized_key.rb b/lib/puppet/type/ssh_authorized_key.rb index 3a12e95ad..1db4a0ac3 100644 --- a/lib/puppet/type/ssh_authorized_key.rb +++ b/lib/puppet/type/ssh_authorized_key.rb @@ -27,11 +27,6 @@ module Puppet newproperty(:user) do desc "The user account in which the SSH key should be installed." - - def value=(value) - @resource[:target] = File.expand_path("~%s/.ssh/authorized_keys" % value) - super - end end newproperty(:target) do @@ -45,25 +40,6 @@ module Puppet defaultto do :absent end end - def generate - atype = Puppet::Type.type(:file) - target = self.should(:target) - dir = File.dirname(target) - user = should(:user) ? should(:user) : "root" - - rels = [] - - unless catalog.resource(:file, dir) - rels << atype.create(:name => dir, :ensure => :directory, :mode => 0700, :owner => user) - end - - unless catalog.resource(:file, target) - rels << atype.create(:name => target, :ensure => :present, :mode => 0600, :owner => user) - end - - rels - end - autorequire(:user) do if should(:user) should(:user) @@ -71,7 +47,7 @@ module Puppet end validate do - unless should(:target) + unless should(:target) or should(:user) raise Puppet::Error, "Attribute 'user' or 'target' is mandatory" end end -- cgit From 4ce7159baba4c637867c91519b5a3b16627dfca5 Mon Sep 17 00:00:00 2001 From: Andrew Shafer Date: Mon, 14 Jul 2008 19:54:52 -0600 Subject: Fail instead of log when rescuing remote file connections Issue 1397 one line fix, very simple --- lib/puppet/type/file/source.rb | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/type/file/source.rb b/lib/puppet/type/file/source.rb index f2704abb6..2514d3d1e 100755 --- a/lib/puppet/type/file/source.rb +++ b/lib/puppet/type/file/source.rb @@ -101,8 +101,7 @@ module Puppet begin desc = server.describe(path, @resource[:links]) rescue Puppet::Network::XMLRPCClientError => detail - self.err "Could not describe %s: %s" % [path, detail] - return nil + fail detail, "Could not describe %s: %s" % [path, detail] end return nil if desc == "" -- cgit From 0a0fcafa3e2405aa18ecc62d1e6dc69bbd9883a1 Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Thu, 17 Jul 2008 11:05:01 +1000 Subject: Fixed #1414 - Return code from waitpid now right shifted 8 bits --- lib/puppet/util.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/util.rb b/lib/puppet/util.rb index 560afe10b..94c96db0c 100644 --- a/lib/puppet/util.rb +++ b/lib/puppet/util.rb @@ -313,7 +313,7 @@ module Util $VERBOSE = oldverb if child_pid # Parent process executes this - child_status = Process.waitpid2(child_pid)[1] + child_status = (Process.waitpid2(child_pid)[1]).to_i >> 8 else # Child process executes this Process.setsid -- cgit From de6aec6e37edb9c575f9223686da03cea4063ad7 Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Thu, 17 Jul 2008 11:12:35 +1000 Subject: Fix Ticket 1426 - services on redhat are restarted again as far I see there have been a regression while refactoring the redhat service provider to user /sbin/service. This commit fixes this bug (1426) and service restarts are working again on redhat based systems. There are no tests, as I couldn't figure out how that should be tested. It seems that some restart logic is already tested, however it looks like not every single kind of provider is covered by tests, nor I see at the moment how I could do that. --- lib/puppet/provider/service/redhat.rb | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) (limited to 'lib') diff --git a/lib/puppet/provider/service/redhat.rb b/lib/puppet/provider/service/redhat.rb index e2d6ac947..48da577ec 100755 --- a/lib/puppet/provider/service/redhat.rb +++ b/lib/puppet/provider/service/redhat.rb @@ -50,10 +50,18 @@ Puppet::Type.type(:service).provide :redhat, :parent => :init do end def restart - if @resource[:hasrestart] == true + if @resource[:hasrestart] == :true service(@resource[:name], "restart") else - return false + super + end + end + + def status + if @resource[:hasstatus] == :true + service(@resource[:name], "status") + else + super end end -- cgit From 7fa7251e30dfefc95dda6ef82181d4346f36880d Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Wed, 16 Jul 2008 22:00:38 -0500 Subject: The mongrel-related tests now run without mongrel. Here were the main changes necessary: * Fixed the class loader so it only loads mongrel if it's available. * Fixed the test runner to skip example groups contained in non-runnable example groups. * Fixed the Mongrel tests to use quoted class names instead of constants, since the constants themselves would be absent. Signed-off-by: Luke Kanies --- lib/puppet/network/http.rb | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/puppet/network/http.rb b/lib/puppet/network/http.rb index 062c67c71..c219859b6 100644 --- a/lib/puppet/network/http.rb +++ b/lib/puppet/network/http.rb @@ -1,13 +1,15 @@ class Puppet::Network::HTTP def self.server_class_by_type(kind) - return Puppet::Network::HTTP::WEBrick if kind.to_sym == :webrick - if kind.to_sym == :mongrel + case kind.to_sym + when :webrick: + require 'puppet/network/http/webrick' + return Puppet::Network::HTTP::WEBrick + when :mongrel: raise ArgumentError, "Mongrel is not installed on this platform" unless Puppet.features.mongrel? + require 'puppet/network/http/mongrel' return Puppet::Network::HTTP::Mongrel + else + raise ArgumentError, "Unknown HTTP server name [#{kind}]" end - raise ArgumentError, "Unknown HTTP server name [#{kind}]" end end - -require 'puppet/network/http/webrick' -require 'puppet/network/http/mongrel' -- cgit From a0fa09f6ee562dd1b61fe56dd4b914419d641986 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Fri, 18 Jul 2008 00:12:01 -0500 Subject: Revert "Fixed #1201 - all external node attributes are converted to strings." This reverts commit ac7f59618a80b6a4aac777f6184e7fa6a0614079. The reason for this revert is that the problem never really existed; Ruby's true and false are always used unless you quote them. --- lib/puppet/indirector/node/exec.rb | 7 ------- 1 file changed, 7 deletions(-) (limited to 'lib') diff --git a/lib/puppet/indirector/node/exec.rb b/lib/puppet/indirector/node/exec.rb index 029a35c4f..52cbc370c 100644 --- a/lib/puppet/indirector/node/exec.rb +++ b/lib/puppet/indirector/node/exec.rb @@ -30,13 +30,6 @@ class Puppet::Node::Exec < Puppet::Indirector::Exec def create_node(name, result) node = Puppet::Node.new(name) set = false - if current = result[:parameters] - result[:parameters] = current.inject({}) do |strings, ary| - param, value = ary - strings[param] = value.to_s - strings - end - end [:parameters, :classes, :environment].each do |param| if value = result[param] node.send(param.to_s + "=", value) -- cgit From d8937acb8c9b108e61330cbac703a17b2eaba9b3 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Fri, 18 Jul 2008 00:54:59 -0500 Subject: You can now select the encoding format when transferring the catalog, with 'yaml' still being the default but 'marshal' being an option. This is because testing has shown drastic performance differences between the two, with up to 70% of compile time being spent in YAML code. Use the 'catalog_format' setting to choose your format, and the setting must be set on the client. Signed-off-by: Luke Kanies --- lib/puppet/defaults.rb | 5 ++++- lib/puppet/network/client/master.rb | 15 ++++++++++----- lib/puppet/network/handler/master.rb | 14 ++++++++------ 3 files changed, 22 insertions(+), 12 deletions(-) (limited to 'lib') diff --git a/lib/puppet/defaults.rb b/lib/puppet/defaults.rb index 5f71bb8b7..87ccd62f6 100644 --- a/lib/puppet/defaults.rb +++ b/lib/puppet/defaults.rb @@ -416,7 +416,10 @@ module Puppet :ca_server => ["$server", "The server to use for certificate authority requests. It's a separate server because it cannot and does not need to horizontally scale."], - :ca_port => ["$masterport", "The port to use for the certificate authority."] + :ca_port => ["$masterport", "The port to use for the certificate authority."], + :catalog_format => ["yaml", "What format to use to dump the catalog. Only supports + 'marshal' and 'yaml'. Only matters on the client, since it asks the server + for a specific format."] ) self.setdefaults(:filebucket, diff --git a/lib/puppet/network/client/master.rb b/lib/puppet/network/client/master.rb index 0de3a117b..2da6cf890 100644 --- a/lib/puppet/network/client/master.rb +++ b/lib/puppet/network/client/master.rb @@ -143,15 +143,20 @@ class Puppet::Network::Client::Master < Puppet::Network::Client # If we can't retrieve the catalog, just return, which will either # fail, or use the in-memory catalog. - unless yaml_objects = get_actual_config(facts) + unless marshalled_objects = get_actual_config(facts) use_cached_config(true) return end begin - objects = YAML.load(yaml_objects) + case Puppet[:catalog_format] + when "marshal": objects = Marshal.load(marshalled_objects) + when "yaml": objects = YAML.load(marshalled_objects) + else + raise "Invalid catalog format '%s'" % Puppet[:catalog_format] + end rescue => detail - msg = "Configuration could not be translated from yaml" + msg = "Configuration could not be translated from %s" % Puppet[:catalog_format] msg += "; using cached catalog" if use_cached_config(true) Puppet.warning msg return @@ -175,7 +180,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client end if ! @catalog.from_cache - self.cache(yaml_objects) + self.cache(marshalled_objects) end # Keep the state database up to date. @@ -442,7 +447,7 @@ class Puppet::Network::Client::Master < Puppet::Network::Client benchmark(:debug, "Retrieved catalog") do # error handling for this is done in the network client begin - textobjects = @driver.getconfig(textfacts, "yaml") + textobjects = @driver.getconfig(textfacts, Puppet[:catalog_format]) begin textobjects = CGI.unescape(textobjects) rescue => detail diff --git a/lib/puppet/network/handler/master.rb b/lib/puppet/network/handler/master.rb index a050b089b..9682c460e 100644 --- a/lib/puppet/network/handler/master.rb +++ b/lib/puppet/network/handler/master.rb @@ -64,7 +64,14 @@ class Puppet::Network::Handler catalog = Puppet::Node::Catalog.find(client) - return translate(catalog.extract) + case format + when "yaml": + return CGI.escape(catalog.extract.to_yaml(:UseBlock => true)) + when "marshal": + return CGI.escape(Marshal.dump(catalog.extract)) + else + raise "Invalid markup format '%s'" % format + end end # @@ -90,11 +97,6 @@ class Puppet::Network::Handler # Translate our configuration appropriately for sending back to a client. def translate(config) - if local? - config - else - CGI.escape(config.to_yaml(:UseBlock => true)) - end end end end -- cgit From ebb219e496682862ac98d382afe014cf1c763f2f Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Fri, 18 Jul 2008 17:51:25 -0500 Subject: Fixed all of the fileserving termini so they use indirection requests. This looks like a much larger commit than it is -- it doesn't change any behaviour at all, it just adds some integration tests (which expose the problem) and then switches from an ad-hoc api to a request-based api. Signed-off-by: Luke Kanies --- lib/puppet/file_serving/terminus_helper.rb | 8 ++++---- lib/puppet/indirector/direct_file_server.rb | 2 +- lib/puppet/indirector/file_server.rb | 28 ++++++++++++++-------------- lib/puppet/indirector/module_files.rb | 28 ++++++++++++++-------------- 4 files changed, 33 insertions(+), 33 deletions(-) (limited to 'lib') diff --git a/lib/puppet/file_serving/terminus_helper.rb b/lib/puppet/file_serving/terminus_helper.rb index d465aa493..e5da0e29f 100644 --- a/lib/puppet/file_serving/terminus_helper.rb +++ b/lib/puppet/file_serving/terminus_helper.rb @@ -8,11 +8,11 @@ require 'puppet/file_serving/fileset' # Define some common methods for FileServing termini. module Puppet::FileServing::TerminusHelper # Create model instances for all files in a fileset. - def path2instances(key, path, options = {}) - args = [:links, :ignore, :recurse].inject({}) { |hash, param| hash[param] = options[param] if options[param]; hash } + def path2instances(request, path) + args = [:links, :ignore, :recurse].inject({}) { |hash, param| hash[param] = request.options[param] if request.options[param]; hash } Puppet::FileServing::Fileset.new(path, args).files.collect do |file| - inst = model.new(File.join(key, file), :path => path, :relative_path => file) - inst.links = options[:links] if options[:links] + inst = model.new(File.join(request.key, file), :path => path, :relative_path => file) + inst.links = request.options[:links] if request.options[:links] inst end end diff --git a/lib/puppet/indirector/direct_file_server.rb b/lib/puppet/indirector/direct_file_server.rb index 1711356f9..b3b4886f3 100644 --- a/lib/puppet/indirector/direct_file_server.rb +++ b/lib/puppet/indirector/direct_file_server.rb @@ -22,6 +22,6 @@ class Puppet::Indirector::DirectFileServer < Puppet::Indirector::Terminus def search(request) uri = key2uri(request.key) return nil unless FileTest.exists?(uri.path) - path2instances(request.key, uri.path, request.options) + path2instances(request, uri.path) end end diff --git a/lib/puppet/indirector/file_server.rb b/lib/puppet/indirector/file_server.rb index 2eb323d46..b0df7ff5d 100644 --- a/lib/puppet/indirector/file_server.rb +++ b/lib/puppet/indirector/file_server.rb @@ -14,28 +14,28 @@ class Puppet::Indirector::FileServer < Puppet::Indirector::Terminus include Puppet::FileServing::TerminusHelper # Is the client authorized to perform this action? - def authorized?(method, key, options = {}) - return false unless [:find, :search].include?(method) + def authorized?(request) + return false unless [:find, :search].include?(request.method) - uri = key2uri(key) + uri = key2uri(request.key) - configuration.authorized?(uri.path, :node => options[:node], :ipaddress => options[:ipaddress]) + configuration.authorized?(uri.path, :node => request.node, :ipaddress => request.ip) end # Find our key using the fileserver. - def find(key, options = {}) - return nil unless path = find_path(key, options) - result = model.new(key, :path => path) - result.links = options[:links] if options[:links] + def find(request) + return nil unless path = find_path(request) + result = model.new(request.key, :path => path) + result.links = request.options[:links] if request.options[:links] return result end # Search for files. This returns an array rather than a single # file. - def search(key, options = {}) - return nil unless path = find_path(key, options) + def search(request) + return nil unless path = find_path(request) - path2instances(key, path, options) + path2instances(request, path) end private @@ -46,10 +46,10 @@ class Puppet::Indirector::FileServer < Puppet::Indirector::Terminus end # Find our path; used by :find and :search. - def find_path(key, options) - uri = key2uri(key) + def find_path(request) + uri = key2uri(request.key) - return nil unless path = configuration.file_path(uri.path, :node => options[:node]) + return nil unless path = configuration.file_path(uri.path, :node => request.node) return path end diff --git a/lib/puppet/indirector/module_files.rb b/lib/puppet/indirector/module_files.rb index 84286d8a5..cf5c29cab 100644 --- a/lib/puppet/indirector/module_files.rb +++ b/lib/puppet/indirector/module_files.rb @@ -14,24 +14,24 @@ class Puppet::Indirector::ModuleFiles < Puppet::Indirector::Terminus include Puppet::FileServing::TerminusHelper # Is the client allowed access to this key with this method? - def authorized?(method, key, options = {}) - return false unless [:find, :search].include?(method) + def authorized?(request) + return false unless [:find, :search].include?(request.method) - uri = key2uri(key) + uri = key2uri(request.key) # Make sure our file path starts with /modules, so that we authorize # against the 'modules' mount. path = uri.path =~ /^\/modules/ ? uri.path : "/modules" + uri.path - configuration.authorized?(path, :node => options[:node], :ipaddress => options[:ipaddress]) + configuration.authorized?(path, :node => request.node, :ipaddress => request.ip) end # Find our key in a module. - def find(key, options = {}) - return nil unless path = find_path(key, options) + def find(request) + return nil unless path = find_path(request) - result = model.new(key, :path => path) - result.links = options[:links] if options[:links] + result = model.new(request.key, :path => path) + result.links = request.options[:links] if request.options[:links] return result end @@ -41,9 +41,9 @@ class Puppet::Indirector::ModuleFiles < Puppet::Indirector::Terminus end # Search for a list of files. - def search(key, options = {}) - return nil unless path = find_path(key, options) - path2instances(key, path, options) + def search(request) + return nil unless path = find_path(request) + path2instances(request, path) end private @@ -63,15 +63,15 @@ class Puppet::Indirector::ModuleFiles < Puppet::Indirector::Terminus end # The abstracted method for turning a key into a path; used by both :find and :search. - def find_path(key, options) - uri = key2uri(key) + def find_path(request) + uri = key2uri(request.key) # Strip off /modules if it's there -- that's how requests get routed to this terminus. # Also, strip off the leading slash if present. module_name, relative_path = uri.path.sub(/^\/modules\b/, '').sub(%r{^/}, '').split(File::Separator, 2) # And use the environment to look up the module. - return nil unless mod = find_module(module_name, options[:node]) + return nil unless mod = find_module(module_name, request.node) path = File.join(mod.files, relative_path) -- cgit From f16da4250c16aeab932a81a349df059c69d7ee23 Mon Sep 17 00:00:00 2001 From: Brett Lentz Date: Fri, 18 Jul 2008 10:05:02 -0700 Subject: Merging fsweetser's selinux patch against 0.24.4 --- lib/puppet/provider/selboolean/getsetsebool.rb | 47 ++++++++ lib/puppet/provider/selmodule/semodule.rb | 143 +++++++++++++++++++++++++ lib/puppet/type/file.rb | 1 + lib/puppet/type/file/selcontext.rb | 96 +++++++++++++++++ lib/puppet/type/selboolean.rb | 29 +++++ lib/puppet/type/selmodule.rb | 50 +++++++++ 6 files changed, 366 insertions(+) create mode 100644 lib/puppet/provider/selboolean/getsetsebool.rb create mode 100644 lib/puppet/provider/selmodule/semodule.rb create mode 100644 lib/puppet/type/file/selcontext.rb create mode 100644 lib/puppet/type/selboolean.rb create mode 100644 lib/puppet/type/selmodule.rb (limited to 'lib') diff --git a/lib/puppet/provider/selboolean/getsetsebool.rb b/lib/puppet/provider/selboolean/getsetsebool.rb new file mode 100644 index 000000000..4614c6c38 --- /dev/null +++ b/lib/puppet/provider/selboolean/getsetsebool.rb @@ -0,0 +1,47 @@ +Puppet::Type.type(:selboolean).provide(:getsetsebool) do + desc "Manage SELinux booleans using the getsebool and setsebool binaries." + + commands :getsebool => "/usr/sbin/getsebool" + commands :setsebool => "/usr/sbin/setsebool" + + def value + self.debug "Retrieving value of selboolean #{@resource[:name]}" + + status = getsebool(@resource[:name]) + + if status =~ / off$/ then + return :off + elsif status =~ / on$/ then + return :on + else + status.chomp! + raise Puppet::Error, "Invalid response '%s' returned from getsebool" % [status] + end + end + + def value=(new) + persist = "" + if @resource[:persistent] == :true + self.debug "Enabling persistence" + persist = "-P" + end + execoutput("#{command(:setsebool)} #{persist} #{@resource[:name]} #{new}") + return :file_changed + end + + # Required workaround, since SELinux policy prevents setsebool + # from writing to any files, even tmp, preventing the standard + # 'setsebool("...")' construct from working. + + def execoutput (cmd) + output = '' + begin + execpipe(cmd) do |out| + output = out.readlines.join('').chomp! + end + rescue Puppet::ExecutionFailure + raise Puppet::ExecutionFailure, output.split("\n")[0] + end + return output + end +end diff --git a/lib/puppet/provider/selmodule/semodule.rb b/lib/puppet/provider/selmodule/semodule.rb new file mode 100644 index 000000000..498136691 --- /dev/null +++ b/lib/puppet/provider/selmodule/semodule.rb @@ -0,0 +1,143 @@ +Puppet::Type.type(:selmodule).provide(:semodule) do + desc "Manage SELinux policy modules using the semodule binary." + + commands :semodule => "/usr/sbin/semodule" + + def create + begin + execoutput("#{command(:semodule)} --install #{selmod_name_to_filename}") + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not load policy module: %s" % [detail]; + end + return :true + end + + def destroy + begin + execoutput("#{command(:semodule)} --remove #{@resource[:name]}") + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not remove policy module: %s" % [detail]; + end + end + + def exists? + self.debug "Checking for module #{@resource[:name]}" + execpipe("#{command(:semodule)} --list") do |out| + out.each do |line| + if line =~ /#{@resource[:name]}\b/ + return :true + end + end + end + return nil + end + + def syncversion + self.debug "Checking syncversion on #{@resource[:name]}" + + loadver = selmodversion_loaded + + if(loadver) then + filever = selmodversion_file + if (filever == loadver) then + return :true + end + end + return :false + end + + def syncversion= (dosync) + begin + execoutput("#{command(:semodule)} --upgrade #{selmod_name_to_filename}") + rescue Puppet::ExecutionFailure => detail + raise Puppet::Error, "Could not upgrade policy module: %s" % [detail]; + end + end + + # Helper functions + + def execoutput (cmd) + output = '' + begin + execpipe(cmd) do |out| + output = out.readlines.join('').chomp! + end + rescue Puppet::ExecutionFailure + raise Puppet::ExecutionFailure, output.split("\n")[0] + end + return output + end + + def selmod_name_to_filename + if @resource[:selmodulepath] + return @resource[:selmodulepath] + else + return "#{@resource[:selmoduledir]}/#{@resource[:name]}.pp" + end + end + + def selmod_readnext (handle) + len = handle.read(4).unpack('L')[0] + return handle.read(len) + end + + def selmodversion_file + magic = 0xF97CFF8F + + filename = selmod_name_to_filename + mod = File.new(filename, "r") + + (hdr, ver, numsec) = mod.read(12).unpack('LLL') + + if hdr != magic + raise Puppet::Error, "Found #{hdr} instead of magic #{magic} in #{filename}" + end + + if ver != 1 + raise Puppet::Error, "Unknown policy file version #{ver} in #{filename}" + end + + # Read through (and throw away) the file section offsets, and also + # the magic header for the first section. + + mod.read((numsec + 1) * 4) + + ## Section 1 should be "SE Linux Module" + + selmod_readnext(mod) + selmod_readnext(mod) + + # Skip past the section headers + mod.read(14) + + # Module name + selmod_readnext(mod) + + # At last! the version + + v = selmod_readnext(mod) + + self.debug "file version #{v}" + return v + end + + def selmodversion_loaded + lines = () + begin + execpipe("#{command(:semodule)} --list") do |output| + lines = output.readlines + lines.each do |line| + line.chomp! + bits = line.split + if bits[0] == @resource[:name] then + self.debug "load version #{bits[1]}" + return bits[1] + end + end + end + rescue Puppet::ExecutionFailure + raise Puppet::ExecutionFailure, "Could not list policy modules: %s" % [lines.join(' ').chomp!] + end + return nil + end +end diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb index 3518e8bb3..cd1528e73 100644 --- a/lib/puppet/type/file.rb +++ b/lib/puppet/type/file.rb @@ -1148,4 +1148,5 @@ module Puppet require 'puppet/type/file/group' require 'puppet/type/file/mode' require 'puppet/type/file/type' + require 'puppet/type/file/selcontext' # SELinux file context end diff --git a/lib/puppet/type/file/selcontext.rb b/lib/puppet/type/file/selcontext.rb new file mode 100644 index 000000000..f36695075 --- /dev/null +++ b/lib/puppet/type/file/selcontext.rb @@ -0,0 +1,96 @@ +# Manage SELinux context of files. +# +# This code actually manages three pieces of data in the context. +# +# [root@delenn files]# ls -dZ / +# drwxr-xr-x root root system_u:object_r:root_t / +# +# The context of '/' here is 'system_u:object_r:root_t'. This is +# three seperate fields: +# +# system_u is the user context +# object_r is the role context +# root_t is the type context +# +# All three of these fields are returned in a single string by the +# output of the stat command, but set individually with the chcon +# command. This allows the user to specify a subset of the three +# values while leaving the others alone. +# +# See http://www.nsa.gov/selinux/ for complete docs on SELinux. + +module Puppet + class SELFileContext < Puppet::Property + + def retrieve + unless @resource.stat(false) + return :absent + end + context = `stat -c %C #{@resource[:path]}` + context.chomp! + if context == "unlabeled" + return nil + end + unless context =~ /^[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/ + raise Puppet::Error, "Invalid output from stat: #{context}" + end + bits = context.split(':') + ret = { + :seluser => bits[0], + :selrole => bits[1], + :seltype => bits[2] + } + return ret[name] + end + + def sync + unless @resource.stat(false) + stat = @resource.stat(true) + unless stat + return nil + end + end + + flag = '' + + case name + when :seluser + flag = "-u" + when :selrole + flag = "-r" + when :seltype + flag = "-t" + else + raise Puppet::Error, "Invalid SELinux file context component: #{name}" + end + + self.debug "Running chcon #{flag} #{@should} #{@resource[:path]}" + retval = system("chcon #{flag} #{@should} #{@resource[:path]}") + unless retval + error = Puppet::Error.new("failed to chcon %s" % [@resource[:path]]) + raise error + end + return :file_changed + end + end + + Puppet.type(:file).newproperty(:seluser, :parent => Puppet::SELFileContext) do + desc "What the SELinux User context of the file should be." + + @event = :file_changed + end + + Puppet.type(:file).newproperty(:selrole, :parent => Puppet::SELFileContext) do + desc "What the SELinux Role context of the file should be." + + @event = :file_changed + end + + Puppet.type(:file).newproperty(:seltype, :parent => Puppet::SELFileContext) do + desc "What the SELinux Type context of the file should be." + + @event = :file_changed + end + +end + diff --git a/lib/puppet/type/selboolean.rb b/lib/puppet/type/selboolean.rb new file mode 100644 index 000000000..d12dd3bcb --- /dev/null +++ b/lib/puppet/type/selboolean.rb @@ -0,0 +1,29 @@ +# +# Simple module for manageing SELinux booleans +# + +module Puppet + newtype(:selboolean) do + @doc = "Enable or disable SELinux booleans." + + newparam(:name) do + desc "The name of the SELinux boolean to be managed." + isnamevar + end + + newproperty(:value) do + desc "Whether the the SELinux boolean should be enabled or disabled. Possible values are ``on`` or ``off``." + newvalue(:on) + newvalue(:off) + end + + newparam(:persistent) do + desc "If set true, SELinux booleans will be written to disk and persist accross reboots." + + defaultto :false + newvalues(:true, :false) + end + + end +end + diff --git a/lib/puppet/type/selmodule.rb b/lib/puppet/type/selmodule.rb new file mode 100644 index 000000000..1f02912ad --- /dev/null +++ b/lib/puppet/type/selmodule.rb @@ -0,0 +1,50 @@ +# +# Simple module for manageing SELinux policy modules +# + +Puppet::Type.newtype(:selmodule) do + @doc = "Enable or disable SELinux policy modules." + + ensurable + + newparam(:name) do + desc "The name of the SELinux policy to be managed." + isnamevar + end + + newparam(:selmoduledir) do + + desc "The directory to look for the compiled pp module file in. + Currently defaults to /usr/share/selinux/targeted" + + defaultto "/usr/share/selinux/targeted" + end + + newparam(:selmodulepath) do + + desc "The full path in which to look for the compiled pp + module file in. You only need to use this if the module file + is not in the directory pointed at by selmoduledir." + + end + + newproperty(:syncversion) do + + desc "If set to 'true', the policy will be reloaded if the + version found in the on-disk file differs from the loaded + version. If set to 'false' (the default) the the only check + that will be made is if the policy is loaded at all or not." + + newvalue(:true) + newvalue(:false) + end + + autorequire(:file) do + if self[:selmodulepath] + [self[:selmodulepath]] + else + ["#{self[:selmoduledir]}/#{self[:name]}.pp"] + end + end +end + -- cgit From 686ba4d4c21f6f1e073bd845492f2fe3cb4837a2 Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Sun, 20 Jul 2008 16:11:56 +1000 Subject: Revert "Merging fsweetser's selinux patch against 0.24.4" This reverts commit f16da4250c16aeab932a81a349df059c69d7ee23. --- lib/puppet/provider/selboolean/getsetsebool.rb | 47 -------- lib/puppet/provider/selmodule/semodule.rb | 143 ------------------------- lib/puppet/type/file.rb | 1 - lib/puppet/type/file/selcontext.rb | 96 ----------------- lib/puppet/type/selboolean.rb | 29 ----- lib/puppet/type/selmodule.rb | 50 --------- 6 files changed, 366 deletions(-) delete mode 100644 lib/puppet/provider/selboolean/getsetsebool.rb delete mode 100644 lib/puppet/provider/selmodule/semodule.rb delete mode 100644 lib/puppet/type/file/selcontext.rb delete mode 100644 lib/puppet/type/selboolean.rb delete mode 100644 lib/puppet/type/selmodule.rb (limited to 'lib') diff --git a/lib/puppet/provider/selboolean/getsetsebool.rb b/lib/puppet/provider/selboolean/getsetsebool.rb deleted file mode 100644 index 4614c6c38..000000000 --- a/lib/puppet/provider/selboolean/getsetsebool.rb +++ /dev/null @@ -1,47 +0,0 @@ -Puppet::Type.type(:selboolean).provide(:getsetsebool) do - desc "Manage SELinux booleans using the getsebool and setsebool binaries." - - commands :getsebool => "/usr/sbin/getsebool" - commands :setsebool => "/usr/sbin/setsebool" - - def value - self.debug "Retrieving value of selboolean #{@resource[:name]}" - - status = getsebool(@resource[:name]) - - if status =~ / off$/ then - return :off - elsif status =~ / on$/ then - return :on - else - status.chomp! - raise Puppet::Error, "Invalid response '%s' returned from getsebool" % [status] - end - end - - def value=(new) - persist = "" - if @resource[:persistent] == :true - self.debug "Enabling persistence" - persist = "-P" - end - execoutput("#{command(:setsebool)} #{persist} #{@resource[:name]} #{new}") - return :file_changed - end - - # Required workaround, since SELinux policy prevents setsebool - # from writing to any files, even tmp, preventing the standard - # 'setsebool("...")' construct from working. - - def execoutput (cmd) - output = '' - begin - execpipe(cmd) do |out| - output = out.readlines.join('').chomp! - end - rescue Puppet::ExecutionFailure - raise Puppet::ExecutionFailure, output.split("\n")[0] - end - return output - end -end diff --git a/lib/puppet/provider/selmodule/semodule.rb b/lib/puppet/provider/selmodule/semodule.rb deleted file mode 100644 index 498136691..000000000 --- a/lib/puppet/provider/selmodule/semodule.rb +++ /dev/null @@ -1,143 +0,0 @@ -Puppet::Type.type(:selmodule).provide(:semodule) do - desc "Manage SELinux policy modules using the semodule binary." - - commands :semodule => "/usr/sbin/semodule" - - def create - begin - execoutput("#{command(:semodule)} --install #{selmod_name_to_filename}") - rescue Puppet::ExecutionFailure => detail - raise Puppet::Error, "Could not load policy module: %s" % [detail]; - end - return :true - end - - def destroy - begin - execoutput("#{command(:semodule)} --remove #{@resource[:name]}") - rescue Puppet::ExecutionFailure => detail - raise Puppet::Error, "Could not remove policy module: %s" % [detail]; - end - end - - def exists? - self.debug "Checking for module #{@resource[:name]}" - execpipe("#{command(:semodule)} --list") do |out| - out.each do |line| - if line =~ /#{@resource[:name]}\b/ - return :true - end - end - end - return nil - end - - def syncversion - self.debug "Checking syncversion on #{@resource[:name]}" - - loadver = selmodversion_loaded - - if(loadver) then - filever = selmodversion_file - if (filever == loadver) then - return :true - end - end - return :false - end - - def syncversion= (dosync) - begin - execoutput("#{command(:semodule)} --upgrade #{selmod_name_to_filename}") - rescue Puppet::ExecutionFailure => detail - raise Puppet::Error, "Could not upgrade policy module: %s" % [detail]; - end - end - - # Helper functions - - def execoutput (cmd) - output = '' - begin - execpipe(cmd) do |out| - output = out.readlines.join('').chomp! - end - rescue Puppet::ExecutionFailure - raise Puppet::ExecutionFailure, output.split("\n")[0] - end - return output - end - - def selmod_name_to_filename - if @resource[:selmodulepath] - return @resource[:selmodulepath] - else - return "#{@resource[:selmoduledir]}/#{@resource[:name]}.pp" - end - end - - def selmod_readnext (handle) - len = handle.read(4).unpack('L')[0] - return handle.read(len) - end - - def selmodversion_file - magic = 0xF97CFF8F - - filename = selmod_name_to_filename - mod = File.new(filename, "r") - - (hdr, ver, numsec) = mod.read(12).unpack('LLL') - - if hdr != magic - raise Puppet::Error, "Found #{hdr} instead of magic #{magic} in #{filename}" - end - - if ver != 1 - raise Puppet::Error, "Unknown policy file version #{ver} in #{filename}" - end - - # Read through (and throw away) the file section offsets, and also - # the magic header for the first section. - - mod.read((numsec + 1) * 4) - - ## Section 1 should be "SE Linux Module" - - selmod_readnext(mod) - selmod_readnext(mod) - - # Skip past the section headers - mod.read(14) - - # Module name - selmod_readnext(mod) - - # At last! the version - - v = selmod_readnext(mod) - - self.debug "file version #{v}" - return v - end - - def selmodversion_loaded - lines = () - begin - execpipe("#{command(:semodule)} --list") do |output| - lines = output.readlines - lines.each do |line| - line.chomp! - bits = line.split - if bits[0] == @resource[:name] then - self.debug "load version #{bits[1]}" - return bits[1] - end - end - end - rescue Puppet::ExecutionFailure - raise Puppet::ExecutionFailure, "Could not list policy modules: %s" % [lines.join(' ').chomp!] - end - return nil - end -end diff --git a/lib/puppet/type/file.rb b/lib/puppet/type/file.rb index cd1528e73..3518e8bb3 100644 --- a/lib/puppet/type/file.rb +++ b/lib/puppet/type/file.rb @@ -1148,5 +1148,4 @@ module Puppet require 'puppet/type/file/group' require 'puppet/type/file/mode' require 'puppet/type/file/type' - require 'puppet/type/file/selcontext' # SELinux file context end diff --git a/lib/puppet/type/file/selcontext.rb b/lib/puppet/type/file/selcontext.rb deleted file mode 100644 index f36695075..000000000 --- a/lib/puppet/type/file/selcontext.rb +++ /dev/null @@ -1,96 +0,0 @@ -# Manage SELinux context of files. -# -# This code actually manages three pieces of data in the context. -# -# [root@delenn files]# ls -dZ / -# drwxr-xr-x root root system_u:object_r:root_t / -# -# The context of '/' here is 'system_u:object_r:root_t'. This is -# three seperate fields: -# -# system_u is the user context -# object_r is the role context -# root_t is the type context -# -# All three of these fields are returned in a single string by the -# output of the stat command, but set individually with the chcon -# command. This allows the user to specify a subset of the three -# values while leaving the others alone. -# -# See http://www.nsa.gov/selinux/ for complete docs on SELinux. - -module Puppet - class SELFileContext < Puppet::Property - - def retrieve - unless @resource.stat(false) - return :absent - end - context = `stat -c %C #{@resource[:path]}` - context.chomp! - if context == "unlabeled" - return nil - end - unless context =~ /^[a-z0-9_]+:[a-z0-9_]+:[a-z0-9_]+/ - raise Puppet::Error, "Invalid output from stat: #{context}" - end - bits = context.split(':') - ret = { - :seluser => bits[0], - :selrole => bits[1], - :seltype => bits[2] - } - return ret[name] - end - - def sync - unless @resource.stat(false) - stat = @resource.stat(true) - unless stat - return nil - end - end - - flag = '' - - case name - when :seluser - flag = "-u" - when :selrole - flag = "-r" - when :seltype - flag = "-t" - else - raise Puppet::Error, "Invalid SELinux file context component: #{name}" - end - - self.debug "Running chcon #{flag} #{@should} #{@resource[:path]}" - retval = system("chcon #{flag} #{@should} #{@resource[:path]}") - unless retval - error = Puppet::Error.new("failed to chcon %s" % [@resource[:path]]) - raise error - end - return :file_changed - end - end - - Puppet.type(:file).newproperty(:seluser, :parent => Puppet::SELFileContext) do - desc "What the SELinux User context of the file should be." - - @event = :file_changed - end - - Puppet.type(:file).newproperty(:selrole, :parent => Puppet::SELFileContext) do - desc "What the SELinux Role context of the file should be." - - @event = :file_changed - end - - Puppet.type(:file).newproperty(:seltype, :parent => Puppet::SELFileContext) do - desc "What the SELinux Type context of the file should be." - - @event = :file_changed - end - -end - diff --git a/lib/puppet/type/selboolean.rb b/lib/puppet/type/selboolean.rb deleted file mode 100644 index d12dd3bcb..000000000 --- a/lib/puppet/type/selboolean.rb +++ /dev/null @@ -1,29 +0,0 @@ -# -# Simple module for manageing SELinux booleans -# - -module Puppet - newtype(:selboolean) do - @doc = "Enable or disable SELinux booleans." - - newparam(:name) do - desc "The name of the SELinux boolean to be managed." - isnamevar - end - - newproperty(:value) do - desc "Whether the the SELinux boolean should be enabled or disabled. Possible values are ``on`` or ``off``." - newvalue(:on) - newvalue(:off) - end - - newparam(:persistent) do - desc "If set true, SELinux booleans will be written to disk and persist accross reboots." - - defaultto :false - newvalues(:true, :false) - end - - end -end - diff --git a/lib/puppet/type/selmodule.rb b/lib/puppet/type/selmodule.rb deleted file mode 100644 index 1f02912ad..000000000 --- a/lib/puppet/type/selmodule.rb +++ /dev/null @@ -1,50 +0,0 @@ -# -# Simple module for manageing SELinux policy modules -# - -Puppet::Type.newtype(:selmodule) do - @doc = "Enable or disable SELinux policy modules." - - ensurable - - newparam(:name) do - desc "The name of the SELinux policy to be managed." - isnamevar - end - - newparam(:selmoduledir) do - - desc "The directory to look for the compiled pp module file in. - Currently defaults to /usr/share/selinux/targeted" - - defaultto "/usr/share/selinux/targeted" - end - - newparam(:selmodulepath) do - - desc "The full path in which to look for the compiled pp - module file in. You only need to use this if the module file - is not in the directory pointed at by selmoduledir." - - end - - newproperty(:syncversion) do - - desc "If set to 'true', the policy will be reloaded if the - version found in the on-disk file differs from the loaded - version. If set to 'false' (the default) the the only check - that will be made is if the policy is loaded at all or not." - - newvalue(:true) - newvalue(:false) - end - - autorequire(:file) do - if self[:selmodulepath] - [self[:selmodulepath]] - else - ["#{self[:selmoduledir]}/#{self[:name]}.pp"] - end - end -end - -- cgit From d9aa5ab68fb3196f5db526050c440c470b55a5f6 Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Mon, 21 Jul 2008 13:16:08 -0500 Subject: Fixing a cert test to pass on Darwin. Darwin has a case-insensitive FS, so the test was failing because it was specifically testing case sensitivity. Signed-off-by: Luke Kanies --- lib/puppet/sslcertificates/support.rb | 1 + 1 file changed, 1 insertion(+) (limited to 'lib') diff --git a/lib/puppet/sslcertificates/support.rb b/lib/puppet/sslcertificates/support.rb index 95f15f0a8..bab250d47 100644 --- a/lib/puppet/sslcertificates/support.rb +++ b/lib/puppet/sslcertificates/support.rb @@ -28,6 +28,7 @@ module Puppet::SSLCertificates::Support # Define the reading method. define_method(reader) do + p Puppet[param] return nil unless FileTest.exists?(Puppet[param]) or rename_files_with_uppercase(Puppet[param]) begin -- cgit From ff36832ec1837f300e57bfd37ca877c356e24a8b Mon Sep 17 00:00:00 2001 From: Luke Kanies Date: Mon, 21 Jul 2008 13:58:33 -0500 Subject: Fixing the renaming code to skip missing directories. I couldn't get this to fail in a targeted regression test, but if it's not working, it causes a failure in the webrick tests. Signed-off-by: Luke Kanies --- lib/puppet/sslcertificates/support.rb | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/sslcertificates/support.rb b/lib/puppet/sslcertificates/support.rb index bab250d47..d95944adc 100644 --- a/lib/puppet/sslcertificates/support.rb +++ b/lib/puppet/sslcertificates/support.rb @@ -28,7 +28,6 @@ module Puppet::SSLCertificates::Support # Define the reading method. define_method(reader) do - p Puppet[param] return nil unless FileTest.exists?(Puppet[param]) or rename_files_with_uppercase(Puppet[param]) begin @@ -129,6 +128,10 @@ module Puppet::SSLCertificates::Support def rename_files_with_uppercase(file) dir = File.dirname(file) short = File.basename(file) + + # If the dir isn't present, we clearly don't have the file. + #return nil unless FileTest.directory?(dir) + raise ArgumentError, "Tried to fix SSL files to a file containing uppercase" unless short.downcase == short real_file = Dir.entries(dir).reject { |f| f =~ /^\./ }.find do |other| other.downcase == short -- cgit From 8f5800f0608dff46407cb5f23ee73f314fe051e8 Mon Sep 17 00:00:00 2001 From: James Turnbull Date: Tue, 22 Jul 2008 16:00:54 +1000 Subject: Fixes #1445 and #1426 --- lib/puppet/provider/service/redhat.rb | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'lib') diff --git a/lib/puppet/provider/service/redhat.rb b/lib/puppet/provider/service/redhat.rb index 48da577ec..3fad8bcfe 100755 --- a/lib/puppet/provider/service/redhat.rb +++ b/lib/puppet/provider/service/redhat.rb @@ -59,7 +59,11 @@ Puppet::Type.type(:service).provide :redhat, :parent => :init do def status if @resource[:hasstatus] == :true - service(@resource[:name], "status") + begin + service(@resource[:name], "status") + rescue + return :stopped + end else super end -- cgit