Class: Puppet::Parser::Compiler

Inherits:
Object
  • Object
show all
Includes:
Resource::TypeCollectionHelper, Util, Util::Errors
Defined in:
lib/vendor/puppet/parser/compiler.rb

Overview

Maintain a graph of scopes, along with a bunch of data about the individual catalog we’re compiling.

Constant Summary

Constants included from Util

Util::AbsolutePathPosix, Util::AbsolutePathWindows

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Resource::TypeCollectionHelper

#known_resource_types

Methods included from Util::Errors

#adderrorcontext, #devfail, #error_context, #exceptwrap, #fail

Methods included from Util

absolute_path?, activerecord_version, benchmark, binread, chuser, classproxy, #execfail, #execpipe, execute, execute_posix, execute_windows, logmethods, memory, path_to_uri, proxy, replace_file, safe_posix_fork, symbolize, symbolizehash, symbolizehash!, synchronize_on, thinmark, #threadlock, uri_to_path, wait_for_output, which, withumask

Methods included from Util::POSIX

#get_posix_field, #gid, #idfield, #methodbyid, #methodbyname, #search_posix_field, #uid

Constructor Details

#initialize(node, options = {}) ⇒ Compiler

Returns a new instance of Compiler.



175
176
177
178
179
180
181
182
183
184
185
186
187
# File 'lib/vendor/puppet/parser/compiler.rb', line 175

def initialize(node, options = {})
  @node = node

  options.each do |param, value|
    begin
      send(param.to_s + "=", value)
    rescue NoMethodError
      raise ArgumentError, "Compiler objects do not accept #{param}"
    end
  end

  initvars
end

Instance Attribute Details

#catalogObject (readonly)

Returns the value of attribute catalog.



30
31
32
# File 'lib/vendor/puppet/parser/compiler.rb', line 30

def catalog
  @catalog
end

#collectionsObject (readonly)

Returns the value of attribute collections.



30
31
32
# File 'lib/vendor/puppet/parser/compiler.rb', line 30

def collections
  @collections
end

#factsObject (readonly)

Returns the value of attribute facts.



30
31
32
# File 'lib/vendor/puppet/parser/compiler.rb', line 30

def facts
  @facts
end

#nodeObject (readonly)

Returns the value of attribute node.



30
31
32
# File 'lib/vendor/puppet/parser/compiler.rb', line 30

def node
  @node
end

#relationshipsObject (readonly)

Returns the value of attribute relationships.



30
31
32
# File 'lib/vendor/puppet/parser/compiler.rb', line 30

def relationships
  @relationships
end

#resourcesObject (readonly)

Returns the value of attribute resources.



30
31
32
# File 'lib/vendor/puppet/parser/compiler.rb', line 30

def resources
  @resources
end

#topscopeObject (readonly)

Returns the value of attribute topscope.



30
31
32
# File 'lib/vendor/puppet/parser/compiler.rb', line 30

def topscope
  @topscope
end

Class Method Details

.compile(node) ⇒ Object



14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
# File 'lib/vendor/puppet/parser/compiler.rb', line 14

def self.compile(node)
   # We get these from the environment and only cache them in a thread
   # variable for the duration of the compilation.  If nothing else is using
   # the thread, though, we can leave 'em hanging round with no ill effects,
   # and this is safer than cleaning them at the end and assuming that will
   # stick until the next entry to this function.
   Thread.current[:known_resource_types] = nil
   Thread.current[:env_module_directories] = nil

   # ...and we actually do the compile now we have caching ready.
   new(node).compile.to_resource
 rescue => detail
   puts detail.backtrace if Puppet[:trace]
   raise Puppet::Error, "#{detail} on node #{node.name}"
end

Instance Method Details

#add_class(name) ⇒ Object

Store the fact that we’ve evaluated a class



82
83
84
# File 'lib/vendor/puppet/parser/compiler.rb', line 82

def add_class(name)
  @catalog.add_class(name) unless name == ""
end

#add_collection(coll) ⇒ Object

Add a collection to the global list.



33
34
35
# File 'lib/vendor/puppet/parser/compiler.rb', line 33

def add_collection(coll)
  @collections << coll
end

#add_override(override) ⇒ Object

Store a resource override.



42
43
44
45
46
47
48
49
50
51
# File 'lib/vendor/puppet/parser/compiler.rb', line 42

def add_override(override)
  # If possible, merge the override in immediately.
  if resource = @catalog.resource(override.ref)
    resource.merge(override)
  else
    # Otherwise, store the override for later; these
    # get evaluated in Resource#finish.
    @resource_overrides[override.ref] << override
  end
end

#add_relationship(dep) ⇒ Object



37
38
39
# File 'lib/vendor/puppet/parser/compiler.rb', line 37

def add_relationship(dep)
  @relationships << dep
end

#add_resource(scope, resource) ⇒ Object

