puppet 7.11.0-universal-darwin → 7.14.0-universal-darwin

Sign up to get free protection for your applications and to get access to all the features.
Files changed (115) hide show
  1. checksums.yaml +4 -4
  2. data/CODEOWNERS +1 -1
  3. data/Gemfile +2 -2
  4. data/Gemfile.lock +24 -19
  5. data/ext/project_data.yaml +1 -1
  6. data/lib/puppet/application/lookup.rb +78 -24
  7. data/lib/puppet/concurrent/thread_local_singleton.rb +5 -3
  8. data/lib/puppet/configurer.rb +74 -25
  9. data/lib/puppet/defaults.rb +20 -1
  10. data/lib/puppet/face/generate.rb +2 -0
  11. data/lib/puppet/file_serving/metadata.rb +3 -0
  12. data/lib/puppet/file_system/file_impl.rb +7 -7
  13. data/lib/puppet/file_system/jruby.rb +1 -1
  14. data/lib/puppet/file_system/path_pattern.rb +10 -15
  15. data/lib/puppet/file_system/uniquefile.rb +1 -1
  16. data/lib/puppet/file_system/windows.rb +4 -4
  17. data/lib/puppet/file_system.rb +3 -2
  18. data/lib/puppet/functions/versioncmp.rb +6 -2
  19. data/lib/puppet/generate/type.rb +9 -0
  20. data/lib/puppet/graph/simple_graph.rb +2 -1
  21. data/lib/puppet/http/client.rb +1 -1
  22. data/lib/puppet/http/redirector.rb +5 -0
  23. data/lib/puppet/node.rb +1 -1
  24. data/lib/puppet/parser/resource.rb +1 -1
  25. data/lib/puppet/pops/evaluator/closure.rb +7 -5
  26. data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +1 -0
  27. data/lib/puppet/pops/parser/code_merger.rb +4 -4
  28. data/lib/puppet/pops/parser/egrammar.ra +2 -0
  29. data/lib/puppet/pops/parser/eparser.rb +574 -558
  30. data/lib/puppet/pops/serialization/to_data_converter.rb +6 -18
  31. data/lib/puppet/pops/validation/checker4_0.rb +7 -2
  32. data/lib/puppet/provider/package/pkg.rb +10 -0
  33. data/lib/puppet/provider/service/init.rb +5 -4
  34. data/lib/puppet/provider/user/useradd.rb +20 -0
  35. data/lib/puppet/resource/catalog.rb +1 -1
  36. data/lib/puppet/resource/type_collection.rb +21 -17
  37. data/lib/puppet/resource.rb +38 -5
  38. data/lib/puppet/ssl/verifier.rb +3 -1
  39. data/lib/puppet/transaction/persistence.rb +22 -12
  40. data/lib/puppet/type/file/data_sync.rb +1 -1
  41. data/lib/puppet/type/file/group.rb +8 -1
  42. data/lib/puppet/type/file/owner.rb +8 -1
  43. data/lib/puppet/type/service.rb +8 -3
  44. data/lib/puppet/type/user.rb +41 -39
  45. data/lib/puppet/util/autoload.rb +1 -1
  46. data/lib/puppet/util/json.rb +20 -0
  47. data/lib/puppet/util/log.rb +7 -2
  48. data/lib/puppet/util/monkey_patches.rb +26 -2
  49. data/lib/puppet/util/package.rb +25 -16
  50. data/lib/puppet/util/windows/service.rb +0 -5
  51. data/lib/puppet/util/windows.rb +3 -0
  52. data/lib/puppet/util/yaml.rb +16 -1
  53. data/lib/puppet/version.rb +1 -1
  54. data/lib/puppet.rb +1 -0
  55. data/locales/puppet.pot +5 -9737
  56. data/man/man5/puppet.conf.5 +21 -2
  57. data/man/man8/puppet-agent.8 +1 -1
  58. data/man/man8/puppet-apply.8 +1 -1
  59. data/man/man8/puppet-catalog.8 +1 -1
  60. data/man/man8/puppet-config.8 +1 -1
  61. data/man/man8/puppet-describe.8 +1 -1
  62. data/man/man8/puppet-device.8 +1 -1
  63. data/man/man8/puppet-doc.8 +1 -1
  64. data/man/man8/puppet-epp.8 +1 -1
  65. data/man/man8/puppet-facts.8 +1 -1
  66. data/man/man8/puppet-filebucket.8 +1 -1
  67. data/man/man8/puppet-generate.8 +1 -1
  68. data/man/man8/puppet-help.8 +1 -1
  69. data/man/man8/puppet-lookup.8 +9 -6
  70. data/man/man8/puppet-module.8 +1 -1
  71. data/man/man8/puppet-node.8 +1 -1
  72. data/man/man8/puppet-parser.8 +1 -1
  73. data/man/man8/puppet-plugin.8 +1 -1
  74. data/man/man8/puppet-report.8 +1 -1
  75. data/man/man8/puppet-resource.8 +1 -1
  76. data/man/man8/puppet-script.8 +1 -1
  77. data/man/man8/puppet-ssl.8 +1 -1
  78. data/man/man8/puppet.8 +2 -2
  79. data/spec/fixtures/integration/application/agent/cached_deferred_catalog.json +2 -1
  80. data/spec/fixtures/unit/forge/bacula.json +1 -1
  81. data/spec/integration/application/agent_spec.rb +28 -0
  82. data/spec/integration/application/lookup_spec.rb +32 -6
  83. data/spec/integration/parser/pcore_resource_spec.rb +20 -0
  84. data/spec/shared_contexts/l10n.rb +5 -0
  85. data/spec/unit/application/lookup_spec.rb +131 -10
  86. data/spec/unit/concurrent/thread_local_singleton_spec.rb +39 -0
  87. data/spec/unit/configurer_spec.rb +167 -60
  88. data/spec/unit/face/generate_spec.rb +64 -0
  89. data/spec/unit/file_system/uniquefile_spec.rb +7 -1
  90. data/spec/unit/file_system_spec.rb +34 -4
  91. data/spec/unit/forge/module_release_spec.rb +3 -3
  92. data/spec/unit/functions/versioncmp_spec.rb +40 -4
  93. data/spec/unit/http/client_spec.rb +58 -1
  94. data/spec/unit/network/formats_spec.rb +6 -0
  95. data/spec/unit/node_spec.rb +6 -0
  96. data/spec/unit/pops/parser/parse_containers_spec.rb +2 -2
  97. data/spec/unit/pops/serialization/to_from_hr_spec.rb +0 -58
  98. data/spec/unit/pops/validator/validator_spec.rb +5 -0
  99. data/spec/unit/provider/package/pkg_spec.rb +15 -0
  100. data/spec/unit/provider/service/gentoo_spec.rb +6 -5
  101. data/spec/unit/provider/service/init_spec.rb +15 -9
  102. data/spec/unit/provider/service/openwrt_spec.rb +21 -29
  103. data/spec/unit/provider/service/redhat_spec.rb +3 -2
  104. data/spec/unit/provider/user/useradd_spec.rb +40 -0
  105. data/spec/unit/resource/catalog_spec.rb +14 -1
  106. data/spec/unit/resource_spec.rb +58 -2
  107. data/spec/unit/transaction/persistence_spec.rb +51 -0
  108. data/spec/unit/type/file/group_spec.rb +7 -0
  109. data/spec/unit/type/file/owner_spec.rb +7 -0
  110. data/spec/unit/type/service_spec.rb +27 -0
  111. data/spec/unit/type/user_spec.rb +67 -45
  112. data/spec/unit/util/autoload_spec.rb +25 -8
  113. data/spec/unit/util/json_spec.rb +126 -0
  114. data/spec/unit/util/yaml_spec.rb +37 -13
  115. metadata +15 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: d9793d493f2252b7b3a101e247cad3de60750964d30ef71b7700e238c6042d2c
