summaryrefslogtreecommitdiffstats
path: root/lib/puppet/file_serving/configuration.rb
blob: 608924c8bb044d518f79c25f61f1a70cc941d775 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
#
#  Created by Luke Kanies on 2007-10-16.
#  Copyright (c) 2007. All rights reserved.

require 'puppet'
require 'puppet/file_serving'
require 'puppet/file_serving/mount'
require 'puppet/file_serving/mount/file'
require 'puppet/file_serving/mount/modules'
require 'puppet/file_serving/mount/plugins'
require 'puppet/util/cacher'

class Puppet::FileServing::Configuration
    require 'puppet/file_serving/configuration/parser'

    class << self
        include Puppet::Util::Cacher
        cached_attr(:configuration) { new() }
    end

    Mount = Puppet::FileServing::Mount

    # Create our singleton configuration.
    def self.create
        configuration
    end

    private_class_method  :new

    attr_reader :mounts
    #private :mounts

    # Find the right mount.  Does some shenanigans to support old-style module
    # mounts.
    def find_mount(mount_name, node)
        # Reparse the configuration if necessary.
        readconfig

        if mount = mounts[mount_name]
            return mount
        end

        if mounts["modules"].environment(node).module(mount_name)
            Puppet.warning "DEPRECATION NOTICE: Found module '%s' without using the 'modules' mount; please prefix path with 'modules/'" % mount_name
            return mounts["modules"]
        end

        # This can be nil.
        mounts[mount_name]
    end

    def initialize
        @mounts = {}
        @config_file = nil

        # We don't check to see if the file is modified the first time,
        # because we always want to parse at first.
        readconfig(false)
    end

    # Is a given mount available?
    def mounted?(name)
        @mounts.include?(name)
    end

    # Split the path into the separate mount point and path.
    def split_path(request)
        # Reparse the configuration if necessary.
        readconfig

        mount_name, path = request.key.split(File::Separator, 2)

        raise(ArgumentError, "Cannot find file: Invalid path '%s'" % mount_name) unless mount_name =~ %r{^[-\w]+$}

        return nil unless mount = find_mount(mount_name, request.options[:node])
        if mount.name == "modules" and mount_name != "modules"
            # yay backward-compatibility
            path = "%s/%s" % [mount_name, path]
        end

        if path == ""
            path = nil
        elsif path
            # Remove any double slashes that might have occurred
            path = path.gsub(/\/+/, "/")
        end

        return mount, path
    end

    def umount(name)
        @mounts.delete(name) if @mounts.include? name
    end

    private

    # Read the configuration file.
    def readconfig(check = true)
        config = Puppet[:fileserverconfig]

        return unless FileTest.exists?(config)

        @parser ||= Puppet::FileServing::Configuration::Parser.new(config)

        if check and ! @parser.changed?
            return
        end

        # Don't assign the mounts hash until we're sure the parsing succeeded.
        begin
            newmounts = @parser.parse
            @mounts = newmounts
        rescue => detail
            puts detail.backtrace if Puppet[:trace]
            Puppet.err "Error parsing fileserver configuration: %s; using old configuration" % detail
        end
    end
end