puppet-debugger 0.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/.document +5 -0
- data/.gitignore +54 -0
- data/.gitlab-ci.yml +129 -0
- data/.rspec +3 -0
- data/CHANGELOG.md +61 -0
- data/Gemfile +18 -0
- data/Gemfile.lock +67 -0
- data/LICENSE.txt +20 -0
- data/README.md +276 -0
- data/Rakefile +32 -0
- data/bin/pdb +4 -0
- data/lib/awesome_print/ext/awesome_puppet.rb +40 -0
- data/lib/puppet-debugger/cli.rb +247 -0
- data/lib/puppet-debugger/code/code_file.rb +98 -0
- data/lib/puppet-debugger/code/code_range.rb +69 -0
- data/lib/puppet-debugger/code/loc.rb +80 -0
- data/lib/puppet-debugger/debugger_code.rb +318 -0
- data/lib/puppet-debugger/support/compiler.rb +20 -0
- data/lib/puppet-debugger/support/environment.rb +38 -0
- data/lib/puppet-debugger/support/errors.rb +75 -0
- data/lib/puppet-debugger/support/facts.rb +78 -0
- data/lib/puppet-debugger/support/functions.rb +72 -0
- data/lib/puppet-debugger/support/input_responders.rb +136 -0
- data/lib/puppet-debugger/support/node.rb +90 -0
- data/lib/puppet-debugger/support/play.rb +91 -0
- data/lib/puppet-debugger/support/scope.rb +42 -0
- data/lib/puppet-debugger/support.rb +176 -0
- data/lib/puppet-debugger.rb +55 -0
- data/lib/trollop.rb +861 -0
- data/lib/version.rb +3 -0
- data/puppet-debugger.gemspec +36 -0
- data/run_container_test.sh +12 -0
- data/spec/facts_spec.rb +86 -0
- data/spec/fixtures/environments/production/manifests/site.pp +1 -0
- data/spec/fixtures/invalid_node_obj.yaml +8 -0
- data/spec/fixtures/node_obj.yaml +298 -0
- data/spec/fixtures/sample_manifest.pp +2 -0
- data/spec/fixtures/sample_start_debugger.pp +13 -0
- data/spec/pdb_spec.rb +50 -0
- data/spec/puppet-debugger_spec.rb +492 -0
- data/spec/remote_node_spec.rb +170 -0
- data/spec/spec_helper.rb +57 -0
- data/spec/support_spec.rb +190 -0
- data/test_matrix.rb +42 -0
- metadata +148 -0
@@ -0,0 +1,318 @@
|
|
1
|
+
require_relative 'code/loc'
|
2
|
+
require_relative 'code/code_range'
|
3
|
+
require_relative 'code/code_file'
|
4
|
+
|
5
|
+
# `Pry::Code` is a class that encapsulates lines of source code and their
|
6
|
+
# line numbers and formats them for terminal output. It can read from a file
|
7
|
+
# or method definition or be instantiated with a `String` or an `Array`.
|
8
|
+
#
|
9
|
+
# In general, the formatting methods in `Code` return a new `Code` object
|
10
|
+
# which will format the text as specified when `#to_s` is called. This allows
|
11
|
+
# arbitrary chaining of formatting methods without mutating the original
|
12
|
+
# object.
|
13
|
+
class DebuggerCode
|
14
|
+
class << self
|
15
|
+
# include MethodSource::CodeHelpers
|
16
|
+
|
17
|
+
# Instantiate a `Code` object containing code loaded from a file or
|
18
|
+
# Pry's line buffer.
|
19
|
+
#
|
20
|
+
# @param [String] filename The name of a file, or "(pry)".
|
21
|
+
# @param [Symbol] code_type The type of code the file contains.
|
22
|
+
# @return [Code]
|
23
|
+
def from_file(filename, code_type = nil)
|
24
|
+
code_file = CodeFile.new(filename, code_type)
|
25
|
+
new(code_file.code, 1, code_file.code_type)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Instantiate a `Code` object containing code loaded from a file or
|
29
|
+
# Pry's line buffer.
|
30
|
+
#
|
31
|
+
# @param [String] source code".
|
32
|
+
# @param [Symbol] code_type The type of code the file contains.
|
33
|
+
# @return [Code]
|
34
|
+
def from_string(code, code_type = nil)
|
35
|
+
new(code, 1, code_type)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
# @return [Symbol] The type of code stored in this wrapper.
|
40
|
+
attr_accessor :code_type
|
41
|
+
|
42
|
+
# Instantiate a `Code` object containing code from the given `Array`,
|
43
|
+
# `String`, or `IO`. The first line will be line 1 unless specified
|
44
|
+
# otherwise. If you need non-contiguous line numbers, you can create an
|
45
|
+
# empty `Code` object and then use `#push` to insert the lines.
|
46
|
+
#
|
47
|
+
# @param [Array<String>, String, IO] lines
|
48
|
+
# @param [Integer?] start_line
|
49
|
+
# @param [Symbol?] code_type
|
50
|
+
def initialize(lines = [], start_line = 1, code_type = :ruby)
|
51
|
+
if lines.is_a? String
|
52
|
+
lines = lines.lines
|
53
|
+
end
|
54
|
+
@lines = lines.each_with_index.map { |line, lineno|
|
55
|
+
LOC.new(line, lineno + start_line.to_i) }
|
56
|
+
@code_type = code_type
|
57
|
+
|
58
|
+
@with_marker = @with_indentation = nil
|
59
|
+
end
|
60
|
+
|
61
|
+
# Append the given line. +lineno+ is one more than the last existing
|
62
|
+
# line, unless specified otherwise.
|
63
|
+
#
|
64
|
+
# @param [String] line
|
65
|
+
# @param [Integer?] lineno
|
66
|
+
# @return [String] The inserted line.
|
67
|
+
def push(line, lineno = nil)
|
68
|
+
if lineno.nil?
|
69
|
+
lineno = @lines.last.lineno + 1
|
70
|
+
end
|
71
|
+
@lines.push(LOC.new(line, lineno))
|
72
|
+
line
|
73
|
+
end
|
74
|
+
alias << push
|
75
|
+
|
76
|
+
# Filter the lines using the given block.
|
77
|
+
#
|
78
|
+
# @yield [LOC]
|
79
|
+
# @return [Code]
|
80
|
+
def select(&block)
|
81
|
+
alter do
|
82
|
+
@lines = @lines.select(&block)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Remove all lines that aren't in the given range, expressed either as a
|
87
|
+
# `Range` object or a first and last line number (inclusive). Negative
|
88
|
+
# indices count from the end of the array of lines.
|
89
|
+
#
|
90
|
+
# @param [Range, Integer] start_line
|
91
|
+
# @param [Integer?] end_line
|
92
|
+
# @return [Code]
|
93
|
+
def between(start_line, end_line = nil)
|
94
|
+
return self unless start_line
|
95
|
+
|
96
|
+
code_range = CodeRange.new(start_line, end_line)
|
97
|
+
|
98
|
+
alter do
|
99
|
+
@lines = @lines[code_range.indices_range(@lines)] || []
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Take `num_lines` from `start_line`, forward or backwards.
|
104
|
+
#
|
105
|
+
# @param [Integer] start_line
|
106
|
+
# @param [Integer] num_lines
|
107
|
+
# @return [Code]
|
108
|
+
def take_lines(start_line, num_lines)
|
109
|
+
start_idx =
|
110
|
+
if start_line >= 0
|
111
|
+
@lines.index { |loc| loc.lineno >= start_line } || @lines.length
|
112
|
+
else
|
113
|
+
[@lines.length + start_line, 0].max
|
114
|
+
end
|
115
|
+
|
116
|
+
alter do
|
117
|
+
@lines = @lines.slice(start_idx, num_lines)
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Remove all lines except for the +lines+ up to and excluding +lineno+.
|
122
|
+
#
|
123
|
+
# @param [Integer] lineno
|
124
|
+
# @param [Integer] lines
|
125
|
+
# @return [Code]
|
126
|
+
def before(lineno, lines = 1)
|
127
|
+
return self unless lineno
|
128
|
+
|
129
|
+
select do |loc|
|
130
|
+
loc.lineno >= lineno - lines && loc.lineno < lineno
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
# Remove all lines except for the +lines+ on either side of and including
|
135
|
+
# +lineno+.
|
136
|
+
#
|
137
|
+
# @param [Integer] lineno
|
138
|
+
# @param [Integer] lines
|
139
|
+
# @return [Code]
|
140
|
+
def around(lineno, lines = 1)
|
141
|
+
return self unless lineno
|
142
|
+
|
143
|
+
select do |loc|
|
144
|
+
loc.lineno >= lineno - lines && loc.lineno <= lineno + lines
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
# Remove all lines except for the +lines+ after and excluding +lineno+.
|
149
|
+
#
|
150
|
+
# @param [Integer] lineno
|
151
|
+
# @param [Integer] lines
|
152
|
+
# @return [Code]
|
153
|
+
def after(lineno, lines = 1)
|
154
|
+
return self unless lineno
|
155
|
+
|
156
|
+
select do |loc|
|
157
|
+
loc.lineno > lineno && loc.lineno <= lineno + lines
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
# Remove all lines that don't match the given `pattern`.
|
162
|
+
#
|
163
|
+
# @param [Regexp] pattern
|
164
|
+
# @return [Code]
|
165
|
+
def grep(pattern)
|
166
|
+
return self unless pattern
|
167
|
+
pattern = Regexp.new(pattern)
|
168
|
+
|
169
|
+
select do |loc|
|
170
|
+
loc.line =~ pattern
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
# Format output with line numbers next to it, unless `y_n` is falsy.
|
175
|
+
#
|
176
|
+
# @param [Boolean?] y_n
|
177
|
+
# @return [Code]
|
178
|
+
def with_line_numbers(y_n = true)
|
179
|
+
alter do
|
180
|
+
@with_line_numbers = y_n
|
181
|
+
end
|
182
|
+
end
|
183
|
+
|
184
|
+
# Format output with a marker next to the given +lineno+, unless +lineno+ is
|
185
|
+
# falsy.
|
186
|
+
#
|
187
|
+
# @param [Integer?] lineno
|
188
|
+
# @return [Code]
|
189
|
+
def with_marker(lineno = 1)
|
190
|
+
alter do
|
191
|
+
@with_marker = !!lineno
|
192
|
+
@marker_lineno = lineno
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# Format output with the specified number of spaces in front of every line,
|
197
|
+
# unless `spaces` is falsy.
|
198
|
+
#
|
199
|
+
# @param [Integer?] spaces
|
200
|
+
# @return [Code]
|
201
|
+
def with_indentation(spaces = 0)
|
202
|
+
alter do
|
203
|
+
@with_indentation = !!spaces
|
204
|
+
@indentation_num = spaces
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# @return [String]
|
209
|
+
def inspect
|
210
|
+
Object.instance_method(:to_s).bind(self).call
|
211
|
+
end
|
212
|
+
|
213
|
+
# @return [Integer] the number of digits in the last line.
|
214
|
+
def max_lineno_width
|
215
|
+
@lines.length > 0 ? @lines.last.lineno.to_s.length : 0
|
216
|
+
end
|
217
|
+
|
218
|
+
# @return [String] a formatted representation (based on the configuration of
|
219
|
+
# the object).
|
220
|
+
def to_s
|
221
|
+
print_to_output("", false)
|
222
|
+
end
|
223
|
+
|
224
|
+
# @return [String] a (possibly highlighted) copy of the source code.
|
225
|
+
def highlighted
|
226
|
+
print_to_output("", true)
|
227
|
+
end
|
228
|
+
|
229
|
+
# Writes a formatted representation (based on the configuration of the
|
230
|
+
# object) to the given output, which must respond to `#<<`.
|
231
|
+
def print_to_output(output, color=false)
|
232
|
+
@lines.each do |loc|
|
233
|
+
loc = loc.dup
|
234
|
+
loc.add_line_number(max_lineno_width) if @with_line_numbers
|
235
|
+
loc.add_marker(@marker_lineno) if @with_marker
|
236
|
+
loc.indent(@indentation_num) if @with_indentation
|
237
|
+
output << loc.line
|
238
|
+
output << "\n"
|
239
|
+
end
|
240
|
+
output
|
241
|
+
end
|
242
|
+
|
243
|
+
# Get the comment that describes the expression on the given line number.
|
244
|
+
#
|
245
|
+
# @param [Integer] line_number (1-based)
|
246
|
+
# @return [String] the code.
|
247
|
+
def comment_describing(line_number)
|
248
|
+
self.class.comment_describing(raw, line_number)
|
249
|
+
end
|
250
|
+
|
251
|
+
# Get the multiline expression that starts on the given line number.
|
252
|
+
#
|
253
|
+
# @param [Integer] line_number (1-based)
|
254
|
+
# @return [String] the code.
|
255
|
+
def expression_at(line_number, consume = 0)
|
256
|
+
self.class.expression_at(raw, line_number, :consume => consume)
|
257
|
+
end
|
258
|
+
|
259
|
+
# Get the multiline expression that starts on the given line number.
|
260
|
+
#
|
261
|
+
# @param [Integer] line_number (1-based)
|
262
|
+
# @return [String] the code.
|
263
|
+
def self.expression_at(raw, line_number, consume = 0)
|
264
|
+
#self.class.expression_at(raw, line_number, :consume => consume)
|
265
|
+
raw
|
266
|
+
end
|
267
|
+
|
268
|
+
# Get the (approximate) Module.nesting at the give line number.
|
269
|
+
#
|
270
|
+
# @param [Integer] line_number line number starting from 1
|
271
|
+
# @param [Module] top_module the module in which this code exists
|
272
|
+
# @return [Array<Module>] a list of open modules.
|
273
|
+
def nesting_at(line_number, top_module = Object)
|
274
|
+
Indent.nesting_at(raw, line_number)
|
275
|
+
end
|
276
|
+
|
277
|
+
# Return an unformatted String of the code.
|
278
|
+
#
|
279
|
+
# @return [String]
|
280
|
+
def raw
|
281
|
+
@lines.map(&:line).join("\n") << "\n"
|
282
|
+
end
|
283
|
+
|
284
|
+
# Return the number of lines stored.
|
285
|
+
#
|
286
|
+
# @return [Integer]
|
287
|
+
def length
|
288
|
+
@lines ? @lines.length : 0
|
289
|
+
end
|
290
|
+
|
291
|
+
# Two `Code` objects are equal if they contain the same lines with the same
|
292
|
+
# numbers. Otherwise, call `to_s` and `chomp` and compare as Strings.
|
293
|
+
#
|
294
|
+
# @param [Code, Object] other
|
295
|
+
# @return [Boolean]
|
296
|
+
def ==(other)
|
297
|
+
if other.is_a?(Code)
|
298
|
+
other_lines = other.instance_variable_get(:@lines)
|
299
|
+
@lines.each_with_index.all? { |loc, i| loc == other_lines[i] }
|
300
|
+
else
|
301
|
+
to_s.chomp == other.to_s.chomp
|
302
|
+
end
|
303
|
+
end
|
304
|
+
|
305
|
+
# Forward any missing methods to the output of `#to_s`.
|
306
|
+
def method_missing(name, *args, &block)
|
307
|
+
to_s.send(name, *args, &block)
|
308
|
+
end
|
309
|
+
undef =~
|
310
|
+
|
311
|
+
protected
|
312
|
+
|
313
|
+
# An abstraction of the `dup.instance_eval` pattern used throughout this
|
314
|
+
# class.
|
315
|
+
def alter(&block)
|
316
|
+
dup.tap { |o| o.instance_eval(&block) }
|
317
|
+
end
|
318
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'tempfile'
|
2
|
+
|
3
|
+
module PuppetDebugger
|
4
|
+
module Support
|
5
|
+
module Compilier
|
6
|
+
def create_compiler(node)
|
7
|
+
Puppet::Parser::Compiler.new(node)
|
8
|
+
end
|
9
|
+
|
10
|
+
def compiler
|
11
|
+
@compiler
|
12
|
+
end
|
13
|
+
|
14
|
+
def set_compiler(value)
|
15
|
+
@compiler = value
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module PuppetDebugger
|
2
|
+
module Support
|
3
|
+
module Environment
|
4
|
+
# creates a puppet environment given a module path and environment name
|
5
|
+
# this is cached
|
6
|
+
def puppet_environment
|
7
|
+
@puppet_environment ||= create_environment
|
8
|
+
end
|
9
|
+
|
10
|
+
def create_environment
|
11
|
+
@puppet_environment = Puppet::Node::Environment.create(
|
12
|
+
default_puppet_env_name,
|
13
|
+
default_modules_paths,
|
14
|
+
default_manifests_dir
|
15
|
+
)
|
16
|
+
end
|
17
|
+
|
18
|
+
def set_environment(value)
|
19
|
+
@puppet_environment = value
|
20
|
+
end
|
21
|
+
|
22
|
+
def puppet_env_name
|
23
|
+
puppet_environment.name
|
24
|
+
end
|
25
|
+
|
26
|
+
# the cached name of the environment
|
27
|
+
def default_puppet_env_name
|
28
|
+
ENV['PUPPET_ENV'] || Puppet[:environment]
|
29
|
+
end
|
30
|
+
|
31
|
+
# currently this is not being used
|
32
|
+
def environment_loaders
|
33
|
+
name = compiler.loaders.public_environment_loader.loader_name
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,75 @@
|
|
1
|
+
module PuppetDebugger
|
2
|
+
module Exception
|
3
|
+
class Error < StandardError
|
4
|
+
attr_accessor :data
|
5
|
+
def initialize(data={})
|
6
|
+
@data = data
|
7
|
+
end
|
8
|
+
|
9
|
+
end
|
10
|
+
|
11
|
+
class FatalError < Error
|
12
|
+
end
|
13
|
+
|
14
|
+
class ConnectError < Error
|
15
|
+
def message
|
16
|
+
out = <<-EOF
|
17
|
+
#{data[:message]}
|
18
|
+
EOF
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class BadFilter < FatalError
|
23
|
+
def message
|
24
|
+
data[:message]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class UndefinedNode < FatalError
|
29
|
+
def message
|
30
|
+
out = <<-EOF
|
31
|
+
Cannot find node with name: #{data[:name]} on remote server
|
32
|
+
EOF
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
class TimeOutError < Error
|
37
|
+
#Errno::ETIMEDOUT
|
38
|
+
end
|
39
|
+
|
40
|
+
class NoClassError < FatalError
|
41
|
+
def message
|
42
|
+
out = <<-EOF
|
43
|
+
#{data[:message]}
|
44
|
+
You are missing puppet classes that are required for compilation.
|
45
|
+
Please ensure these classes are installed on this machine in any of the following paths:
|
46
|
+
#{data[:default_modules_paths]}
|
47
|
+
EOF
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
class NodeDefinitionError < FatalError
|
52
|
+
def message
|
53
|
+
out = <<-EOF
|
54
|
+
You are missing a default node definition in your site.pp that is required for compilation.
|
55
|
+
Please ensure you have at least the following default node definition
|
56
|
+
node default {
|
57
|
+
# include classes here
|
58
|
+
}
|
59
|
+
in your #{data[:default_site_manifest]} file.
|
60
|
+
EOF
|
61
|
+
out.fatal
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
class AuthError < FatalError
|
66
|
+
def message
|
67
|
+
out = <<-EOF
|
68
|
+
#{data[:message]}
|
69
|
+
You will need to edit your auth.conf or conf.d/auth.conf (puppetserver) to allow node calls.
|
70
|
+
EOF
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
module PuppetDebugger
|
2
|
+
module Support
|
3
|
+
module Facts
|
4
|
+
# in the future we will want to grab real facts from real systems via puppetdb
|
5
|
+
# or enc data
|
6
|
+
|
7
|
+
# allow the user to specify the facterdb filter
|
8
|
+
def dynamic_facterdb_filter
|
9
|
+
ENV['REPL_FACTERDB_FILTER'] || default_facterdb_filter
|
10
|
+
end
|
11
|
+
|
12
|
+
def default_facterdb_filter
|
13
|
+
"operatingsystem=#{facter_os_name} and operatingsystemrelease=#{facter_os_version} and architecture=x86_64 and facterversion=#{facter_version}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def facter_version
|
17
|
+
ENV['REPL_FACTER_VERSION'] || default_facter_version
|
18
|
+
end
|
19
|
+
|
20
|
+
# return the correct supported version of facter facts
|
21
|
+
def default_facter_version
|
22
|
+
if Gem::Version.new(Puppet.version) >= Gem::Version.new(4.4)
|
23
|
+
'/^3\.1/'
|
24
|
+
else
|
25
|
+
'/^2\.4/'
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def facter_os_name
|
30
|
+
ENV['REPL_FACTER_OS_NAME'] || 'Fedora'
|
31
|
+
end
|
32
|
+
|
33
|
+
def facter_os_version
|
34
|
+
ENV['REPL_FACTER_OS_VERSION'] || '23'
|
35
|
+
end
|
36
|
+
|
37
|
+
def set_facts(value)
|
38
|
+
@facts = value
|
39
|
+
end
|
40
|
+
|
41
|
+
# uses facterdb (cached facts) and retrives the facts given a filter
|
42
|
+
# creates a new facts object
|
43
|
+
# we could also use fact_merge to get real facts from the real system or puppetdb
|
44
|
+
def node_facts
|
45
|
+
node_facts = FacterDB.get_facts(dynamic_facterdb_filter).first
|
46
|
+
if node_facts.nil?
|
47
|
+
message = <<-EOS
|
48
|
+
Using filter: #{facterdb_filter}
|
49
|
+
Bad FacterDB filter, please change the filter so it returns a result set.
|
50
|
+
See https://github.com/camptocamp/facterdb/#with-a-string-filter
|
51
|
+
EOS
|
52
|
+
raise PuppetDebugger::Exception::BadFilter.new(:message => message)
|
53
|
+
end
|
54
|
+
# fix for when --show-legacy facts are not part of the facter 3 fact set
|
55
|
+
node_facts[:fqdn] = node_facts[:networking].fetch('fqdn',nil) unless node_facts[:fqdn]
|
56
|
+
node_facts
|
57
|
+
end
|
58
|
+
|
59
|
+
def default_facts
|
60
|
+
unless @facts
|
61
|
+
values = Hash[ node_facts.map { |k, v| [k.to_s, v] } ]
|
62
|
+
name = values['fqdn']
|
63
|
+
@facts ||= Puppet::Node::Facts.new(name, values)
|
64
|
+
end
|
65
|
+
@facts
|
66
|
+
end
|
67
|
+
|
68
|
+
def server_facts
|
69
|
+
data = {}
|
70
|
+
data["servername"] = Facter.value("fqdn") || Facter.value('networking')['fqdn']
|
71
|
+
data['serverip'] = Facter.value("ipaddress")
|
72
|
+
data["serverversion"] = Puppet.version.to_s
|
73
|
+
data
|
74
|
+
end
|
75
|
+
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,72 @@
|
|
1
|
+
module PuppetDebugger
|
2
|
+
module Support
|
3
|
+
module Functions
|
4
|
+
# returns a array of function files which is only required
|
5
|
+
# when displaying the function map, puppet will load each function on demand
|
6
|
+
# in the future we may want to utilize the puppet loaders to find these things
|
7
|
+
def function_files
|
8
|
+
search_dirs = lib_dirs.map do |lib_dir|
|
9
|
+
[File.join(lib_dir, 'puppet', 'functions', '**', '*.rb'),
|
10
|
+
File.join(lib_dir, 'functions', '**', '*.rb'),
|
11
|
+
File.join(lib_dir, 'puppet', 'parser', 'functions', '*.rb')
|
12
|
+
]
|
13
|
+
end
|
14
|
+
# add puppet lib directories
|
15
|
+
search_dirs << [File.join(puppet_lib_dir, 'puppet', 'functions', '**', '*.rb'),
|
16
|
+
File.join(puppet_lib_dir, 'puppet', 'parser', 'functions', '*.rb')
|
17
|
+
]
|
18
|
+
Dir.glob(search_dirs.flatten)
|
19
|
+
end
|
20
|
+
|
21
|
+
# returns either the module name or puppet version
|
22
|
+
def mod_finder
|
23
|
+
@mod_finder ||= Regexp.new('\/([\w\-\.]+)\/lib')
|
24
|
+
end
|
25
|
+
|
26
|
+
# returns a map of functions
|
27
|
+
def function_map
|
28
|
+
unless @functions
|
29
|
+
do_initialize
|
30
|
+
@functions = {}
|
31
|
+
function_files.each do |file|
|
32
|
+
obj = {}
|
33
|
+
name = File.basename(file, '.rb')
|
34
|
+
obj[:name] = name
|
35
|
+
obj[:parent] = mod_finder.match(file)[1]
|
36
|
+
@functions["#{obj[:parent]}::#{name}"] = obj
|
37
|
+
end
|
38
|
+
end
|
39
|
+
@functions
|
40
|
+
end
|
41
|
+
|
42
|
+
# returns an array of module loaders that we may need to use in the future
|
43
|
+
# in order to parse all types of code (ie. functions) For now this is not
|
44
|
+
# being used.
|
45
|
+
def resolve_paths(loaders)
|
46
|
+
mod_resolver = loaders.instance_variable_get(:@module_resolver)
|
47
|
+
all_mods = mod_resolver.instance_variable_get(:@all_module_loaders)
|
48
|
+
end
|
49
|
+
|
50
|
+
# gather all the lib dirs
|
51
|
+
def lib_dirs
|
52
|
+
dirs = modules_paths.map do |mod_dir|
|
53
|
+
Dir["#{mod_dir}/*/lib"].entries
|
54
|
+
end.flatten
|
55
|
+
dirs + [puppet_repl_lib_dir]
|
56
|
+
end
|
57
|
+
|
58
|
+
# load all the lib dirs so puppet can find the functions
|
59
|
+
# at this time, this function is not being used
|
60
|
+
def load_lib_dirs
|
61
|
+
lib_dirs.each do |lib|
|
62
|
+
$LOAD_PATH << lib
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
# def functions
|
67
|
+
# @functions = []
|
68
|
+
# @functions << compiler.loaders.static_loader.loaded.keys.find_all {|l| l.type == :function}
|
69
|
+
# end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|