4
- data.tar.gz: 3bd5ae0c361450f655511306ab6ef3a57ea5ca13325954fa3f75b504e386db4d
3
+ metadata.gz: 392ba2ec9564298ed85bb838513e1c77c658b4d7eec230cd9187779d4bf1463e
4
+ data.tar.gz: 402ea46ece628a86c88351d7c93e739456a584bb95a21e2e5a4790616d724ad8
5
5
  SHA512:
6
- metadata.gz: aa041c1c1e2888208c99870e0927f45fe6c6f9599ac8701ea09f9bfde1e7be88fd64961704a5e5c73ad63844c355c755c31252597cff948f7d41147ca99ec2cb
7
- data.tar.gz: 54bf0703f36b3c7a2a42a4f1b7124c3c8374e01d196b29628da54cfa03f236f88705daf0c0be1737d69de78103fc6d389cdab8c3f25c992d88a428edc9518e40
6
+ metadata.gz: e699edeb228d551ae1e3804620e3913cf192c4d5381dda61dfbb479d4b655275d6bf4d0a2a7e74a7bc5569bc74d14db222a69e4a62f931583b7d52fd1bb64eee
7
+ data.tar.gz: 06add9d22b8a646a50caf987611b1a4b366477619c2681634cc21a38de36e540d8455993c572fd5f20616771361b7bad0b847bbbcd8cac28bc02a8de916ce81c
data/CODEOWNERS CHANGED
@@ -1,5 +1,5 @@
1
1
  # defaults
