Class: Puppet::Util::Autoload

Inherits:
Object
  • Object
show all
Includes:
Puppet::Util, FileCache, Warnings
Defined in:
lib/vendor/puppet/util/autoload.rb

Overview

Autoload paths, either based on names or all at once.

Defined Under Namespace

Modules: FileCache

Constant Summary

Constants included from Puppet::Util

AbsolutePathPosix, AbsolutePathWindows

Class Attribute Summary collapse

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from FileCache

clear, #directory_exist?, #file_exist?, #found_file, #found_file?, #found_files, #missing_file, #missing_file?, #missing_files

Methods included from Warnings

clear_warnings, notice_once, warnonce

Methods included from Puppet::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 POSIX

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

Constructor Details

#initialize(obj, path, options = {}) ⇒ Autoload

Returns a new instance of Autoload.

Raises:

  • (ArgumentError)


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
# File 'lib/vendor/puppet/util/autoload.rb', line 49

def initialize(obj, path, options = {})
  @path = path.to_s
  raise ArgumentError, "Autoload paths cannot be fully qualified" if absolute_path?(@path)
  @object = obj

  self.class[obj] = self

  options.each do |opt, value|
    opt = opt.intern if opt.is_a? String
    begin
      self.send(opt.to_s + "=", value)
    rescue NoMethodError
      raise ArgumentError, "#{opt} is not a valid option"
    end
  end

  @wrap = true unless defined?(@wrap)
end

Class Attribute Details

.autoloadersObject (readonly)

Returns the value of attribute autoloaders.



15
16
17
# File 'lib/vendor/puppet/util/autoload.rb', line 15

def autoloaders
  @autoloaders
end

Instance Attribute Details

#objectObject

Returns the value of attribute object.



47
48
49
# File 'lib/vendor/puppet/util/autoload.rb', line 47

def object
  @object
end

#objwarnObject

Returns the value of attribute objwarn.



47
48
49
# File 'lib/vendor/puppet/util/autoload.rb', line 47

def objwarn
  @objwarn
end

#pathObject

Returns the value of attribute path.



47
48
49
# File 'lib/vendor/puppet/util/autoload.rb', line 47

def path
  @path
end

#wrapObject

Returns the value of attribute wrap.



47
48
49
# File 'lib/vendor/puppet/util/autoload.rb', line 47

def wrap
  @wrap
end

Class Method Details

.list_loadedObject

List all loaded files.



23
24
25
26
27
# File 'lib/vendor/puppet/util/autoload.rb', line 23

def self.list_loaded
  @loaded.sort { |a,b| a[0] <=> b[0] }.collect do |path, hash|
    "#{path}: #{hash[:file]}"
  end
end

.loaded(file) ⇒ Object

Save the fact that a given path has been loaded. This is so we can load downloaded plugins if they’ve already been loaded into memory.



42
43
44
45
# File 'lib/vendor/puppet/util/autoload.rb', line 42

def self.loaded(file)
  $" << file + ".rb" unless $".include?(file)
  @loaded << file unless @loaded.include?(file)
end

.loaded?(path) ⇒ Boolean

Has a given path been loaded? This is used for testing whether a changed file should be loaded or just ignored. This is only used in network/client/master, when downloading plugins, to see if a given plugin is currently loaded and thus should be reloaded.

Returns:

  • (Boolean)


34
35
36
37
# File 'lib/vendor/puppet/util/autoload.rb', line 34

def self.loaded?(path)
  path = path.to_s.sub(/\.rb$/, '')
  @loaded.include?(path)
end

Instance Method Details

#files_to_loadObject



121
122
123
# File 'lib/vendor/puppet/util/autoload.rb', line 121

def files_to_load
  searchpath.map { |dir| Dir.glob("#{dir}/*.rb") }.flatten
end

#load(name, env = nil) ⇒ Object

Load a single plugin by name. We use ‘load’ here so we can reload a given plugin.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
# File 'lib/vendor/puppet/util/autoload.rb', line 70

def load(name,env=nil)
  path = name.to_s + ".rb"

  searchpath(env).each do |dir|
    file = File.join(dir, path)
    next unless file_exist?(file)
    begin
      Kernel.load file, @wrap
      name = name.intern
      loaded name, file
      return true
    rescue SystemExit,NoMemoryError
      raise
    rescue Exception => detail
      puts detail.backtrace if Puppet[:trace]
      raise Puppet::Error, "Could not autoload #{name}: #{detail}"
    end
  end
  false
end

#loadallObject

Load all instances that we can. This uses require, rather than load, so that already-loaded files don’t get reloaded unnecessarily.



104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
# File 'lib/vendor/puppet/util/autoload.rb', line 104

def loadall
  # Load every instance of everything we can find.
  files_to_load.each do |file|
    name = File.basename(file).chomp(".rb").intern
    next if loaded?(name)
    begin
      loaded(name, file)
      Kernel.require file
    rescue SystemExit,NoMemoryError
      raise
    rescue Exception => detail
      puts detail.backtrace if Puppet[:trace]
      raise Puppet::Error, "Could not autoload #{file}: #{detail}"
    end
  end
end

#loaded(name, file) ⇒ Object

Mark the named object as loaded. Note that this supports unqualified queries, while we store the result as a qualified query in the class.



93
94
95
# File 'lib/vendor/puppet/util/autoload.rb', line 93

def loaded(name, file)
  self.class.loaded(File.join(@path, name.to_s))
end

#loaded?(name) ⇒ Boolean

Indicate whether the specfied plugin has been loaded.

Returns:

  • (Boolean)


98
99
100
# File 'lib/vendor/puppet/util/autoload.rb', line 98

def loaded?(name)
  self.class.loaded?(File.join(@path, name.to_s))
end

#module_directories(env = nil) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# File 'lib/vendor/puppet/util/autoload.rb', line 130

def module_directories(env=nil)
  # We have to require this late in the process because otherwise we might
  # have load order issues. Since require is much slower than defined?, we
  # can skip that - and save some 2,155 invocations of require in my real
  # world testing. --daniel 2012-07-10
  require 'puppet/node/environment' unless defined?(Puppet::Node::Environment)

  real_env = Puppet::Node::Environment.new(env)

  # We're using a per-thread cache of said module directories, so that
  # we don't scan the filesystem each time we try to load something with
  # this autoload instance. But since we don't want to cache for the eternity
  # this env_module_directories gets reset after the compilation on the master.
  # This is also reset after an agent ran.
  # One of the side effect of this change is that this module directories list will be
  # shared among all autoload that we have running at a time. But that won't be an issue
  # as by definition those directories are shared by all autoload.
  Thread.current[:env_module_directories] ||= {}
  Thread.current[:env_module_directories][real_env] ||= real_env.modulepath.collect do |dir|
      Dir.entries(dir).reject { |f| f =~ /^\./ }.collect { |f| File.join(dir, f) }
    end.flatten.collect { |d| [File.join(d, "plugins"), File.join(d, "lib")] }.flatten.find_all do |d|
      FileTest.directory?(d)
    end
end

#search_directories(env = nil) ⇒ Object



155
156
157
# File 'lib/vendor/puppet/util/autoload.rb', line 155

def search_directories(env=nil)
  [module_directories(env), Puppet[:libdir].split(File::PATH_SEPARATOR), $LOAD_PATH].flatten
end

#searchpath(env = nil) ⇒ Object

The list of directories to search through for loadable plugins.



126
127
128
# File 'lib/vendor/puppet/util/autoload.rb', line 126

def searchpath(env=nil)
  search_directories(env).uniq.collect { |d| File.join(d, @path) }.find_all { |d| FileTest.directory?(d) }
end