puppet-debugger 0.19.0 → 1.0.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 +4 -4
- data/.gitlab-ci.yml +10 -27
- data/.rubocop.yml +64 -232
- data/.rubocop_todo.yml +89 -147
- data/CHANGELOG.md +12 -1
- data/Gemfile +7 -5
- data/README.md +4 -5
- data/Rakefile +11 -12
- data/bin/pdb +1 -1
- data/lib/awesome_print/ext/awesome_puppet.rb +10 -8
- data/lib/plugins/puppet-debugger/input_responders/benchmark.rb +5 -4
- data/lib/plugins/puppet-debugger/input_responders/classes.rb +4 -1
- data/lib/plugins/puppet-debugger/input_responders/classification.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/commands.rb +18 -18
- data/lib/plugins/puppet-debugger/input_responders/datatypes.rb +11 -5
- data/lib/plugins/puppet-debugger/input_responders/environment.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/exit.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/facterdb_filter.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/facts.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/functions.rb +34 -32
- data/lib/plugins/puppet-debugger/input_responders/help.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/krt.rb +4 -2
- data/lib/plugins/puppet-debugger/input_responders/play.rb +22 -24
- data/lib/plugins/puppet-debugger/input_responders/reset.rb +5 -3
- data/lib/plugins/puppet-debugger/input_responders/resources.rb +5 -2
- data/lib/plugins/puppet-debugger/input_responders/set.rb +34 -32
- data/lib/plugins/puppet-debugger/input_responders/stacktrace.rb +23 -0
- data/lib/plugins/puppet-debugger/input_responders/types.rb +6 -2
- data/lib/plugins/puppet-debugger/input_responders/vars.rb +6 -5
- data/lib/plugins/puppet-debugger/input_responders/whereami.rb +5 -3
- data/lib/puppet-debugger/cli.rb +118 -91
- data/lib/puppet-debugger/code/code_file.rb +13 -14
- data/lib/puppet-debugger/code/code_range.rb +5 -3
- data/lib/puppet-debugger/code/loc.rb +1 -1
- data/lib/puppet-debugger/debugger_code.rb +2 -0
- data/lib/puppet-debugger/hooks.rb +15 -16
- data/lib/puppet-debugger/input_responder_plugin.rb +54 -52
- data/lib/puppet-debugger/monkey_patches.rb +4 -1
- data/lib/puppet-debugger/plugin_test_helper.rb +9 -8
- data/lib/puppet-debugger/support.rb +27 -17
- data/lib/puppet-debugger/support/environment.rb +4 -4
- data/lib/puppet-debugger/support/errors.rb +25 -27
- data/lib/puppet-debugger/support/facts.rb +5 -5
- data/lib/puppet-debugger/support/node.rb +4 -5
- data/lib/puppet-debugger/support/scope.rb +19 -17
- data/lib/puppet-debugger/trollop.rb +38 -31
- data/lib/puppet-debugger/version.rb +1 -1
- data/lib/puppet/application/debugger.rb +141 -135
- data/output.json +1 -0
- data/puppet-debugger.gemspec +17 -16
- data/spec/awesome_print/ext/awesome_puppet_spec.rb +30 -30
- data/spec/fixtures/sample_start_debugger.pp +3 -2
- data/spec/hooks_spec.rb +33 -35
- data/spec/input_responder_plugin_spec.rb +7 -6
- data/spec/input_responders/benchmark_spec.rb +3 -1
- data/spec/input_responders/classes_spec.rb +12 -10
- data/spec/input_responders/classification_spec.rb +4 -2
- data/spec/input_responders/commands_spec.rb +2 -0
- data/spec/input_responders/datatypes_spec.rb +4 -3
- data/spec/input_responders/environment_spec.rb +2 -0
- data/spec/input_responders/exit_spec.rb +9 -11
- data/spec/input_responders/facterdb_filter_spec.rb +2 -0
- data/spec/input_responders/facts_spec.rb +2 -0
- data/spec/input_responders/functions_spec.rb +30 -28
- data/spec/input_responders/help_spec.rb +4 -2
- data/spec/input_responders/krt_spec.rb +3 -1
- data/spec/input_responders/play_spec.rb +10 -20
- data/spec/input_responders/reset_spec.rb +2 -0
- data/spec/input_responders/resources_spec.rb +3 -1
- data/spec/input_responders/set_spec.rb +3 -1
- data/spec/input_responders/stacktrace_spec.rb +15 -0
- data/spec/input_responders/types_spec.rb +2 -0
- data/spec/input_responders/vars_spec.rb +4 -4
- data/spec/input_responders/whereami_spec.rb +2 -0
- data/spec/pdb_spec.rb +0 -9
- data/spec/puppet/application/debugger_spec.rb +18 -19
- data/spec/puppet_debugger_spec.rb +81 -84
- data/spec/remote_node_spec.rb +1 -5
- data/spec/spec_helper.rb +22 -18
- data/spec/support_spec.rb +3 -5
- data/test_matrix.rb +1 -1
- metadata +48 -31
@@ -9,8 +9,6 @@ module PuppetDebugger
|
|
9
9
|
end
|
10
10
|
end
|
11
11
|
|
12
|
-
|
13
|
-
|
14
12
|
class FatalError < Error
|
15
13
|
end
|
16
14
|
|
@@ -22,9 +20,9 @@ module PuppetDebugger
|
|
22
20
|
|
23
21
|
class ConnectError < Error
|
24
22
|
def message
|
25
|
-
|
26
|
-
#{data[:message]}
|
27
|
-
|
23
|
+
<<~OUT
|
24
|
+
#{data[:message]}
|
25
|
+
OUT
|
28
26
|
end
|
29
27
|
end
|
30
28
|
|
@@ -36,9 +34,9 @@ EOF
|
|
36
34
|
|
37
35
|
class UndefinedNode < FatalError
|
38
36
|
def message
|
39
|
-
|
40
|
-
Cannot find node with name: #{data[:name]} on remote server
|
41
|
-
|
37
|
+
<<~OUT
|
38
|
+
Cannot find node with name: #{data[:name]} on remote server
|
39
|
+
OUT
|
42
40
|
end
|
43
41
|
end
|
44
42
|
|
@@ -48,36 +46,36 @@ Cannot find node with name: #{data[:name]} on remote server
|
|
48
46
|
|
49
47
|
class NoClassError < FatalError
|
50
48
|
def message
|
51
|
-
|
52
|
-
#{data[:message]}
|
53
|
-
You are missing puppet classes that are required for compilation.
|
54
|
-
Please ensure these classes are installed on this machine in any of the following paths:
|
55
|
-
#{data[:default_modules_paths]}
|
56
|
-
|
49
|
+
<<~OUT
|
50
|
+
#{data[:message]}
|
51
|
+
You are missing puppet classes that are required for compilation.
|
52
|
+
Please ensure these classes are installed on this machine in any of the following paths:
|
53
|
+
#{data[:default_modules_paths]}
|
54
|
+
OUT
|
57
55
|
end
|
58
56
|
end
|
59
57
|
|
60
58
|
class NodeDefinitionError < FatalError
|
61
59
|
def message
|
62
|
-
out =
|
63
|
-
You are missing a default node definition in your site.pp that is required for compilation.
|
64
|
-
Please ensure you have at least the following default node definition
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
in your #{data[:default_site_manifest]} file.
|
69
|
-
|
60
|
+
out = <<~OUT
|
61
|
+
You are missing a default node definition in your site.pp that is required for compilation.
|
62
|
+
Please ensure you have at least the following default node definition
|
63
|
+
node default {
|
64
|
+
# include classes here
|
65
|
+
}
|
66
|
+
in your #{data[:default_site_manifest]} file.
|
67
|
+
OUT
|
70
68
|
out.fatal
|
71
69
|
end
|
72
70
|
end
|
73
71
|
|
74
72
|
class AuthError < FatalError
|
75
73
|
def message
|
76
|
-
|
77
|
-
#{data[:message]}
|
78
|
-
You will need to edit your auth.conf or conf.d/auth.conf (puppetserver) to allow node calls.
|
79
|
-
|
80
|
-
|
74
|
+
<<~OUT
|
75
|
+
#{data[:message]}
|
76
|
+
You will need to edit your auth.conf or conf.d/auth.conf (puppetserver) to allow node calls.
|
77
|
+
OUT
|
78
|
+
end
|
81
79
|
end
|
82
80
|
end
|
83
81
|
end
|
@@ -46,11 +46,11 @@ module PuppetDebugger
|
|
46
46
|
def node_facts
|
47
47
|
node_facts = FacterDB.get_facts(dynamic_facterdb_filter).first
|
48
48
|
if node_facts.nil?
|
49
|
-
message =
|
50
|
-
Using filter: #{dynamic_facterdb_filter}
|
51
|
-
Bad FacterDB filter, please change the filter so it returns a result set.
|
52
|
-
See https://github.com/camptocamp/facterdb/#with-a-string-filter
|
53
|
-
|
49
|
+
message = <<~OUT
|
50
|
+
Using filter: #{dynamic_facterdb_filter}
|
51
|
+
Bad FacterDB filter, please change the filter so it returns a result set.
|
52
|
+
See https://github.com/camptocamp/facterdb/#with-a-string-filter
|
53
|
+
OUT
|
54
54
|
raise PuppetDebugger::Exception::BadFilter, message: message
|
55
55
|
end
|
56
56
|
# fix for when --show-legacy facts are not part of the facter 3 fact set
|
@@ -32,6 +32,7 @@ module PuppetDebugger
|
|
32
32
|
# Collect our facts.
|
33
33
|
facts = Puppet::Node::Facts.indirection.find(Puppet[:node_name_value])
|
34
34
|
raise "Could not find facts for #{Puppet[:node_name_value]}" unless facts
|
35
|
+
|
35
36
|
Puppet[:node_name_value] = facts.values[Puppet[:node_name_fact]]
|
36
37
|
facts.name = Puppet[:node_name_value]
|
37
38
|
end
|
@@ -39,6 +40,7 @@ module PuppetDebugger
|
|
39
40
|
# Find our Node
|
40
41
|
node = Puppet::Node.indirection.find(Puppet[:node_name_value])
|
41
42
|
raise "Could not find node #{Puppet[:node_name_value]}" unless node
|
43
|
+
|
42
44
|
# Merge in the facts.
|
43
45
|
node.merge(facts.values) if facts
|
44
46
|
end
|
@@ -91,11 +93,8 @@ module PuppetDebugger
|
|
91
93
|
def set_node_from_name(name)
|
92
94
|
out_buffer.puts "Fetching node #{name}"
|
93
95
|
remote_node = get_remote_node(name)
|
94
|
-
|
95
|
-
|
96
|
-
raise PuppetDebugger::Exception::UndefinedNode, name: remote_node.name
|
97
|
-
end
|
98
|
-
remote_node_name = remote_node.name
|
96
|
+
raise PuppetDebugger::Exception::UndefinedNode, name: remote_node.name if remote_node&.parameters&.empty?
|
97
|
+
|
99
98
|
node_object = convert_remote_node(remote_node)
|
100
99
|
set_node(node_object)
|
101
100
|
end
|
@@ -12,27 +12,29 @@ module PuppetDebugger
|
|
12
12
|
@catalog || scope.compiler.catalog
|
13
13
|
end
|
14
14
|
|
15
|
-
def get_catalog_text(
|
16
|
-
return nil unless
|
17
|
-
|
15
|
+
def get_catalog_text(catalog)
|
16
|
+
return nil unless catalog
|
17
|
+
|
18
|
+
Puppet::FileSystem.read(catalog, encoding: 'utf-8')
|
18
19
|
end
|
19
20
|
|
20
21
|
def set_catalog(catalog_file)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
# Resolve all deferred values and replace them / mutate the catalog
|
32
|
-
# Puppet 6 only
|
33
|
-
Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, c) if Gem::Version.new(Puppet.version) >= Gem::Version.new('6.0.0')
|
34
|
-
@catalog = c
|
22
|
+
return unless catalog_file
|
23
|
+
|
24
|
+
catalog_text = get_catalog_text(catalog_file)
|
25
|
+
scope # required
|
26
|
+
Puppet.override({ current_environment: environment }, _('For puppet debugger')) do
|
27
|
+
format = Puppet::Resource::Catalog.default_format
|
28
|
+
begin
|
29
|
+
c = Puppet::Resource::Catalog.convert_from(format, catalog_text)
|
30
|
+
rescue StandardError => e
|
31
|
+
raise Puppet::Error, format(_('Could not deserialize catalog from %{format}: %{detail}'), format: format, detail: e), e.backtrace
|
35
32
|
end
|
33
|
+
# Resolve all deferred values and replace them / mutate the catalog
|
34
|
+
# Puppet 6 only
|
35
|
+
Puppet::Pops::Evaluator::DeferredResolver.resolve_and_replace(node.facts, c) if Gem::Version.new(Puppet.version) >= Gem::Version.new('6.0.0')
|
36
|
+
@catalog = c
|
37
|
+
end
|
36
38
|
end
|
37
39
|
|
38
40
|
# @return [Puppet::Pops::Scope] - returns a puppet scope object
|
@@ -1,4 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
+
|
2
3
|
# lib/trollop.rb -- trollop command-line processing library
|
3
4
|
# Copyright (c) 2008-2014 William Morgan.
|
4
5
|
# Copyright (c) 2014 Red Hat, Inc.
|
@@ -33,10 +34,10 @@ module Trollop
|
|
33
34
|
end
|
34
35
|
|
35
36
|
## Regex for floating point numbers
|
36
|
-
FLOAT_RE = /^-?((\d+(\.\d+)?)|(\.\d+))([eE][-+]?[\d]+)
|
37
|
+
FLOAT_RE = /^-?((\d+(\.\d+)?)|(\.\d+))([eE][-+]?[\d]+)?$/.freeze
|
37
38
|
|
38
39
|
## Regex for parameters
|
39
|
-
PARAM_RE = /^-(-|\.$|[^\d\.])
|
40
|
+
PARAM_RE = /^-(-|\.$|[^\d\.])/.freeze
|
40
41
|
|
41
42
|
## The commandline parser. In typical usage, the methods in this class
|
42
43
|
## will be handled internally by Trollop::options. In this case, only the
|
@@ -50,24 +51,24 @@ module Trollop
|
|
50
51
|
class Parser
|
51
52
|
## The set of values that indicate a flag option when passed as the
|
52
53
|
## +:type+ parameter of #opt.
|
53
|
-
FLAG_TYPES = [
|
54
|
+
FLAG_TYPES = %i[flag bool boolean].freeze
|
54
55
|
|
55
56
|
## The set of values that indicate a single-parameter (normal) option when
|
56
57
|
## passed as the +:type+ parameter of #opt.
|
57
58
|
##
|
58
59
|
## A value of +io+ corresponds to a readable IO resource, including
|
59
60
|
## a filename, URI, or the strings 'stdin' or '-'.
|
60
|
-
SINGLE_ARG_TYPES = [
|
61
|
+
SINGLE_ARG_TYPES = %i[int integer string double float io date].freeze
|
61
62
|
|
62
63
|
## The set of values that indicate a multiple-parameter option (i.e., that
|
63
64
|
## takes multiple space-separated values on the commandline) when passed as
|
64
65
|
## the +:type+ parameter of #opt.
|
65
|
-
MULTI_ARG_TYPES = [
|
66
|
+
MULTI_ARG_TYPES = %i[ints integers strings doubles floats ios dates].freeze
|
66
67
|
|
67
68
|
## The complete set of legal values for the +:type+ parameter of #opt.
|
68
69
|
TYPES = FLAG_TYPES + SINGLE_ARG_TYPES + MULTI_ARG_TYPES
|
69
70
|
|
70
|
-
INVALID_SHORT_ARG_REGEX = /[\d-]
|
71
|
+
INVALID_SHORT_ARG_REGEX = /[\d-]/.freeze #:nodoc:
|
71
72
|
|
72
73
|
## The values from the commandline that were not interpreted by #parse.
|
73
74
|
attr_reader :leftovers
|
@@ -151,8 +152,7 @@ module Trollop
|
|
151
152
|
when :doubles then :floats
|
152
153
|
when Class
|
153
154
|
case opts[:type].name
|
154
|
-
when 'TrueClass',
|
155
|
-
'FalseClass' then :flag
|
155
|
+
when 'TrueClass', 'FalseClass' then :flag
|
156
156
|
when 'String' then :string
|
157
157
|
when 'Integer' then :int
|
158
158
|
when 'Float' then :float
|
@@ -164,6 +164,7 @@ module Trollop
|
|
164
164
|
when nil then nil
|
165
165
|
else
|
166
166
|
raise ArgumentError, "unsupported argument type '#{opts[:type]}'" unless TYPES.include?(opts[:type])
|
167
|
+
|
167
168
|
opts[:type]
|
168
169
|
end
|
169
170
|
|
@@ -175,14 +176,13 @@ module Trollop
|
|
175
176
|
opts[:default].first
|
176
177
|
else
|
177
178
|
opts[:default]
|
178
|
-
|
179
|
+
end
|
179
180
|
|
180
181
|
type_from_default =
|
181
182
|
case disambiguated_default
|
182
183
|
when Integer then :int
|
183
184
|
when Numeric then :float
|
184
|
-
when TrueClass,
|
185
|
-
FalseClass then :flag
|
185
|
+
when TrueClass, FalseClass then :flag
|
186
186
|
when String then :string
|
187
187
|
when IO then :io
|
188
188
|
when Date then :date
|
@@ -190,6 +190,7 @@ module Trollop
|
|
190
190
|
if opts[:default].empty?
|
191
191
|
if opts[:type]
|
192
192
|
raise ArgumentError, 'multiple argument type must be plural' unless MULTI_ARG_TYPES.include?(opts[:type])
|
193
|
+
|
193
194
|
nil
|
194
195
|
else
|
195
196
|
raise ArgumentError, "multiple argument type cannot be deduced from an empty array for '#{opts[:default][0].class.name}'"
|
@@ -220,7 +221,7 @@ module Trollop
|
|
220
221
|
when /^--([^-].*)$/ then Regexp.last_match(1)
|
221
222
|
when /^[^-]/ then opts[:long]
|
222
223
|
else raise ArgumentError, "invalid long option name #{opts[:long].inspect}"
|
223
|
-
|
224
|
+
end
|
224
225
|
raise ArgumentError, "long option name #{opts[:long].inspect} is already taken; please specify a (different) :long" if @long[opts[:long]]
|
225
226
|
|
226
227
|
## fill in :short
|
@@ -229,7 +230,7 @@ module Trollop
|
|
229
230
|
when /^-(.)$/ then Regexp.last_match(1)
|
230
231
|
when nil, :none, /^.$/ then opts[:short]
|
231
232
|
else raise ArgumentError, "invalid short option name '#{opts[:short].inspect}'"
|
232
|
-
|
233
|
+
end
|
233
234
|
|
234
235
|
if opts[:short]
|
235
236
|
raise ArgumentError, "short option name #{opts[:short].inspect} is already taken; please specify a (different) :short" if @short[opts[:short]]
|
@@ -255,21 +256,21 @@ module Trollop
|
|
255
256
|
## Sets the version string. If set, the user can request the version
|
256
257
|
## on the commandline. Should probably be of the form "<program name>
|
257
258
|
## <version number>".
|
258
|
-
def version(
|
259
|
-
|
259
|
+
def version(value = nil)
|
260
|
+
value ? @version = value : @version
|
260
261
|
end
|
261
262
|
|
262
263
|
## Sets the usage string. If set the message will be printed as the
|
263
264
|
## first line in the help (educate) output and ending in two new
|
264
265
|
## lines.
|
265
|
-
def usage(
|
266
|
-
|
266
|
+
def usage(value = nil)
|
267
|
+
value ? @usage = value : @usage
|
267
268
|
end
|
268
269
|
|
269
270
|
## Adds a synopsis (command summary description) right below the
|
270
271
|
## usage line, or as the first line if usage isn't specified.
|
271
|
-
def synopsis(
|
272
|
-
|
272
|
+
def synopsis(value = nil)
|
273
|
+
value ? @synopsis = value : @synopsis
|
273
274
|
end
|
274
275
|
|
275
276
|
## Adds text to the help display. Can be interspersed with calls to
|
@@ -347,22 +348,20 @@ module Trollop
|
|
347
348
|
["--#{Regexp.last_match(1)}", true]
|
348
349
|
else
|
349
350
|
[arg, false]
|
350
|
-
|
351
|
+
end
|
351
352
|
|
352
353
|
sym = case arg
|
353
354
|
when /^-([^-])$/ then @short[Regexp.last_match(1)]
|
354
355
|
when /^--([^-]\S*)$/ then @long[Regexp.last_match(1)] || @long["no-#{Regexp.last_match(1)}"]
|
355
356
|
else raise CommandlineError, "invalid argument syntax: '#{arg}'"
|
356
|
-
|
357
|
+
end
|
357
358
|
|
358
359
|
sym = nil if arg =~ /--no-/ # explicitly invalidate --no-no- arguments
|
359
360
|
|
360
361
|
next 0 if ignore_invalid_options && !sym
|
361
362
|
raise CommandlineError, "unknown argument '#{arg}'" unless sym
|
362
363
|
|
363
|
-
if given_args.include?(sym) && !@specs[sym][:multi]
|
364
|
-
raise CommandlineError, "option '#{arg}' specified multiple times"
|
365
|
-
end
|
364
|
+
raise CommandlineError, "option '#{arg}' specified multiple times" if given_args.include?(sym) && !@specs[sym][:multi]
|
366
365
|
|
367
366
|
given_args[sym] ||= {}
|
368
367
|
given_args[sym][:arg] = arg
|
@@ -396,9 +395,13 @@ module Trollop
|
|
396
395
|
|
397
396
|
case type
|
398
397
|
when :depends
|
399
|
-
syms.each
|
398
|
+
syms.each do |sym|
|
399
|
+
raise CommandlineError, "--#{@specs[constraint_sym][:long]} requires --#{@specs[sym][:long]}" unless given_args.include? sym
|
400
|
+
end
|
400
401
|
when :conflicts
|
401
|
-
syms.each
|
402
|
+
syms.each do |sym|
|
403
|
+
raise CommandlineError, "--#{@specs[constraint_sym][:long]} conflicts with --#{@specs[sym][:long]}" if given_args.include?(sym) && (sym != constraint_sym)
|
404
|
+
end
|
402
405
|
end
|
403
406
|
end
|
404
407
|
|
@@ -413,6 +416,7 @@ module Trollop
|
|
413
416
|
opts = @specs[sym]
|
414
417
|
if params.empty? && opts[:type] != :flag
|
415
418
|
raise CommandlineError, "option '#{arg}' needs a parameter" unless opts[:default]
|
419
|
+
|
416
420
|
params << (opts[:default].is_a?(Array) ? opts[:default].clone : [opts[:default]])
|
417
421
|
end
|
418
422
|
|
@@ -527,7 +531,7 @@ module Trollop
|
|
527
531
|
spec[:default].join(', ')
|
528
532
|
else
|
529
533
|
spec[:default].to_s
|
530
|
-
|
534
|
+
end
|
531
535
|
|
532
536
|
if spec[:default]
|
533
537
|
if spec[:desc] =~ /\.$/
|
@@ -553,7 +557,7 @@ module Trollop
|
|
553
557
|
end
|
554
558
|
else
|
555
559
|
80
|
556
|
-
|
560
|
+
end
|
557
561
|
end
|
558
562
|
|
559
563
|
def legacy_width
|
@@ -580,15 +584,15 @@ module Trollop
|
|
580
584
|
## The per-parser version of Trollop::die (see that for documentation).
|
581
585
|
def die(arg, msg = nil, error_code = nil)
|
582
586
|
if msg
|
583
|
-
|
587
|
+
warn "Error: argument --#{@specs[arg][:long]} #{msg}."
|
584
588
|
else
|
585
|
-
|
589
|
+
warn "Error: #{arg}."
|
586
590
|
end
|
587
591
|
if @educate_on_error
|
588
592
|
$stderr.puts
|
589
593
|
educate $stderr
|
590
594
|
else
|
591
|
-
|
595
|
+
warn 'Try --help for help.'
|
592
596
|
end
|
593
597
|
exit(error_code || -1)
|
594
598
|
end
|
@@ -602,6 +606,7 @@ module Trollop
|
|
602
606
|
|
603
607
|
until i >= args.length
|
604
608
|
return remains += args[i..-1] if @stop_words.member? args[i]
|
609
|
+
|
605
610
|
case args[i]
|
606
611
|
when /^--$/ # arg terminator
|
607
612
|
return remains += args[(i + 1)..-1]
|
@@ -662,11 +667,13 @@ module Trollop
|
|
662
667
|
|
663
668
|
def parse_integer_parameter(param, arg)
|
664
669
|
raise CommandlineError, "option '#{arg}' needs an integer" unless param =~ /^-?[\d_]+$/
|
670
|
+
|
665
671
|
param.to_i
|
666
672
|
end
|
667
673
|
|
668
674
|
def parse_float_parameter(param, arg)
|
669
675
|
raise CommandlineError, "option '#{arg}' needs a floating-point number" unless param =~ FLOAT_RE
|
676
|
+
|
670
677
|
param.to_f
|
671
678
|
end
|
672
679
|
|
@@ -1,185 +1,185 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require
|
4
|
-
require
|
5
|
-
require
|
3
|
+
require 'puppet/application'
|
4
|
+
require 'optparse'
|
5
|
+
require 'puppet/util/command_line'
|
6
6
|
|
7
7
|
class Puppet::Application::Debugger < Puppet::Application
|
8
8
|
attr_reader :use_stdin
|
9
9
|
|
10
|
-
option(
|
10
|
+
option('--execute EXECUTE', '-e') do |arg|
|
11
11
|
options[:code] = arg
|
12
12
|
end
|
13
13
|
|
14
|
-
option(
|
14
|
+
option('--facterdb-filter FILTER') do |arg|
|
15
15
|
options[:use_facterdb] = true unless options[:node_name]
|
16
|
-
ENV[
|
16
|
+
ENV['DEBUGGER_FACTERDB_FILTER'] = arg if arg
|
17
17
|
end
|
18
18
|
|
19
|
-
option(
|
19
|
+
option('--test') do |_arg|
|
20
20
|
options[:quiet] = true
|
21
21
|
options[:run_once] = true
|
22
22
|
@use_stdin = true
|
23
23
|
end
|
24
24
|
|
25
|
-
option(
|
25
|
+
option('--no-facterdb') { |_arg| options[:use_facterdb] = false }
|
26
26
|
|
27
|
-
option(
|
27
|
+
option('--log-level LEVEL', '-l') do |arg|
|
28
28
|
Puppet::Util::Log.level = arg.to_sym
|
29
29
|
end
|
30
30
|
|
31
|
-
option(
|
31
|
+
option('--catalog catalog', '-c catalog') do |arg|
|
32
32
|
options[:catalog] = arg
|
33
33
|
end
|
34
34
|
|
35
|
-
option(
|
35
|
+
option('--quiet', '-q') { |_arg| options[:quiet] = true }
|
36
36
|
|
37
|
-
option(
|
37
|
+
option('--play URL', '-p') do |arg|
|
38
38
|
options[:play] = arg
|
39
39
|
end
|
40
40
|
|
41
|
-
option(
|
41
|
+
option('--stdin', '-s') { |_arg| @use_stdin = true }
|
42
42
|
|
43
|
-
option(
|
43
|
+
option('--run-once', '-r') { |_arg| options[:run_once] = true }
|
44
44
|
|
45
|
-
option(
|
45
|
+
option('--node-name CERTNAME', '-n') do |arg|
|
46
46
|
options[:use_facterdb] = false
|
47
47
|
options[:node_name] = arg
|
48
48
|
end
|
49
49
|
|
50
50
|
def help
|
51
|
-
|
51
|
+
<<~HELP
|
52
52
|
|
53
|
-
puppet-debugger(8) -- Starts a debugger session using the puppet-debugger tool
|
54
|
-
========
|
53
|
+
puppet-debugger(8) -- Starts a debugger session using the puppet-debugger tool
|
54
|
+
========
|
55
55
|
|
56
|
-
SYNOPSIS
|
57
|
-
--------
|
58
|
-
A interactive command line tool for evaluating the puppet language and debugging
|
59
|
-
puppet code.
|
56
|
+
SYNOPSIS
|
57
|
+
--------
|
58
|
+
A interactive command line tool for evaluating the puppet language and debugging
|
59
|
+
puppet code.
|
60
60
|
|
61
|
-
USAGE
|
62
|
-
-----
|
63
|
-
puppet debugger [--help] [--version] [-e|--execute CODE] [--facterdb-filter FILTER]
|
64
|
-
|
65
|
-
|
61
|
+
USAGE
|
62
|
+
-----
|
63
|
+
puppet debugger [--help] [--version] [-e|--execute CODE] [--facterdb-filter FILTER]
|
64
|
+
[--test] [--no-facterdb] [-q|--quiet] [-p|--play URL] [-s|--stdin]
|
65
|
+
[-r|--run-once] [-n|--node-name CERTNAME]
|
66
66
|
|
67
67
|
|
68
|
-
DESCRIPTION
|
69
|
-
-----------
|
70
|
-
A interactive command line tool for evaluating the puppet language and debugging
|
71
|
-
puppet code.
|
72
|
-
|
73
|
-
USAGE WITH DEBUG MODULE
|
74
|
-
-----------------------
|
75
|
-
Use the puppet debugger in conjunction with the debug::break() puppet function
|
76
|
-
to pry into your code during compilation. Get immediate insight in how the puppet4
|
77
|
-
languge works during the execution of your code.
|
68
|
+
DESCRIPTION
|
69
|
+
-----------
|
70
|
+
A interactive command line tool for evaluating the puppet language and debugging
|
71
|
+
puppet code.
|
72
|
+
|
73
|
+
USAGE WITH DEBUG MODULE
|
74
|
+
-----------------------
|
75
|
+
Use the puppet debugger in conjunction with the debug::break() puppet function
|
76
|
+
to pry into your code during compilation. Get immediate insight in how the puppet4
|
77
|
+
languge works during the execution of your code.
|
78
78
|
|
79
|
-
To use the break function install the module via: puppet module install nwops/debug
|
79
|
+
To use the break function install the module via: puppet module install nwops/debug
|
80
80
|
|
81
|
-
Now place the debug::break() function anywhere in your code to
|
81
|
+
Now place the debug::break() function anywhere in your code to
|
82
82
|
|
83
|
-
Example:
|
84
|
-
|
83
|
+
Example:
|
84
|
+
puppet debugger -e '$abs_vars = [-11,-22,-33].map | Integer $num | { debug::break() ; notice($num) }'
|
85
85
|
|
86
|
-
See: https://github.com/nwops/puppet-debug
|
87
|
-
OPTIONS
|
88
|
-
-------
|
89
|
-
Note that any setting that's valid in the configuration
|
90
|
-
file is also a valid long argument. For example, 'server' is a valid
|
91
|
-
setting, so you can specify '--server <servername>' as
|
92
|
-
an argument.
|
86
|
+
See: https://github.com/nwops/puppet-debug
|
87
|
+
OPTIONS
|
88
|
+
-------
|
89
|
+
Note that any setting that's valid in the configuration
|
90
|
+
file is also a valid long argument. For example, 'server' is a valid
|
91
|
+
setting, so you can specify '--server <servername>' as
|
92
|
+
an argument.
|
93
93
|
|
94
|
-
See the configuration file documentation at
|
95
|
-
http://docs.puppetlabs.com/references/stable/configuration.html for the
|
96
|
-
full list of acceptable parameters. A commented list of all
|
97
|
-
configuration options can also be generated by running puppet debugger with
|
98
|
-
'--genconfig'.
|
94
|
+
See the configuration file documentation at
|
95
|
+
http://docs.puppetlabs.com/references/stable/configuration.html for the
|
96
|
+
full list of acceptable parameters. A commented list of all
|
97
|
+
configuration options can also be generated by running puppet debugger with
|
98
|
+
'--genconfig'.
|
99
99
|
|
100
|
-
* --help:
|
101
|
-
|
100
|
+
* --help:
|
101
|
+
Print this help message
|
102
102
|
|
103
|
-
* --version:
|
104
|
-
|
103
|
+
* --version:
|
104
|
+
Print the puppet version number and exit.
|
105
105
|
|
106
|
-
* --execute:
|
107
|
-
|
106
|
+
* --execute:
|
107
|
+
Execute a specific piece of Puppet code
|
108
108
|
|
109
|
-
* --facterdb-filter
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
109
|
+
* --facterdb-filter
|
110
|
+
Disables the usage of the current node level facts and uses cached facts
|
111
|
+
from facterdb. Specifying a filter will override the default facterdb filter.
|
112
|
+
Not specifiying a filter will use the default CentOS based filter.
|
113
|
+
This will greatly speed up the start time of the debugger since
|
114
|
+
you are using cached facts. Additionally, using facterdb also allows you
|
115
|
+
to play with many other operating system facts that you might not have access
|
116
|
+
to. For example filters please see the facterdb docs.
|
117
117
|
|
118
|
-
|
118
|
+
See https://github.com/camptocamp/facterdb for more info
|
119
119
|
|
120
|
-
* --no-facterdb
|
121
|
-
|
120
|
+
* --no-facterdb
|
121
|
+
Use the facts found on this node instead of cached facts from facterdb.
|
122
122
|
|
123
|
-
* --log-level
|
124
|
-
|
123
|
+
* --log-level
|
124
|
+
Set the Puppet log level which can be very useful with using the debugger.
|
125
125
|
|
126
|
-
* --quiet
|
127
|
-
|
126
|
+
* --quiet
|
127
|
+
Do not display the debugger help script upon startup.
|
128
128
|
|
129
|
-
* --play
|
130
|
-
|
131
|
-
|
129
|
+
* --play
|
130
|
+
Plays back the code file supplied into the debugger. Can also supply
|
131
|
+
any http based url.
|
132
132
|
|
133
|
-
* --run-once
|
134
|
-
|
133
|
+
* --run-once
|
134
|
+
Return the result from the debugger and exit
|
135
135
|
|
136
|
-
* --stdin
|
137
|
-
|
136
|
+
* --stdin
|
137
|
+
Read from stdin instead of starting the debugger right away. Useful when piping code into the debugger.
|
138
138
|
|
139
|
-
* --catalog:
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
139
|
+
* --catalog:
|
140
|
+
Import a JSON catalog (such as one generated with 'puppet master --compile'). You need to
|
141
|
+
specify a valid JSON encoded catalog file. Gives you the ability
|
142
|
+
to inspect the catalog and all the parameter values that make up the resources. Can
|
143
|
+
specify a file or pipe to stdin with '-'.
|
144
144
|
|
145
|
-
* --node-name
|
146
|
-
|
147
|
-
|
148
|
-
|
149
|
-
|
145
|
+
* --node-name
|
146
|
+
Retrieves the node information remotely via the puppet server given the node name.
|
147
|
+
This is extremely useful when trying to debug classification issues, as this can show
|
148
|
+
classes and parameters retrieved from the ENC. You can also play around with the real facts
|
149
|
+
of the remote node as well.
|
150
150
|
|
151
|
-
|
152
|
-
|
153
|
-
|
151
|
+
Note: this requires special permission in your puppet server's auth.conf file to allow
|
152
|
+
access to make remote calls from this node: #{Puppet[:certname]}. If you are running
|
153
|
+
the debugger from the puppet server as root you do not need any special setup.
|
154
154
|
|
155
|
-
|
155
|
+
You must also have a signed cert and be able to connect to the server from this system.
|
156
156
|
|
157
|
-
|
157
|
+
Mutually exclusive with --facterdb-filter
|
158
158
|
|
159
|
-
* --test
|
160
|
-
|
159
|
+
* --test
|
160
|
+
Runs the code in the debugger and exit without showing the help screen ( --quiet --run-once, --stdin)
|
161
161
|
|
162
|
-
EXAMPLE
|
163
|
-
-------
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
|
171
|
-
|
172
|
-
|
162
|
+
EXAMPLE
|
163
|
+
-------
|
164
|
+
$ puppet debugger
|
165
|
+
$ echo "notice('hello, can you hear me?')" | puppet debugger --test
|
166
|
+
$ echo "notice('hello, can you hear me?')" | puppet debugger --stdin
|
167
|
+
$ puppet debugger --execute "notice('hello')"
|
168
|
+
$ puppet debugger --facterdb-filter 'facterversion=/^2.4\./ and operatingsystem=Debian'
|
169
|
+
$ puppet debugger --play https://gist.github.com/logicminds/4f6bcfd723c92aad1f01f6a800319fa4
|
170
|
+
$ puppet debugger --facterdb-filter 'facterversion=/^2.4\./ and operatingsystem=Debian' \\
|
171
|
+
--play https://gist.github.com/logicminds/4f6bcfd723c92aad1f01f6a800319fa4
|
172
|
+
$ puppet debugger --node-name
|
173
173
|
|
174
174
|
|
175
|
-
AUTHOR
|
176
|
-
------
|
177
|
-
Corey Osman <corey@nwops.io>
|
175
|
+
AUTHOR
|
176
|
+
------
|
177
|
+
Corey Osman <corey@nwops.io>
|
178
178
|
|
179
179
|
|
180
|
-
COPYRIGHT
|
181
|
-
---------
|
182
|
-
Copyright (c) 2019 NWOps
|
180
|
+
COPYRIGHT
|
181
|
+
---------
|
182
|
+
Copyright (c) 2019 NWOps
|
183
183
|
|
184
184
|
HELP
|
185
185
|
end
|
@@ -187,13 +187,13 @@ Copyright (c) 2019 NWOps
|
|
187
187
|
def initialize(command_line = Puppet::Util::CommandLine.new)
|
188
188
|
@command_line = CommandLineArgs.new(command_line.subcommand_name, command_line.args.dup)
|
189
189
|
@options = { use_facterdb: true, play: nil, run_once: false,
|
190
|
-
|
191
|
-
|
190
|
+
node_name: nil, quiet: false, help: false, scope: nil,
|
191
|
+
catalog: nil }
|
192
192
|
@use_stdin = false
|
193
193
|
begin
|
194
|
-
require
|
195
|
-
rescue LoadError
|
196
|
-
Puppet.err(
|
194
|
+
require 'puppet-debugger'
|
195
|
+
rescue LoadError
|
196
|
+
Puppet.err('You must install the puppet-debugger: gem install puppet-debugger')
|
197
197
|
end
|
198
198
|
end
|
199
199
|
|
@@ -201,26 +201,26 @@ Copyright (c) 2019 NWOps
|
|
201
201
|
# if this is a file we don't play back since its part of the environment
|
202
202
|
# if just the code we put in a file and use the play feature of the debugger
|
203
203
|
# we could do the same thing with the passed in manifest file but that might be too much code to show
|
204
|
-
|
205
204
|
if options[:code]
|
206
205
|
code_input = options.delete(:code)
|
207
|
-
file = Tempfile.new([
|
208
|
-
File.open(file,
|
206
|
+
file = Tempfile.new(['puppet_debugger_input', '.pp'])
|
207
|
+
File.open(file, 'w') do |f|
|
209
208
|
f.write(code_input)
|
210
209
|
end
|
211
210
|
options[:play] = file
|
212
211
|
elsif command_line.args.empty? && use_stdin
|
213
212
|
code_input = STDIN.read
|
214
|
-
file = Tempfile.new([
|
215
|
-
File.open(file,
|
213
|
+
file = Tempfile.new(['puppet_debugger_input', '.pp'])
|
214
|
+
File.open(file, 'w') do |f|
|
216
215
|
f.write(code_input)
|
217
216
|
end
|
218
217
|
options[:play] = file
|
219
218
|
elsif !command_line.args.empty?
|
220
219
|
manifest = command_line.args.shift
|
221
220
|
raise "Could not find file #{manifest}" unless Puppet::FileSystem.exist?(manifest)
|
222
|
-
|
223
|
-
|
221
|
+
|
222
|
+
Puppet.warning("Only one file can be used per run. Skipping #{command_line.args.join(', ')}") unless command_line.args.empty?
|
223
|
+
options[:play] = manifest
|
224
224
|
end
|
225
225
|
begin
|
226
226
|
if !options[:use_facterdb] && options[:node_name].nil?
|
@@ -235,20 +235,21 @@ Copyright (c) 2019 NWOps
|
|
235
235
|
rescue Exception => e
|
236
236
|
case e.class.to_s
|
237
237
|
when 'SystemExit'
|
238
|
-
|
238
|
+
nil
|
239
239
|
else
|
240
240
|
puts e.message
|
241
241
|
puts e.backtrace
|
242
|
-
exit 1
|
243
242
|
end
|
244
243
|
end
|
245
244
|
end
|
246
245
|
|
247
246
|
def create_environment(manifest)
|
248
247
|
configured_environment = Puppet.lookup(:current_environment)
|
249
|
-
manifest
|
250
|
-
configured_environment.override_with(manifest: manifest)
|
248
|
+
if manifest
|
249
|
+
configured_environment.override_with(manifest: manifest)
|
250
|
+
else
|
251
251
|
configured_environment
|
252
|
+
end
|
252
253
|
end
|
253
254
|
|
254
255
|
def create_node(environment)
|
@@ -258,14 +259,16 @@ Copyright (c) 2019 NWOps
|
|
258
259
|
unless facts = Puppet::Node::Facts.indirection.find(Puppet[:node_name_value])
|
259
260
|
raise "Could not find facts for #{Puppet[:node_name_value]}"
|
260
261
|
end
|
262
|
+
|
261
263
|
Puppet[:node_name_value] = facts.values[Puppet[:node_name_fact]]
|
262
264
|
facts.name = Puppet[:node_name_value]
|
263
265
|
end
|
264
|
-
Puppet.override({ current_environment: environment },
|
266
|
+
Puppet.override({ current_environment: environment }, 'For puppet debugger') do
|
265
267
|
# Find our Node
|
266
268
|
unless node = Puppet::Node.indirection.find(Puppet[:node_name_value])
|
267
269
|
raise "Could not find node #{Puppet[:node_name_value]}"
|
268
270
|
end
|
271
|
+
|
269
272
|
# Merge in the facts.
|
270
273
|
node.merge(facts.values) if facts
|
271
274
|
end
|
@@ -288,11 +291,14 @@ Copyright (c) 2019 NWOps
|
|
288
291
|
if $stdout.isatty
|
289
292
|
options = options.merge(scope: scope)
|
290
293
|
# required in order to use convert puppet hash into ruby hash with symbols
|
291
|
-
options = options.each_with_object({})
|
294
|
+
options = options.each_with_object({}) do |(k, v), data|
|
295
|
+
data[k.to_sym] = v
|
296
|
+
data
|
297
|
+
end
|
292
298
|
# options[:source_file], options[:source_line] = stacktrace.last
|
293
299
|
::PuppetRepl::Cli.start(options)
|
294
300
|
else
|
295
|
-
Puppet.info
|
301
|
+
Puppet.info 'puppet debug: refusing to start the debugger without a tty'
|
296
302
|
end
|
297
303
|
end
|
298
304
|
|
@@ -303,7 +309,7 @@ Copyright (c) 2019 NWOps
|
|
303
309
|
# for compatibility with older puppet versions
|
304
310
|
# The basics behind this are to find the `.pp` file in the list of loaded code
|
305
311
|
def stacktrace
|
306
|
-
|
312
|
+
caller.each_with_object([]) do |loc, memo|
|
307
313
|
if loc =~ /\A(.*\.pp)?:([0-9]+):in\s(.*)/
|
308
314
|
# if the file is not found we set to code
|
309
315
|
# and read from Puppet[:code]
|