2
- * @puppetlabs/platform-core @puppetlabs/puppetserver-maintainers @puppetlabs/night-s-watch
2
+ * @puppetlabs/phoenix @puppetlabs/puppetserver-maintainers @puppetlabs/night-s-watch
3
3
 
4
4
  # PAL
5
5
  /lib/puppet/pal @puppetlabs/bolt
data/Gemfile CHANGED
@@ -3,7 +3,7 @@ source ENV['GEM_SOURCE'] || "https://rubygems.org"
3
3
  gemspec
4
4
 
5
5
  def location_for(place, fake_version = nil)
6
- if place.is_a?(String) && place =~ /^(git[:@][^#]*)#(.*)/
6
+ if place.is_a?(String) && place =~ /^((?:git[:@]|https:)[^#]*)#(.*)/
7
7
  [fake_version, { git: $1, branch: $2, require: false }].compact
8
8
  elsif place.is_a?(String) && place =~ /^file:\/\/(.*)/
9
9
  ['>= 0', { path: File.expand_path($1), require: false }]
@@ -26,7 +26,7 @@ group(:features) do
26
26
  #gem 'ruby-shadow', '~> 2.5', require: false, platforms: [:ruby]
27
27
  gem 'minitar', '~> 0.9', require: false
28
28
  gem 'msgpack', '~> 1.2', require: false
29
- gem 'rdoc', '~> 6.0', require: false, platforms: [:ruby]
29
+ gem 'rdoc', ['~> 6.0', '< 6.4.0'], require: false, platforms: [:ruby]
30
30
  # requires native augeas headers/libs
31
31
  # gem 'ruby-augeas', require: false, platforms: [:ruby]
32
32
  # requires native ldap headers/libs
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  GIT
2
- remote: git://github.com/puppetlabs/packaging
3
- revision: 734cbd7a585d76fb359222d4d5ee6bf239956432
2
+ remote: https://github.com/puppetlabs/packaging
3
+ revision: 9d36e41d10ce14c66d9c3c35157788e63c1afef8
4
4
  branch: 1.0.x
5
5
  specs:
6
- packaging (0.99.80.6.g734cbd7)
6
+ packaging (0.105.0)
7
+ apt_stage_artifacts
7
8
  artifactory (~> 2)
8
9
  csv (= 3.1.5)
9
10
  rake (>= 12.3)
@@ -12,12 +13,12 @@ GIT
12
13
  PATH
13
14
  remote: .
14
15
  specs:
15
- puppet (7.11.0)
16
+ puppet (7.14.0)
16
17
  CFPropertyList (~> 2.2)
17
18
  concurrent-ruby (~> 1.0)
18
19
  deep_merge (~> 1.0)
19
20
  facter (>= 2.4.0, < 5)
20
- fast_gettext (~> 1.1)
21
+ fast_gettext (>= 1.1, < 3)
21
22
  hiera (>= 3.2.1, < 4)
22
23
  locale (~> 2.1)
23
24
  multi_json (~> 1.13)
@@ -30,6 +31,8 @@ GEM
30
31
  CFPropertyList (2.3.6)
31
32
  addressable (2.8.0)
32
33
  public_suffix (>= 2.0.2, < 5.0)
34
+ apt_stage_artifacts (0.10.1)
35
+ docopt
33
36
  artifactory (2.8.2)
34
37
  ast (2.4.2)
35
38
  coderay (1.1.3)
@@ -37,14 +40,14 @@ GEM
37
40
  crack (0.4.5)
38
41
  rexml
39
42
  csv (3.1.5)
40
- deep_merge (1.2.1)
41
- diff-lcs (1.4.4)
43
+ deep_merge (1.2.2)
44
+ diff-lcs (1.5.0)
42
45
  docopt (0.6.1)
43
- facter (4.2.3)
46
+ facter (4.2.7)
44
47
  hocon (~> 1.3)
45
48
  thor (>= 1.0.1, < 2.0)
46
49
  fast_gettext (1.1.2)
47
- ffi (1.15.4)
50
+ ffi (1.15.5)
48
51
  gettext (3.2.9)
49
52
  locale (>= 2.0.5)
50
53
  text (>= 1.3.0)
@@ -53,7 +56,7 @@ GEM
53
56
  gettext (>= 3.0.2, < 3.3.0)
54
57
  locale
55
58
  hashdiff (1.0.1)
56
- hiera (3.7.0)
59
+ hiera (3.8.0)
57
60
  hiera-eyaml (3.2.2)
58
61
  highline
59
62
  optimist
@@ -87,7 +90,7 @@ GEM
87
90
  rake
88
91
  rake (13.0.6)
89
92
  rdiscount (2.2.0.2)
90
- rdoc (6.3.2)
93
+ rdoc (6.3.3)
91
94
  release-metrics (1.1.0)
92
95
  csv
93
96
  docopt
@@ -102,7 +105,7 @@ GEM
102
105
  rspec-mocks (~> 3.10.0)
103
106
  rspec-core (3.10.1)
104
107
  rspec-support (~> 3.10.0)
105
- rspec-expectations (3.10.1)
108
+ rspec-expectations (3.10.2)
106
109
  diff-lcs (>= 1.2.0, < 2.0)
107
110
  rspec-support (~> 3.10.0)
108
111
  rspec-its (1.3.0)
@@ -111,7 +114,7 @@ GEM
111
114
  rspec-mocks (3.10.2)
112
115
  diff-lcs (>= 1.2.0, < 2.0)
113
116
  rspec-support (~> 3.10.0)
114
- rspec-support (3.10.2)
117
+ rspec-support (3.10.3)
115
118
  rubocop (0.49.1)
116
119
  parallel (~> 1.10)
117
120
  parser (>= 2.3.3.1, < 3.0)
@@ -126,17 +129,19 @@ GEM
126
129
  scanf (1.0.0)
127
130
  semantic_puppet (1.0.4)
128
131
  text (1.3.1)
129
- thor (1.1.0)
130
- unicode-display_width (1.7.0)
132
+ thor (1.2.1)
133
+ unicode-display_width (1.8.0)
131
134
  vcr (5.1.0)
132
135
  webmock (3.14.0)
133
136
  addressable (>= 2.8.0)
134
137
  crack (>= 0.3.2)
135
138
  hashdiff (>= 0.4.0, < 2.0.0)
136
- yard (0.9.26)
139
+ webrick (1.7.0)
140
+ yard (0.9.27)
141
+ webrick (~> 1.7.0)
137
142
 
138
143
  PLATFORMS
139
- ruby
144
+ x86_64-linux
140
145
 
141
146
  DEPENDENCIES
142
147
  diff-lcs (~> 1.3)
@@ -155,7 +160,7 @@ DEPENDENCIES
155
160
  puppetserver-ca (~> 2.0)
156
161
  racc (= 1.5.2)
157
162
  rake (~> 13.0)
158
- rdoc (~> 6.0)
163
+ rdoc (~> 6.0, < 6.4.0)
159
164
  ronn (~> 0.7.3)
160
165
  rspec (~> 3.1)
161
166
  rspec-expectations (~> 3.9, != 3.9.3)
@@ -169,4 +174,4 @@ DEPENDENCIES
169
174
  yard
170
175
 
171
176
  BUNDLED WITH
172
- 1.17.3
177
+ 2.2.6
@@ -21,7 +21,7 @@ gem_runtime_dependencies:
21
21
  facter: ['> 2.0.1', '< 5']
22
22
  hiera: ['>= 3.2.1', '< 4']
23
23
  semantic_puppet: '~> 1.0'
24
- fast_gettext: '~> 1.1'
24
+ fast_gettext: ['>= 1.1', '< 3']
25
25
  locale: '~> 2.1'
26
26
  multi_json: '~> 1.10'
27
27
  puppet-resource_api: '~>1.5'
@@ -7,6 +7,7 @@ class Puppet::Application::Lookup < Puppet::Application
7
7
 
8
8
  RUN_HELP = _("Run 'puppet lookup --help' for more details").freeze
9
9
  DEEP_MERGE_OPTIONS = '--knock-out-prefix, --sort-merged-arrays, and --merge-hash-arrays'.freeze
10
+ TRUSTED_INFORMATION_FACTS = ["hostname", "domain", "fqdn", "clientcert"].freeze
10
11
 
11
12
  run_mode :server
12
13
 
@@ -54,11 +55,7 @@ class Puppet::Application::Lookup < Puppet::Application
54
55
  end
55
56
 
56
57
  option('--facts FACT_FILE') do |arg|
57
- if %w{.yaml .yml .json}.include?(arg.match(/\.[^.]*$/)[0])
58
- options[:fact_file] = arg
59
- else
60
- raise _("The --fact file only accepts yaml and json files.\n%{run_help}") % { run_help: RUN_HELP }
61
- end
58
+ options[:fact_file] = arg
62
59
  end
63
60
 
64
61
  def app_defaults
@@ -137,7 +134,9 @@ DESCRIPTION
137
134
  The lookup command is a CLI for Puppet's 'lookup()' function. It searches your
138
135
  Hiera data and returns a value for the requested lookup key, so you can test and
139
136
  explore your data. It is a modern replacement for the 'hiera' command.
140
-
137
+ Lookup uses the setting for global hiera.yaml from puppet's config,
138
+ and the environment to find the environment level hiera.yaml as well as the
139
+ resulting modulepath for the environment (for hiera.yaml files in modules).
141
140
  Hiera usually relies on a node's facts to locate the relevant data sources. By
142
141
  default, 'puppet lookup' uses facts from the node you run the command on, but
143
142
  you can get data for any other node with the '--node <NAME>' option. If
@@ -186,7 +185,8 @@ OPTIONS
186
185
  * --environment <ENV>
187
186
  Like with most Puppet commands, you can specify an environment on the command
188
187
  line. This is important for lookup because different environments can have
189
- different Hiera data.
188
+ different Hiera data. This environment will be always be the one used regardless
189
+ of any other factors.
190
190
 
191
191
  * --merge first|unique|hash|deep:
192
192
  Specify the merge behavior, overriding any merge behavior from the data's
@@ -237,6 +237,13 @@ EXAMPLE
237
237
  To look up 'key_name' using the Puppet Server node's facts:
238
238
  $ puppet lookup key_name
239
239
 
240
+ To look up 'key_name' using the Puppet Server node's arbitrary variables from a manifest, and
241
+ classify the node if applicable:
242
+ $ puppet lookup key_name --compile
243
+
244
+ To look up 'key_name' using the Puppet Server node's facts, overridden by facts given in a file:
245
+ $ puppet lookup key_name --facts fact_file.yaml
246
+
240
247
  To look up 'key_name' with agent.local's facts:
241
248
  $ puppet lookup --node agent.local key_name
242
249
 
@@ -341,31 +348,66 @@ Copyright (c) 2015 Puppet Inc., LLC Licensed under the Apache 2.0 License
341
348
  Puppet.settings[:facts_terminus] = 'facter'
342
349
  end
343
350
 
344
- unless node.is_a?(Puppet::Node) # to allow unit tests to pass a node instance
345
- ni = Puppet::Node.indirection
346
- tc = ni.terminus_class
347
- if tc == :plain || options[:compile]
348
- node = ni.find(node)
349
- else
350
- ni.terminus_class = :plain
351
- node = ni.find(node)
352
- ni.terminus_class = tc
353
- end
354
- end
355
-
356
351
  fact_file = options[:fact_file]
357
352
 
358
353
  if fact_file
359
- if fact_file.end_with?("json")
360
- given_facts = Puppet::Util::Json.load(Puppet::FileSystem.read(fact_file, :encoding => 'utf-8'))
361
- else
354
+ if fact_file.end_with?('.json')
355
+ given_facts = Puppet::Util::Json.load_file(fact_file)
356
+ elsif fact_file.end_with?('.yml', '.yaml')
362
357
  given_facts = Puppet::Util::Yaml.safe_load_file(fact_file)
358
+ else
359
+ given_facts = Puppet::Util::Json.load_file_if_valid(fact_file)
360
+ given_facts = Puppet::Util::Yaml.safe_load_file_if_valid(fact_file) unless given_facts
363
361
  end
364
362
 
365
363
  unless given_facts.instance_of?(Hash)
366
- raise _("Incorrect formatted data in %{fact_file} given via the --facts flag") % { fact_file: fact_file }
364
+ raise _("Incorrectly formatted data in %{fact_file} given via the --facts flag (only accepts yaml and json files)") % { fact_file: fact_file }
365
+ end
366
+
367
+ if TRUSTED_INFORMATION_FACTS.any? { |key| given_facts.key? key }
368
+ unless TRUSTED_INFORMATION_FACTS.all? { |key| given_facts.key? key }
369
+ raise _("When overriding any of the %{trusted_facts_list} facts with %{fact_file} "\
370
+ "given via the --facts flag, they must all be overridden.") % { fact_file: fact_file ,trusted_facts_list: TRUSTED_INFORMATION_FACTS.join(',')}
371
+ end
367
372
  end
368
- node.add_extra_facts(given_facts)
373
+ end
374
+
375
+ unless node.is_a?(Puppet::Node) # to allow unit tests to pass a node instance
376
+ facts = retrieve_node_facts(node, given_facts)
377
+ if Puppet.settings.set_by_cli?('environment')
378
+ node = Puppet::Node.new(node, :classes => nil, :parameters => nil, :facts => facts, :environment => Puppet.settings.value('environment'))
379
+ else
380
+ ni = Puppet::Node.indirection
381
+ tc = ni.terminus_class
382
+ if options[:compile]
383
+ if tc == :plain
384
+ node = ni.find(node, facts: facts)
385
+ else
386
+ begin
387
+ service = Puppet.runtime[:http]
388
+ session = service.create_session
389
+ cert = session.route_to(:ca)
390
+
391
+ _, x509 = cert.get_certificate(node)
392
+ cert = OpenSSL::X509::Certificate.new(x509)
393
+ Puppet::SSL::Oids.register_puppet_oids
394
+ trusted = Puppet::Context::TrustedInformation.remote(true, facts.values['certname'] || node, Puppet::SSL::Certificate.from_instance(cert))
395
+ Puppet.override(trusted_information: trusted) do
396
+ node = ni.find(node, facts: facts)
397
+ end
398
+ rescue
399
+ Puppet.warning _("CA is not available, the operation will continue without using trusted facts.")
400
+ node = ni.find(node, facts: facts)
401
+ end
402
+ end
403
+ else
404
+ ni.terminus_class = :plain
405
+ node = ni.find(node, facts: facts)
406
+ ni.terminus_class = tc
407
+ end
408
+ end
409
+ else
410
+ node.add_extra_facts(given_facts) if given_facts
369
411
  end
370
412
 
371
413
  Puppet[:code] = 'undef' unless options[:compile]
@@ -378,4 +420,16 @@ Copyright (c) 2015 Puppet Inc., LLC Licensed under the Apache 2.0 License
378
420
  compiler.compile { |catalog| yield(compiler.topscope); catalog }
379
421
  end
380
422
  end
423
+
424
+ def retrieve_node_facts(node, given_facts)
425
+ facts = Puppet::Node::Facts.indirection.find(node, :environment => Puppet.lookup(:current_environment))
426
+
427
+ facts = Puppet::Node::Facts.new(node, {}) if facts.nil?
428
+ facts.add_extra_values(given_facts) if given_facts
429
+
430
+ if facts.values.empty?
431
+ raise _("No facts available for target node: %{node}") % { node: node}
432
+ end
433
+ facts
434
+ end
381
435
  end
@@ -5,10 +5,12 @@ module Puppet
5
5
  def singleton
6
6
  key = (name + ".singleton").intern
7
7
  thread = Thread.current
8
- unless thread.thread_variable?(key)
9
- thread.thread_variable_set(key, new)
8
+ value = thread.thread_variable_get(key)
9
+ if value.nil?
10
+ value = new
11
+ thread.thread_variable_set(key, value)
10
12
  end
11
- thread.thread_variable_get(key)
13
+ value
12
14
  end
13
15
  end
14
16
  end
@@ -390,9 +390,18 @@ class Puppet::Configurer
390
390
  # We only need to find out the environment to run in if we don't already have a catalog
391
391
  unless (cached_catalog || options[:catalog] || Puppet.settings.set_by_cli?(:environment) || Puppet[:strict_environment_mode])
392
392
  Puppet.debug(_("Environment not passed via CLI and no catalog was given, attempting to find out the last server-specified environment"))
393
- if last_server_specified_environment
394
- @environment = last_server_specified_environment
395
- report.environment = last_server_specified_environment
393
+ initial_environment, loaded_last_environment = last_server_specified_environment
394
+
395
+ unless Puppet[:use_last_environment] && loaded_last_environment
396
+ Puppet.debug(_("Requesting environment from the server"))
397
+ initial_environment = current_server_specified_environment(@environment, configured_environment, options)
398
+ end
399
+
400
+ if initial_environment
401
+ @environment = initial_environment
402
+ report.environment = initial_environment
403
+
404
+ push_current_environment_and_loaders
396
405
  else
397
406
  Puppet.debug(_("Could not find a usable environment in the lastrunfile. Either the file does not exist, does not have the required keys, or the values of 'initial_environment' and 'converged_environment' are identical."))
398
407
  end
@@ -403,14 +412,7 @@ class Puppet::Configurer
403
412
  # This is to maintain compatibility with anyone using this class
404
413
  # aside from agent, apply, device.
405
414
  unless Puppet.lookup(:loaders) { nil }
406
- new_env = Puppet::Node::Environment.remote(@environment)
407
- Puppet.push_context(
408
- {
409
- current_environment: new_env,
410
- loaders: Puppet::Pops::Loaders.new(new_env, true)
411
- },
412
- "Local node environment #{@environment} for configurer transaction"
413
- )
415
+ push_current_environment_and_loaders
414
416
  end
415
417
 
416
418
  temp_value = options[:pluginsync]
@@ -446,14 +448,7 @@ class Puppet::Configurer
446
448
  @environment = catalog.environment
447
449
  report.environment = @environment
448
450
 
449
- new_env = Puppet::Node::Environment.remote(@environment)
450
- Puppet.push_context(
451
- {
452
- :current_environment => new_env,
453
- :loaders => Puppet::Pops::Loaders.new(new_env, true)
454
- },
455
- "Local node environment #{@environment} for configurer transaction"
456
- )
451
+ push_current_environment_and_loaders
457
452
 
458
453
  query_options, facts = get_facts(options)
459
454
  query_options[:configured_environment] = configured_environment
@@ -563,24 +558,67 @@ class Puppet::Configurer
563
558
  end
564
559
  private :find_functional_server
565
560
 
561
+ #
562
+ # @api private
563
+ #
564
+ # Read the last server-specified environment from the lastrunfile. The
565
+ # environment is considered to be server-specified if the values of
566
+ # `initial_environment` and `converged_environment` are different.
567
+ #
568
+ # @return [String, Boolean] An array containing a string with the environment
569
+ # read from the lastrunfile in case the server is authoritative, and a
570
+ # boolean marking whether the last environment was correctly loaded.
566
571
  def last_server_specified_environment
567
- return @last_server_specified_environment if @last_server_specified_environment
572
+ return @last_server_specified_environment, @loaded_last_environment if @last_server_specified_environment
573
+
568
574
  if Puppet::FileSystem.exist?(Puppet[:lastrunfile])
569
575
  summary = Puppet::Util::Yaml.safe_load_file(Puppet[:lastrunfile])
570
- return unless summary.dig('application', 'run_mode') == 'agent'
571
- initial_environment = summary.dig('application', 'initial_environment')
572
- converged_environment = summary.dig('application', 'converged_environment')
576
+ return [nil, nil] unless summary['application']['run_mode'] == 'agent'
577
+ initial_environment = summary['application']['initial_environment']
578
+ converged_environment = summary['application']['converged_environment']
573
579
  @last_server_specified_environment = converged_environment if initial_environment != converged_environment
580
+ Puppet.debug(_("Successfully loaded last environment from the lastrunfile"))
581
+ @loaded_last_environment = true
574
582
  end
575
583
 
576
584
  Puppet.debug(_("Found last server-specified environment: %{environment}") % { environment: @last_server_specified_environment }) if @last_server_specified_environment
577
- @last_server_specified_environment
585
+ [@last_server_specified_environment, @loaded_last_environment]
578
586
  rescue => detail
579
587
  Puppet.debug(_("Could not find last server-specified environment: %{detail}") % { detail: detail })
580
- nil
588
+ [nil, nil]
581
589
  end
582
590
  private :last_server_specified_environment
583
591
 
592
+ def current_server_specified_environment(current_environment, configured_environment, options)
593
+ return @server_specified_environment if @server_specified_environment
594
+
595
+ begin
596
+ node_retr_time = thinmark do
597
+ node = Puppet::Node.indirection.find(Puppet[:node_name_value],
598
+ :environment => Puppet::Node::Environment.remote(current_environment),
599
+ :configured_environment => configured_environment,
600
+ :ignore_cache => true,
601
+ :transaction_uuid => @transaction_uuid,
602
+ :fail_on_404 => true)
603
+
604
+ @server_specified_environment = node.environment_name.to_s
605
+
606
+ if @server_specified_environment != @environment
607
+ Puppet.notice _("Local environment: '%{local_env}' doesn't match server specified node environment '%{node_env}', switching agent to '%{node_env}'.") % { local_env: @environment, node_env: @server_specified_environment }
608
+ end
609
+ end
610
+
611
+ options[:report].add_times(:node_retrieval, node_retr_time)
612
+
613
+ @server_specified_environment
614
+ rescue => detail
615
+ Puppet.warning(_("Unable to fetch my node definition, but the agent run will continue:"))
616
+ Puppet.warning(detail)
617
+ nil
618
+ end
619
+ end
620
+ private :current_server_specified_environment
621
+
584
622
  def send_report(report)
585
623
  puts report.summary if Puppet[:summarize]
586
624
  save_last_run_summary(report)
@@ -649,6 +687,17 @@ class Puppet::Configurer
649
687
  end
650
688
  end
651
689
 
690
+ def push_current_environment_and_loaders
691
+ new_env = Puppet::Node::Environment.remote(@environment)
692
+ Puppet.push_context(
693
+ {
694
+ :current_environment => new_env,
695
+ :loaders => Puppet::Pops::Loaders.new(new_env, true)
696
+ },
697
+ "Local node environment #{@environment} for configurer transaction"
698
+ )
699
+ end
700
+
652
701
  def retrieve_catalog_from_cache(query_options)
653
702
  result = nil
654
703
  @duration = thinmark do
@@ -421,6 +421,17 @@ module Puppet
421
421
  <https://puppet.com/docs/puppet/latest/environments_about.html>",
422
422
  :type => :path,
423
423
  },
424
+ :use_last_environment => {
425
+ :type => :boolean,
426
+ :default => true,
427
+ :desc => <<-'EOT'
428
+ Puppet saves both the initial and converged environment in the last_run_summary file.
429
+ If they differ, and this setting is set to true, we will use the last converged
430
+ environment and skip the node request.
431
+
432
+ When set to false, we will do the node request and ignore the environment data from the last_run_summary file.
433
+ EOT
434
+ },
424
435
  :always_retry_plugins => {
425
436
  :type => :boolean,
426
437
  :default => true,
@@ -761,6 +772,12 @@ Valid values are 0 (never cache) and 15 (15 second minimum wait time).
761
772
  :owner => "service",
762
773
  :group => "service",
763
774
  :desc => "The directory where catalog previews per node are generated."
775
+ },
776
+ :location_trusted => {
777
+ :default => false,
778
+ :type => :boolean,
779
+ :desc => "This will allow sending the name + password and the cookie header to all hosts that puppet may redirect to.
780
+ This may or may not introduce a security breach if puppet redirects you to a site to which you'll send your authentication info and cookies."
764
781
  }
765
782
  )
766
783
 
@@ -1977,7 +1994,9 @@ EOT
1977
1994
  :call_hook => :on_initialize_and_write, # Call our hook with the default value, so we always get the value added to facter.
1978
1995
  :hook => proc do |value|
1979
1996
  paths = value.split(File::PATH_SEPARATOR)
1980
- Puppet.runtime[:facter].search(*paths)
1997
+ facter = Puppet.runtime[:facter]
1998
+ facter.reset
1999
+ facter.search(*paths)
1981
2000
  end
1982
2001
  }
1983
2002
  )
