puppet-debugger 0.15.2 → 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 +21 -45
- data/.rubocop.yml +64 -233
- data/.rubocop_todo.yml +89 -147
- data/.ruby-version +1 -1
- data/.vscode/launch.json +15 -0
- data/CHANGELOG.md +34 -2
- data/Gemfile +7 -5
- data/README.md +29 -261
- data/Rakefile +11 -12
- data/bin/pdb +1 -1
- data/lib/awesome_print/ext/awesome_puppet.rb +22 -8
- data/lib/plugins/puppet-debugger/input_responders/benchmark.rb +5 -4
- data/lib/plugins/puppet-debugger/input_responders/classes.rb +14 -2
- 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 +22 -6
- 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 +16 -7
- 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 +8 -7
- data/lib/plugins/puppet-debugger/input_responders/whereami.rb +5 -3
- data/lib/puppet-debugger.rb +1 -45
- data/lib/puppet-debugger/cli.rb +120 -92
- 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 +57 -0
- 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 +10 -3
- 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 -7
- data/lib/puppet-debugger/support/scope.rb +29 -0
- data/lib/puppet-debugger/trollop.rb +38 -31
- data/lib/puppet-debugger/version.rb +1 -1
- data/lib/puppet/application/debugger.rb +151 -126
- data/output.json +1 -0
- data/puppet-debugger.gemspec +17 -15
- data/spec/awesome_print/ext/awesome_puppet_spec.rb +30 -30
- data/spec/fixtures/pe-xl-core-0.puppet.vm.json +1 -0
- 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 -13
- 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 +8 -2
- 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 +5 -3
- 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 +7 -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 +35 -17
- data/spec/puppet_debugger_spec.rb +81 -83
- 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 +53 -19
@@ -8,6 +8,35 @@ module PuppetDebugger
|
|
8
8
|
@scope = value
|
9
9
|
end
|
10
10
|
|
11
|
+
def catalog
|
12
|
+
@catalog || scope.compiler.catalog
|
13
|
+
end
|
14
|
+
|
15
|
+
def get_catalog_text(catalog)
|
16
|
+
return nil unless catalog
|
17
|
+
|
18
|
+
Puppet::FileSystem.read(catalog, encoding: 'utf-8')
|
19
|
+
end
|
20
|
+
|
21
|
+
def set_catalog(catalog_file)
|
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
|
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
|
38
|
+
end
|
39
|
+
|
11
40
|
# @return [Puppet::Pops::Scope] - returns a puppet scope object
|
12
41
|
def scope
|
13
42
|
@scope ||= create_scope
|
@@ -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,186 +1,199 @@
|
|
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
|
+
options[:catalog] = arg
|
33
|
+
end
|
34
|
+
|
35
|
+
option('--quiet', '-q') { |_arg| options[:quiet] = true }
|
32
36
|
|
33
|
-
option(
|
37
|
+
option('--play URL', '-p') do |arg|
|
34
38
|
options[:play] = arg
|
35
39
|
end
|
36
40
|
|
37
|
-
option(
|
41
|
+
option('--stdin', '-s') { |_arg| @use_stdin = true }
|
38
42
|
|
39
|
-
option(
|
43
|
+
option('--run-once', '-r') { |_arg| options[:run_once] = true }
|
40
44
|
|
41
|
-
option(
|
45
|
+
option('--node-name CERTNAME', '-n') do |arg|
|
42
46
|
options[:use_facterdb] = false
|
43
47
|
options[:node_name] = arg
|
44
48
|
end
|
45
49
|
|
46
50
|
def help
|
47
|
-
|
51
|
+
<<~HELP
|
48
52
|
|
49
|
-
puppet-debugger(8) -- Starts a debugger session using the puppet-debugger tool
|
50
|
-
========
|
53
|
+
puppet-debugger(8) -- Starts a debugger session using the puppet-debugger tool
|
54
|
+
========
|
51
55
|
|
52
|
-
SYNOPSIS
|
53
|
-
--------
|
54
|
-
A interactive command line tool for evaluating the puppet language and debugging
|
55
|
-
puppet code.
|
56
|
+
SYNOPSIS
|
57
|
+
--------
|
58
|
+
A interactive command line tool for evaluating the puppet language and debugging
|
59
|
+
puppet code.
|
56
60
|
|
57
|
-
USAGE
|
58
|
-
-----
|
59
|
-
puppet debugger [--help] [--version] [-e|--execute CODE] [--facterdb-filter FILTER]
|
60
|
-
|
61
|
-
|
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]
|
62
66
|
|
63
67
|
|
64
|
-
DESCRIPTION
|
65
|
-
-----------
|
66
|
-
A interactive command line tool for evaluating the puppet language and debugging
|
67
|
-
puppet 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.
|
68
78
|
|
69
|
-
|
70
|
-
-----------------------
|
71
|
-
Use the puppet debugger in conjunction with the debug::break() puppet function
|
72
|
-
to pry into your code during compilation. Get immediate insight in how the puppet4
|
73
|
-
languge works during the execution of your code.
|
79
|
+
To use the break function install the module via: puppet module install nwops/debug
|
74
80
|
|
75
|
-
|
81
|
+
Now place the debug::break() function anywhere in your code to
|
76
82
|
|
77
|
-
|
83
|
+
Example:
|
84
|
+
puppet debugger -e '$abs_vars = [-11,-22,-33].map | Integer $num | { debug::break() ; notice($num) }'
|
78
85
|
|
79
|
-
|
80
|
-
|
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.
|
81
93
|
|
82
|
-
See
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
setting, so you can specify '--server <servername>' as
|
88
|
-
an argument.
|
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'.
|
89
99
|
|
90
|
-
|
91
|
-
|
92
|
-
full list of acceptable parameters. A commented list of all
|
93
|
-
configuration options can also be generated by running puppet debugger with
|
94
|
-
'--genconfig'.
|
100
|
+
* --help:
|
101
|
+
Print this help message
|
95
102
|
|
96
|
-
* --
|
97
|
-
|
103
|
+
* --version:
|
104
|
+
Print the puppet version number and exit.
|
98
105
|
|
99
|
-
* --
|
100
|
-
|
106
|
+
* --execute:
|
107
|
+
Execute a specific piece of Puppet code
|
101
108
|
|
102
|
-
* --
|
103
|
-
|
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.
|
104
117
|
|
105
|
-
|
106
|
-
Disables the usage of the current node level facts and uses cached facts
|
107
|
-
from facterdb. Specifying a filter will override the default facterdb filter.
|
108
|
-
Not specifiying a filter will use the default CentOS based filter.
|
109
|
-
This will greatly speed up the start time of the debugger since
|
110
|
-
you are using cached facts. Additionally, using facterdb also allows you
|
111
|
-
to play with many other operating system facts that you might not have access
|
112
|
-
to. For example filters please see the facterdb docs.
|
118
|
+
See https://github.com/camptocamp/facterdb for more info
|
113
119
|
|
114
|
-
|
120
|
+
* --no-facterdb
|
121
|
+
Use the facts found on this node instead of cached facts from facterdb.
|
115
122
|
|
116
|
-
* --
|
117
|
-
|
123
|
+
* --log-level
|
124
|
+
Set the Puppet log level which can be very useful with using the debugger.
|
118
125
|
|
119
|
-
* --
|
120
|
-
|
126
|
+
* --quiet
|
127
|
+
Do not display the debugger help script upon startup.
|
121
128
|
|
122
|
-
* --
|
123
|
-
|
129
|
+
* --play
|
130
|
+
Plays back the code file supplied into the debugger. Can also supply
|
131
|
+
any http based url.
|
124
132
|
|
125
|
-
* --
|
126
|
-
|
127
|
-
any http based url.
|
133
|
+
* --run-once
|
134
|
+
Return the result from the debugger and exit
|
128
135
|
|
129
|
-
* --
|
130
|
-
|
136
|
+
* --stdin
|
137
|
+
Read from stdin instead of starting the debugger right away. Useful when piping code into the debugger.
|
131
138
|
|
132
|
-
* --
|
133
|
-
|
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 '-'.
|
134
144
|
|
135
|
-
* --node-name
|
136
|
-
|
137
|
-
|
138
|
-
|
139
|
-
|
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.
|
140
150
|
|
141
|
-
|
142
|
-
|
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.
|
143
154
|
|
144
|
-
|
155
|
+
You must also have a signed cert and be able to connect to the server from this system.
|
145
156
|
|
146
|
-
|
157
|
+
Mutually exclusive with --facterdb-filter
|
147
158
|
|
148
|
-
* --test
|
149
|
-
|
159
|
+
* --test
|
160
|
+
Runs the code in the debugger and exit without showing the help screen ( --quiet --run-once, --stdin)
|
150
161
|
|
151
|
-
EXAMPLE
|
152
|
-
-------
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
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
|
162
173
|
|
163
174
|
|
164
|
-
AUTHOR
|
165
|
-
------
|
166
|
-
Corey Osman <corey@nwops.io>
|
175
|
+
AUTHOR
|
176
|
+
------
|
177
|
+
Corey Osman <corey@nwops.io>
|
167
178
|
|
168
179
|
|
169
|
-
COPYRIGHT
|
170
|
-
---------
|
171
|
-
Copyright (c) 2019 NWOps
|
180
|
+
COPYRIGHT
|
181
|
+
---------
|
182
|
+
Copyright (c) 2019 NWOps
|
172
183
|
|
173
184
|
HELP
|
174
185
|
end
|
175
186
|
|
176
187
|
def initialize(command_line = Puppet::Util::CommandLine.new)
|
177
188
|
@command_line = CommandLineArgs.new(command_line.subcommand_name, command_line.args.dup)
|
178
|
-
@options = { use_facterdb: true, play: nil, run_once: false,
|
189
|
+
@options = { use_facterdb: true, play: nil, run_once: false,
|
190
|
+
node_name: nil, quiet: false, help: false, scope: nil,
|
191
|
+
catalog: nil }
|
179
192
|
@use_stdin = false
|
180
193
|
begin
|
181
|
-
require
|
182
|
-
rescue LoadError
|
183
|
-
Puppet.err(
|
194
|
+
require 'puppet-debugger'
|
195
|
+
rescue LoadError
|
196
|
+
Puppet.err('You must install the puppet-debugger: gem install puppet-debugger')
|
184
197
|
end
|
185
198
|
end
|
186
199
|
|
@@ -188,26 +201,26 @@ Copyright (c) 2019 NWOps
|
|
188
201
|
# if this is a file we don't play back since its part of the environment
|
189
202
|
# if just the code we put in a file and use the play feature of the debugger
|
190
203
|
# we could do the same thing with the passed in manifest file but that might be too much code to show
|
191
|
-
|
192
204
|
if options[:code]
|
193
205
|
code_input = options.delete(:code)
|
194
|
-
file = Tempfile.new([
|
195
|
-
File.open(file,
|
206
|
+
file = Tempfile.new(['puppet_debugger_input', '.pp'])
|
207
|
+
File.open(file, 'w') do |f|
|
196
208
|
f.write(code_input)
|
197
209
|
end
|
198
210
|
options[:play] = file
|
199
211
|
elsif command_line.args.empty? && use_stdin
|
200
212
|
code_input = STDIN.read
|
201
|
-
file = Tempfile.new([
|
202
|
-
File.open(file,
|
213
|
+
file = Tempfile.new(['puppet_debugger_input', '.pp'])
|
214
|
+
File.open(file, 'w') do |f|
|
203
215
|
f.write(code_input)
|
204
216
|
end
|
205
217
|
options[:play] = file
|
206
218
|
elsif !command_line.args.empty?
|
207
219
|
manifest = command_line.args.shift
|
208
220
|
raise "Could not find file #{manifest}" unless Puppet::FileSystem.exist?(manifest)
|
209
|
-
|
210
|
-
|
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
|
211
224
|
end
|
212
225
|
begin
|
213
226
|
if !options[:use_facterdb] && options[:node_name].nil?
|
@@ -220,16 +233,23 @@ Copyright (c) 2019 NWOps
|
|
220
233
|
end
|
221
234
|
::PuppetDebugger::Cli.start_without_stdin(options)
|
222
235
|
rescue Exception => e
|
223
|
-
|
224
|
-
|
236
|
+
case e.class.to_s
|
237
|
+
when 'SystemExit'
|
238
|
+
nil
|
239
|
+
else
|
240
|
+
puts e.message
|
241
|
+
puts e.backtrace
|
242
|
+
end
|
225
243
|
end
|
226
244
|
end
|
227
245
|
|
228
246
|
def create_environment(manifest)
|
229
247
|
configured_environment = Puppet.lookup(:current_environment)
|
230
|
-
manifest
|
231
|
-
configured_environment.override_with(manifest: manifest)
|
248
|
+
if manifest
|
249
|
+
configured_environment.override_with(manifest: manifest)
|
250
|
+
else
|
232
251
|
configured_environment
|
252
|
+
end
|
233
253
|
end
|
234
254
|
|
235
255
|
def create_node(environment)
|
@@ -239,14 +259,16 @@ Copyright (c) 2019 NWOps
|
|
239
259
|
unless facts = Puppet::Node::Facts.indirection.find(Puppet[:node_name_value])
|
240
260
|
raise "Could not find facts for #{Puppet[:node_name_value]}"
|
241
261
|
end
|
262
|
+
|
242
263
|
Puppet[:node_name_value] = facts.values[Puppet[:node_name_fact]]
|
243
264
|
facts.name = Puppet[:node_name_value]
|
244
265
|
end
|
245
|
-
Puppet.override({ current_environment: environment },
|
266
|
+
Puppet.override({ current_environment: environment }, 'For puppet debugger') do
|
246
267
|
# Find our Node
|
247
268
|
unless node = Puppet::Node.indirection.find(Puppet[:node_name_value])
|
248
269
|
raise "Could not find node #{Puppet[:node_name_value]}"
|
249
270
|
end
|
271
|
+
|
250
272
|
# Merge in the facts.
|
251
273
|
node.merge(facts.values) if facts
|
252
274
|
end
|
@@ -269,11 +291,14 @@ Copyright (c) 2019 NWOps
|
|
269
291
|
if $stdout.isatty
|
270
292
|
options = options.merge(scope: scope)
|
271
293
|
# required in order to use convert puppet hash into ruby hash with symbols
|
272
|
-
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
|
273
298
|
# options[:source_file], options[:source_line] = stacktrace.last
|
274
299
|
::PuppetRepl::Cli.start(options)
|
275
300
|
else
|
276
|
-
Puppet.info
|
301
|
+
Puppet.info 'puppet debug: refusing to start the debugger without a tty'
|
277
302
|
end
|
278
303
|
end
|
279
304
|
|
@@ -284,7 +309,7 @@ Copyright (c) 2019 NWOps
|
|
284
309
|
# for compatibility with older puppet versions
|
285
310
|
# The basics behind this are to find the `.pp` file in the list of loaded code
|
286
311
|
def stacktrace
|
287
|
-
|
312
|
+
caller.each_with_object([]) do |loc, memo|
|
288
313
|
if loc =~ /\A(.*\.pp)?:([0-9]+):in\s(.*)/
|
289
314
|
# if the file is not found we set to code
|
290
315
|
# and read from Puppet[:code]
|