Store a resource in our resource table.



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/vendor/puppet/parser/compiler.rb', line 54

def add_resource(scope, resource)
  @resources << resource

  # Note that this will fail if the resource is not unique.
  @catalog.add_resource(resource)

  if resource.type.to_s.downcase != "class" && resource[:stage]
    raise ArgumentError, "Only classes can set 'stage'; normal resources like #{resource} cannot change run stage"
  end

  # Stages should not be inside of classes.  They are always a
  # top-level container, regardless of where they appear in the
  # manifest.
  return if resource.type.to_s.downcase == "stage"

  # This adds a resource to the class it lexically appears in in the
  # manifest.
  if resource.type.to_s.downcase != "class"
    return @catalog.add_edge(scope.resource, resource)
  end
end

#ast_nodes?Boolean

Do we use nodes found in the code, vs. the external node sources?

Returns:

  • (Boolean)


77
78
79
# File 'lib/vendor/puppet/parser/compiler.rb', line 77

def ast_nodes?
  known_resource_types.nodes?
end

#classlistObject

Return a list of all of the defined classes.



88
89
90
# File 'lib/vendor/puppet/parser/compiler.rb', line 88

def classlist
  @catalog.classes
end

#compileObject

Compiler our catalog. This mostly revolves around finding and evaluating classes. This is the main entry into our catalog.



94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
# File 'lib/vendor/puppet/parser/compiler.rb', line 94

def compile
  # Set the client's parameters into the top scope.
  set_node_parameters
  create_settings_scope

  evaluate_main

  evaluate_ast_node

  evaluate_node_classes

  evaluate_generators

  finish

  fail_on_unevaluated

  @catalog
end

#delete_collection(coll) ⇒ Object

LAK:FIXME There are no tests for this.



115
116
117
# File 'lib/vendor/puppet/parser/compiler.rb', line 115

def delete_collection(coll)
  @collections.delete(coll) if @collections.include?(coll)
end

#environmentObject

Return the node’s environment.



120
121
122
123
124
125
126
# File 'lib/vendor/puppet/parser/compiler.rb', line 120

def environment
  unless defined?(@environment)
    @environment = (node.environment and node.environment != "") ? node.environment : nil
  end
  Puppet::Node::Environment.current = @environment
  @environment
end

#evaluate_classes(classes, scope, lazy_evaluate = true) ⇒ Object

Evaluate each specified class in turn. If there are any classes we can’t find, raise an error. This method really just creates resource objects that point back to the classes, and then the resources are themselves evaluated later in the process.

Raises:



137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
# File 'lib/vendor/puppet/parser/compiler.rb', line 137

def evaluate_classes(classes, scope, lazy_evaluate = true)
  raise Puppet::DevError, "No source for scope passed to evaluate_classes" unless scope.source
  param_classes = nil
  # if we are a param class, save the classes hash
  # and transform classes to be the keys
  if classes.class == Hash
    param_classes = classes
    classes = classes.keys
  end
  classes.each do |name|
    # If we can find the class, then make a resource that will evaluate it.
    if klass = scope.find_hostclass(name)

      if param_classes
        resource = klass.ensure_in_catalog(scope, param_classes[name] || {})
      else
        next if scope.class_scope(klass)
        resource = klass.ensure_in_catalog(scope)
      end

      # If they've disabled lazy evaluation (which the :include function does),
      # then evaluate our resource immediately.
      resource.evaluate unless lazy_evaluate
    else
      raise Puppet::Error, "Could not find class #{name} for #{node.name}"
    end
  end
end

#evaluate_node_classesObject

Evaluate all of the classes specified by the node.



129
130
131
# File 'lib/vendor/puppet/parser/compiler.rb', line 129

def evaluate_node_classes
  evaluate_classes(@node.classes, @node_scope || topscope)
end

#evaluate_relationshipsObject



166
167
168
# File 'lib/vendor/puppet/parser/compiler.rb', line 166

def evaluate_relationships
  @relationships.each { |rel| rel.evaluate(catalog) }
end

#findresource(*args) ⇒ Object

Return a resource by either its ref or its type and title.



171
172
173
# File 'lib/vendor/puppet/parser/compiler.rb', line 171

def findresource(*args)
  @catalog.resource(*args)
end

#newscope(parent, options = {}) ⇒ Object

Create a new scope, with either a specified parent scope or using the top scope.



191
192
193
194
195
196
197
# File 'lib/vendor/puppet/parser/compiler.rb', line 191

def newscope(parent, options = {})
  parent ||= topscope
  options[:compiler] = self
  scope = Puppet::Parser::Scope.new(options)
  scope.parent = parent
  scope
end

#resource_overrides(resource) ⇒ Object

Return any overrides for the given resource.



200
201
202
# File 'lib/vendor/puppet/parser/compiler.rb', line 200

def resource_overrides(resource)
  @resource_overrides[resource.ref]
end