@@ -58,6 +58,8 @@ Puppet::Face.define(:generate, '0.1.0') do
58
58
  Puppet::FileSystem::mkpath(outputdir)
59
59
 
60
60
  generator.generate(inputs, outputdir, options[:force])
61
+
62
+ exit(1) if generator.bad_input?
61
63
  nil
62
64
  end
63
65
  end
@@ -118,6 +118,9 @@ class Puppet::FileServing::Metadata < Puppet::FileServing::Base
118
118
  when "link"
119
119
  @destination = Puppet::FileSystem.readlink(real_path)
120
120
  @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", real_path).to_s rescue nil
121
+ when "fifo", "socket"
122
+ @checksum_type = "none"
123
+ @checksum = ("{#{@checksum_type}}") + send("#{@checksum_type}_file", real_path).to_s
121
124
  else
122
125
  raise ArgumentError, _("Cannot manage files of type %{file_type}") % { file_type: stat.ftype }
123
126
  end
@@ -130,23 +130,23 @@ class Puppet::FileSystem::FileImpl
130
130
  end
131
131
 
132
132
  def symlink?(path)
133
- File.symlink?(path)
133
+ ::File.symlink?(path)
134
134
  end
135
135
 
136
136
  def readlink(path)
137
- File.readlink(path)
137
+ ::File.readlink(path)
138
138
  end
