summaryrefslogtreecommitdiffstats
path: root/lib/puppet/node/environment.rb
blob: d1a126aaa9b8c6d44d65697728253288dc57dc81 (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
119
require 'puppet/util/cacher'

# Just define it, so this class has fewer load dependencies.
class Puppet::Node
end

# Model the environment that a node can operate in.  This class just
# provides a simple wrapper for the functionality around environments.
class Puppet::Node::Environment
    module Helper
        def environment
            Puppet::Node::Environment.new(@environment)
        end

        def environment=(env)
            if env.is_a?(String) or env.is_a?(Symbol)
                @environment = env
            else
                @environment = env.name
            end
        end
    end

    include Puppet::Util::Cacher

    @seen = {}

    # Return an existing environment instance, or create a new one.
    def self.new(name = nil)
        return name if name.is_a?(self)
        name ||= Puppet.settings.value(:environment)

        raise ArgumentError, "Environment name must be specified" unless name

        symbol = name.to_sym

        return @seen[symbol] if @seen[symbol]

        obj = self.allocate
        obj.send :initialize, symbol
        @seen[symbol] = obj
    end

    # This is only used for testing.
    def self.clear
        @seen.clear
    end

    attr_reader :name

    # Return an environment-specific setting.
    def [](param)
        Puppet.settings.value(param, self.name)
    end

    def initialize(name)
        @name = name
    end

    def known_resource_types
        if @known_resource_types.nil? or @known_resource_types.stale?
            @known_resource_types = Puppet::Resource::TypeCollection.new(self)
            @known_resource_types.perform_initial_import
        end
        @known_resource_types
    end

    def module(name)
        mod = Puppet::Module.new(name, self)
        return nil unless mod.exist?
        return mod
    end

    # Cache the modulepath, so that we aren't searching through
    # all known directories all the time.
    cached_attr(:modulepath, :ttl => Puppet[:filetimeout]) do
        dirs = self[:modulepath].split(File::PATH_SEPARATOR)
        if ENV["PUPPETLIB"]
            dirs = ENV["PUPPETLIB"].split(File::PATH_SEPARATOR) + dirs
        end
        validate_dirs(dirs)
    end

    # Return all modules from this environment.
    # Cache the list, because it can be expensive to create.
    cached_attr(:modules, :ttl => Puppet[:filetimeout]) do
        module_names = modulepath.collect { |path| Dir.entries(path) }.flatten.uniq
        module_names.collect do |path|
            begin
                Puppet::Module.new(path, self)
            rescue Puppet::Module::Error => e
                nil
            end
        end.compact
    end

    # Cache the manifestdir, so that we aren't searching through
    # all known directories all the time.
    cached_attr(:manifestdir, :ttl => Puppet[:filetimeout]) do
        validate_dirs(self[:manifestdir].split(File::PATH_SEPARATOR))
    end

    def to_s
        name.to_s
    end

    def validate_dirs(dirs)
        dirs.collect do |dir|
            if dir !~ /^#{File::SEPARATOR}/
                File.join(Dir.getwd, dir)
            else
                dir
            end
        end.find_all do |p|
            p =~ /^#{File::SEPARATOR}/ && FileTest.directory?(p)
        end
    end

end