diff options
Diffstat (limited to 'lib/puppet/file_serving/mount.rb')
-rw-r--r-- | lib/puppet/file_serving/mount.rb | 180 |
1 files changed, 180 insertions, 0 deletions
diff --git a/lib/puppet/file_serving/mount.rb b/lib/puppet/file_serving/mount.rb new file mode 100644 index 000000000..719c30b16 --- /dev/null +++ b/lib/puppet/file_serving/mount.rb @@ -0,0 +1,180 @@ +# +# Created by Luke Kanies on 2007-10-16. +# Copyright (c) 2007. All rights reserved. + +require 'puppet/network/authstore' +require 'puppet/util/logging' +require 'puppet/file_serving' +require 'puppet/file_serving/metadata' +require 'puppet/file_serving/content' + +# Broker access to the filesystem, converting local URIs into metadata +# or content objects. +class Puppet::FileServing::Mount < Puppet::Network::AuthStore + include Puppet::Util::Logging + + attr_reader :name + + @@syncs = {} + + @@files = {} + + # Return a new mount with the same properties as +self+, except + # with a different name and path. + def copy(name, path) + result = self.clone + result.path = path + result.instance_variable_set(:@name, name) + return result + end + + # Return a content instance for a given file. + def content(short_file, client = nil) + file_instance(Puppet::FileServing::Content, short_file, client) + end + + # Return a fully qualified path, given a short path and + # possibly a client name. + def file_path(short, client = nil) + p = path(client) + raise ArgumentError.new("Mounts without paths are not usable") unless p + File.join(p, short) + end + + # Create out object. It must have a name. + def initialize(name, path = nil) + unless name =~ %r{^[-\w]+$} + raise ArgumentError, "Invalid mount name format '%s'" % name + end + @name = name + + if path + self.path = path + else + @path = nil + end + + super() + end + + # Return a metadata instance with the appropriate information provided. + def metadata(short_file, client = nil) + file_instance(Puppet::FileServing::Metadata, short_file, client) + end + + # Return the path as appropriate, expanding as necessary. + def path(client = nil) + if expandable? + return expand(@path, client) + else + return @path + end + end + + # Set the path. + def path=(path) + # FIXME: For now, just don't validate paths with replacement + # patterns in them. + if path =~ /%./ + # Mark that we're expandable. + @expandable = true + else + unless FileTest.exists?(path) + raise ArgumentError, "%s does not exist" % path + end + unless FileTest.directory?(path) + raise ArgumentError, "%s is not a directory" % path + end + unless FileTest.readable?(path) + raise ArgumentError, "%s is not readable" % path + end + @expandable = false + end + @path = path + end + + def sync(path) + @@syncs[path] ||= Sync.new + @@syncs[path] + end + + def to_s + "mount[%s]" % @name + end + + # Verify our configuration is valid. This should really check to + # make sure at least someone will be allowed, but, eh. + def valid? + if name == MODULES + return @path.nil? + else + return ! @path.nil? + end + end + + private + + # Create a map for a specific client. + def clientmap(client) + { + "h" => client.sub(/\..*$/, ""), + "H" => client, + "d" => client.sub(/[^.]+\./, "") # domain name + } + end + + # Replace % patterns as appropriate. + def expand(path, client = nil) + # This map should probably be moved into a method. + map = nil + + if client + map = clientmap(client) + else + Puppet.notice "No client; expanding '%s' with local host" % + path + # Else, use the local information + map = localmap() + end + path.gsub(/%(.)/) do |v| + key = $1 + if key == "%" + "%" + else + map[key] || v + end + end + end + + # Do we have any patterns in our path, yo? + def expandable? + if defined? @expandable + @expandable + else + false + end + end + + # Return an instance of the appropriate class. + def file_instance(klass, short_file, client = nil) + file = file_path(short_file, client) + + return nil unless FileTest.exists?(file) + + return klass.new(file) + end + + # Cache this manufactured map, since if it's used it's likely + # to get used a lot. + def localmap + unless defined? @@localmap + @@localmap = { + "h" => Facter.value("hostname"), + "H" => [Facter.value("hostname"), + Facter.value("domain")].join("."), + "d" => Facter.value("domain") + } + end + @@localmap + end +end |