139
139
 
140
140
  def unlink(*paths)
141
- File.unlink(*paths)
141
+ ::File.unlink(*paths)
142
142
  end
143
143
 
144
144
  def stat(path)
145
- File.stat(path)
145
+ ::File.stat(path)
146
146
  end
147
147
 
148
148
  def lstat(path)
149
- File.lstat(path)
149
+ ::File.lstat(path)
150
150
  end
151
151
 
152
152
  def compare_stream(path, stream)
@@ -159,7 +159,7 @@ class Puppet::FileSystem::FileImpl
159
159
 
160
160
  def replace_file(path, mode = nil)
161
161
  begin
162
- stat = Puppet::FileSystem.lstat(path)
162
+ stat = lstat(path)
163
163
  gid = stat.gid
164
164
  uid = stat.uid
165
165
  mode ||= stat.mode & 07777
@@ -180,7 +180,7 @@ class Puppet::FileSystem::FileImpl
180
180
  tempfile_path = tempfile.path
181
181
  FileUtils.chown(uid, gid, tempfile_path) if uid && gid
182
182
  chmod(mode, tempfile_path)
183
- File.rename(tempfile_path, Puppet::FileSystem.path_string(path))
183
+ ::File.rename(tempfile_path, path_string(path))
184
184
  ensure
185
185
  tempfile.close!
186
186
  end
@@ -14,7 +14,7 @@ class Puppet::FileSystem::JRuby < Puppet::FileSystem::Posix
14
14
  def replace_file(path, mode = nil, &block)
15
15
  # MRI Ruby rename checks if destination is a directory and raises, while
16
16
  # JRuby removes the directory and replaces the file.
17
- if Puppet::FileSystem.directory?(path)
17
+ if directory?(path)
18
18
  raise Errno::EISDIR, _("Is a directory: %{directory}") % { directory: path }
19
19
  end
20
20