puppet 4.10.1-universal-darwin → 4.10.4-universal-darwin
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/ext/project_data.yaml +1 -1
- data/lib/puppet.rb +40 -28
- data/lib/puppet/application/agent.rb +1 -1
- data/lib/puppet/application/apply.rb +1 -1
- data/lib/puppet/application/cert.rb +1 -1
- data/lib/puppet/application/describe.rb +1 -1
- data/lib/puppet/application/device.rb +1 -1
- data/lib/puppet/application/doc.rb +3 -3
- data/lib/puppet/application/filebucket.rb +1 -1
- data/lib/puppet/application/inspect.rb +2 -2
- data/lib/puppet/application/lookup.rb +1 -1
- data/lib/puppet/application/master.rb +1 -1
- data/lib/puppet/application/resource.rb +7 -7
- data/lib/puppet/defaults.rb +1 -1
- data/lib/puppet/etc.rb +75 -39
- data/lib/puppet/face/ca.rb +1 -1
- data/lib/puppet/face/catalog.rb +1 -1
- data/lib/puppet/face/certificate.rb +1 -1
- data/lib/puppet/face/certificate_request.rb +1 -1
- data/lib/puppet/face/certificate_revocation_list.rb +1 -1
- data/lib/puppet/face/config.rb +1 -1
- data/lib/puppet/face/epp.rb +1 -1
- data/lib/puppet/face/facts.rb +1 -1
- data/lib/puppet/face/file.rb +1 -1
- data/lib/puppet/face/help.rb +1 -1
- data/lib/puppet/face/key.rb +1 -1
- data/lib/puppet/face/man.rb +2 -2
- data/lib/puppet/face/module.rb +1 -1
- data/lib/puppet/face/node.rb +1 -1
- data/lib/puppet/face/parser.rb +1 -1
- data/lib/puppet/face/plugin.rb +1 -1
- data/lib/puppet/face/report.rb +1 -1
- data/lib/puppet/face/resource.rb +1 -1
- data/lib/puppet/face/resource_type.rb +1 -1
- data/lib/puppet/face/status.rb +1 -1
- data/lib/puppet/feature/base.rb +1 -1
- data/lib/puppet/functions/eyaml_lookup_key.rb +16 -12
- data/lib/puppet/functions/hiera.rb +9 -2
- data/lib/puppet/functions/hiera_array.rb +9 -2
- data/lib/puppet/functions/hiera_hash.rb +10 -2
- data/lib/puppet/functions/hiera_include.rb +17 -3
- data/lib/puppet/functions/hocon_data.rb +6 -0
- data/lib/puppet/functions/json_data.rb +4 -0
- data/lib/puppet/functions/yaml_data.rb +4 -0
- data/lib/puppet/generate/models/type/type.rb +6 -5
- data/lib/puppet/generate/templates/type/pcore.erb +1 -1
- data/lib/puppet/module_tool/skeleton/templates/generator/examples/init.pp.erb +1 -1
- data/lib/puppet/parser/functions/create_resources.rb +8 -0
- data/lib/puppet/parser/scope.rb +2 -2
- data/lib/puppet/pops/adapters.rb +10 -4
- data/lib/puppet/pops/evaluator/runtime3_resource_support.rb +0 -2
- data/lib/puppet/pops/evaluator/runtime3_support.rb +31 -0
- data/lib/puppet/pops/issues.rb +8 -0
- data/lib/puppet/pops/loader/loader.rb +4 -0
- data/lib/puppet/pops/loader/module_loaders.rb +0 -2
- data/lib/puppet/pops/loader/static_loader.rb +1 -1
- data/lib/puppet/pops/loader/type_definition_instantiator.rb +1 -1
- data/lib/puppet/pops/loader/typed_name.rb +1 -0
- data/lib/puppet/pops/loaders.rb +7 -15
- data/lib/puppet/pops/lookup/environment_data_provider.rb +1 -1
- data/lib/puppet/pops/lookup/hiera_config.rb +3 -1
- data/lib/puppet/pops/lookup/interpolation.rb +2 -1
- data/lib/puppet/pops/lookup/lookup_key.rb +1 -1
- data/lib/puppet/pops/lookup/module_data_provider.rb +10 -2
- data/lib/puppet/pops/lookup/sub_lookup.rb +10 -9
- data/lib/puppet/pops/parser/lexer2.rb +20 -3
- data/lib/puppet/pops/pcore.rb +2 -2
- data/lib/puppet/pops/resource/resource_type_impl.rb +2 -2
- data/lib/puppet/pops/semantic_error.rb +12 -0
- data/lib/puppet/pops/serialization/deserializer.rb +7 -4
- data/lib/puppet/pops/types/p_type_set_type.rb +2 -2
- data/lib/puppet/pops/types/string_converter.rb +5 -17
- data/lib/puppet/pops/types/type_set_reference.rb +1 -1
- data/lib/puppet/pops/validation/checker4_0.rb +4 -0
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
- data/lib/puppet/provider/nameservice.rb +12 -4
- data/lib/puppet/provider/package/yum.rb +8 -8
- data/lib/puppet/provider/user/useradd.rb +1 -1
- data/lib/puppet/reference/configuration.rb +1 -1
- data/lib/puppet/resource.rb +9 -11
- data/lib/puppet/resource/type_collection.rb +1 -0
- data/lib/puppet/type/exec.rb +32 -26
- data/lib/puppet/type/file/mode.rb +4 -0
- data/lib/puppet/util/character_encoding.rb +77 -74
- data/lib/puppet/util/monkey_patches.rb +3 -1
- data/lib/puppet/util/windows/api_types.rb +3 -0
- data/lib/puppet/util/windows/file.rb +1 -1
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +31 -7
- data/spec/integration/faces/documentation_spec.rb +2 -2
- data/spec/integration/parser/pcore_resource_spec.rb +15 -0
- data/spec/integration/resource/type_collection_spec.rb +6 -0
- data/spec/lib/puppet/face/1.0.0/huzzah.rb +1 -1
- data/spec/lib/puppet/face/basetest.rb +1 -1
- data/spec/lib/puppet/face/huzzah.rb +1 -1
- data/spec/lib/puppet/face/version_matching.rb +1 -1
- data/spec/lib/puppet_spec/character_encoding.rb +12 -0
- data/spec/lib/puppet_spec/compiler.rb +7 -0
- data/spec/shared_examples/rhel_package_provider.rb +10 -11
- data/spec/unit/application/resource_spec.rb +22 -1
- data/spec/unit/configurer/fact_handler_spec.rb +2 -1
- data/spec/unit/etc_spec.rb +361 -153
- data/spec/unit/functions/lookup_spec.rb +118 -2
- data/spec/unit/parser/functions/create_resources_spec.rb +47 -6
- data/spec/unit/parser/scope_spec.rb +8 -0
- data/spec/unit/pops/evaluator/evaluating_parser_spec.rb +40 -0
- data/spec/unit/pops/loaders/loaders_spec.rb +141 -79
- data/spec/unit/pops/lookup/interpolation_spec.rb +49 -9
- data/spec/unit/pops/lookup/lookup_spec.rb +32 -0
- data/spec/unit/pops/parser/lexer2_spec.rb +28 -0
- data/spec/unit/pops/types/p_object_type_spec.rb +1 -1
- data/spec/unit/pops/types/p_type_set_type_spec.rb +1 -1
- data/spec/unit/pops/types/string_converter_spec.rb +21 -0
- data/spec/unit/pops/validator/validator_spec.rb +43 -0
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +2 -0
- data/spec/unit/provider/nameservice_spec.rb +113 -3
- data/spec/unit/provider/user/useradd_spec.rb +13 -0
- data/spec/unit/resource/catalog_spec.rb +21 -0
- data/spec/unit/util/character_encoding_spec.rb +193 -52
- metadata +4 -2
@@ -155,7 +155,7 @@ class ResourceTypeImpl
|
|
155
155
|
# TechDebt: The case of having one namevar and an empty title patterns is unspecified behavior in puppet.
|
156
156
|
# Here, it may lead to an empty map which may or may not trigger the wanted/expected behavior.
|
157
157
|
#
|
158
|
-
@title_patterns_hash.map {|k,v| [ k,
|
158
|
+
@title_patterns_hash.map { |k,v| [ k, v.map { |n| [ n.to_sym ] } ] }
|
159
159
|
end
|
160
160
|
else
|
161
161
|
if @title_patterns_hash.nil? || @title_patterns_hash.empty?
|
@@ -166,7 +166,7 @@ class ResourceTypeImpl
|
|
166
166
|
#
|
167
167
|
raise Puppet::DevError,"you must specify title patterns when there are two or more key attributes"
|
168
168
|
end
|
169
|
-
@title_patterns_hash.nil? ? [] : @title_patterns_hash.map {|k,v| [ k,
|
169
|
+
@title_patterns_hash.nil? ? [] : @title_patterns_hash.map { |k,v| [ k, v.map { |n| [ n.to_sym] } ] }
|
170
170
|
end
|
171
171
|
end
|
172
172
|
|
@@ -47,10 +47,13 @@ module Serialization
|
|
47
47
|
result = type.read(val.attribute_count, self)
|
48
48
|
if result.is_a?(Types::PObjectType)
|
49
49
|
existing_type = loader.load(:type, result.name)
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
50
|
+
if result.eql?(existing_type)
|
51
|
+
result = existing_type
|
52
|
+
else
|
53
|
+
# Add result to the loader unless it is equal to the existing_type. The add
|
54
|
+
# will only succeed when the existing_type is nil.
|
55
|
+
loader.add_entry(:type, result.name, result, nil)
|
56
|
+
end
|
54
57
|
end
|
55
58
|
result
|
56
59
|
when Extension::ObjectStart
|
@@ -279,7 +279,7 @@ class PTypeSetType < PMetaType
|
|
279
279
|
if types.is_a?(Hash)
|
280
280
|
types.each do |type_name, value|
|
281
281
|
full_name = "#{@name}::#{type_name}".freeze
|
282
|
-
typed_name = Loader::TypedName.new(:type, full_name
|
282
|
+
typed_name = Loader::TypedName.new(:type, full_name, name_auth)
|
283
283
|
type = Loader::TypeDefinitionInstantiator.create_type(full_name, value, name_auth)
|
284
284
|
loader.set_entry(typed_name, type, Adapters::SourcePosAdapter.adapt(value).to_uri)
|
285
285
|
types[type_name] = type
|
@@ -300,7 +300,7 @@ class PTypeSetType < PMetaType
|
|
300
300
|
if types.is_a?(Hash)
|
301
301
|
types.each do |type_name, value|
|
302
302
|
full_name = "#{@name}::#{type_name}".freeze
|
303
|
-
typed_name = Loader::TypedName.new(:type, full_name
|
303
|
+
typed_name = Loader::TypedName.new(:type, full_name, name_auth)
|
304
304
|
meta_name = value.is_a?(Hash) ? 'Object' : 'TypeAlias'
|
305
305
|
type = Loader::TypeDefinitionInstantiator.create_named_type(full_name, meta_name, value, name_auth)
|
306
306
|
loader.set_entry(typed_name, type)
|
@@ -544,25 +544,12 @@ class StringConverter
|
|
544
544
|
when :s
|
545
545
|
val.to_s
|
546
546
|
when :q
|
547
|
-
val.
|
548
|
-
when :puppet
|
549
|
-
puppet_safe(val.to_s)
|
550
|
-
when :i, :d, :x, :o, :f, :puppet
|
551
|
-
converted = convert(o, PNumericType) # rest is default
|
552
|
-
"%#{f}" % converted
|
547
|
+
val.inspect
|
553
548
|
else
|
554
|
-
raise FormatError.new('Runtime', f.format, '
|
549
|
+
raise FormatError.new('Runtime', f.format, 'sq')
|
555
550
|
end
|
556
551
|
end
|
557
552
|
|
558
|
-
# Given an unsafe string make it safe for puppet
|
559
|
-
def puppet_safe(str)
|
560
|
-
str = str.inspect # all specials are now quoted
|
561
|
-
# all $ variables must be quoted
|
562
|
-
str.gsub!("\$", "\\\$")
|
563
|
-
str
|
564
|
-
end
|
565
|
-
|
566
553
|
# Basically string_PAnyType converts the value to a String and then formats it according
|
567
554
|
# to the resulting type
|
568
555
|
#
|
@@ -839,8 +826,9 @@ class StringConverter
|
|
839
826
|
f = get_format(val_type, format_map)
|
840
827
|
case f.format
|
841
828
|
when :p
|
842
|
-
|
843
|
-
|
829
|
+
rx_s = val.options == 0 ? val.source : val.to_s
|
830
|
+
rx_s = rx_s.gsub(/\//, '\/') unless Gem::Version.new(RUBY_VERSION.dup) < Gem::Version.new('2.0.0')
|
831
|
+
str_regexp = "/#{rx_s}/"
|
844
832
|
f.orig_fmt == '%p' ? str_regexp : Kernel.format(f.orig_fmt.gsub('p', 's'), str_regexp)
|
845
833
|
when :s
|
846
834
|
str_regexp = val.options == 0 ? val.source : val.to_s
|
@@ -37,7 +37,7 @@ class TypeSetReference
|
|
37
37
|
end
|
38
38
|
|
39
39
|
def resolve(type_parser, loader)
|
40
|
-
typed_name = Loader::TypedName.new(:type, @name
|
40
|
+
typed_name = Loader::TypedName.new(:type, @name, @name_authority)
|
41
41
|
loaded_entry = loader.load_typed(typed_name)
|
42
42
|
type_set = loaded_entry.nil? ? nil : loaded_entry.value
|
43
43
|
|
@@ -626,6 +626,10 @@ class Checker4_0 < Evaluator::LiteralEvaluator
|
|
626
626
|
# to enable better error message of the result of the expression rather than the static instruction.
|
627
627
|
# (This can be revised as there are static constructs that are illegal, but require updating many
|
628
628
|
# tests that expect the detailed reporting).
|
629
|
+
type_name_expr = o.type_name
|
630
|
+
if o.form && o.form != :regular && type_name_expr.is_a?(Model::QualifiedName) && type_name_expr.value == 'class'
|
631
|
+
acceptor.accept(Issues::CLASS_NOT_VIRTUALIZABLE, o)
|
632
|
+
end
|
629
633
|
end
|
630
634
|
|
631
635
|
def check_ResourceBody(o)
|
@@ -31,6 +31,7 @@ class ValidatorFactory_4_0 < Factory
|
|
31
31
|
p[Issues::DUPLICATE_DEFAULT] = Puppet[:strict] == :off ? :ignore : Puppet[:strict]
|
32
32
|
p[Issues::NAME_WITH_HYPHEN] = :error
|
33
33
|
p[Issues::EMPTY_RESOURCE_SPECIALIZATION] = :ignore
|
34
|
+
p[Issues::CLASS_NOT_VIRTUALIZABLE] = Puppet[:strict] == :off ? :warning : Puppet[:strict]
|
34
35
|
p
|
35
36
|
end
|
36
37
|
end
|
@@ -24,10 +24,12 @@ class Puppet::Provider::NameService < Puppet::Provider
|
|
24
24
|
|
25
25
|
def instances
|
26
26
|
objects = []
|
27
|
-
|
28
|
-
|
27
|
+
Puppet::Etc.send("set#{section}ent")
|
28
|
+
begin
|
29
|
+
while ent = Puppet::Etc.send("get#{section}ent")
|
30
|
+
objects << new(:name => ent.name, :canonical_name => ent.canonical_name, :ensure => :present)
|
31
|
+
end
|
29
32
|
end
|
30
|
-
|
31
33
|
objects
|
32
34
|
end
|
33
35
|
|
@@ -51,6 +53,7 @@ class Puppet::Provider::NameService < Puppet::Provider
|
|
51
53
|
# List everything out by name. Abstracted a bit so that it works
|
52
54
|
# for both users and groups.
|
53
55
|
def listbyname
|
56
|
+
Puppet.deprecation_warning(_("listbyname is deprecated and will be removed in a future release of Puppet. Please use `self.instances` to obtain a list of users."))
|
54
57
|
names = []
|
55
58
|
Puppet::Etc.send("set#{section()}ent")
|
56
59
|
begin
|
@@ -226,7 +229,7 @@ class Puppet::Provider::NameService < Puppet::Provider
|
|
226
229
|
if @objectinfo.nil? or refresh == true
|
227
230
|
@etcmethod ||= ("get" + self.class.section.to_s + "nam").intern
|
228
231
|
begin
|
229
|
-
@objectinfo = Puppet::Etc.send(@etcmethod, @
|
232
|
+
@objectinfo = Puppet::Etc.send(@etcmethod, @canonical_name)
|
230
233
|
rescue ArgumentError
|
231
234
|
@objectinfo = nil
|
232
235
|
end
|
@@ -276,6 +279,11 @@ class Puppet::Provider::NameService < Puppet::Provider
|
|
276
279
|
super
|
277
280
|
@custom_environment = {}
|
278
281
|
@objectinfo = nil
|
282
|
+
if resource.is_a?(Hash) && !resource[:canonical_name].nil?
|
283
|
+
@canonical_name = resource[:canonical_name]
|
284
|
+
else
|
285
|
+
@canonical_name = resource[:name]
|
286
|
+
end
|
279
287
|
end
|
280
288
|
|
281
289
|
def set(param, value)
|
@@ -39,17 +39,17 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
|
|
39
39
|
#
|
40
40
|
# @api private
|
41
41
|
# @param package [String] The name of the package to query
|
42
|
-
# @param enablerepo [Array<String>] A list of repositories to enable for this query
|
43
42
|
# @param disablerepo [Array<String>] A list of repositories to disable for this query
|
43
|
+
# @param enablerepo [Array<String>] A list of repositories to enable for this query
|
44
44
|
# @param disableexcludes [Array<String>] A list of repository excludes to disable for this query
|
45
45
|
# @return [Hash<Symbol, String>]
|
46
|
-
def self.latest_package_version(package,
|
46
|
+
def self.latest_package_version(package, disablerepo, enablerepo, disableexcludes)
|
47
47
|
|
48
|
-
key = [
|
48
|
+
key = [disablerepo, enablerepo, disableexcludes]
|
49
49
|
|
50
50
|
@latest_versions ||= {}
|
51
51
|
if @latest_versions[key].nil?
|
52
|
-
@latest_versions[key] = check_updates(
|
52
|
+
@latest_versions[key] = check_updates(disablerepo, enablerepo, disableexcludes)
|
53
53
|
end
|
54
54
|
|
55
55
|
if @latest_versions[key][package]
|
@@ -61,15 +61,15 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
|
|
61
61
|
# combination of repositories to enable and disable.
|
62
62
|
#
|
63
63
|
# @api private
|
64
|
-
# @param enablerepo [Array<String>] A list of repositories to enable for this query
|
65
64
|
# @param disablerepo [Array<String>] A list of repositories to disable for this query
|
65
|
+
# @param enablerepo [Array<String>] A list of repositories to enable for this query
|
66
66
|
# @param disableexcludes [Array<String>] A list of repository excludes to disable for this query
|
67
67
|
# @return [Hash<String, Array<Hash<String, String>>>] All packages that were
|
68
68
|
# found with a list of found versions for each package.
|
69
|
-
def self.check_updates(
|
69
|
+
def self.check_updates(disablerepo, enablerepo, disableexcludes)
|
70
70
|
args = [command(:cmd), 'check-update']
|
71
|
-
args.concat(enablerepo.map { |repo| ["--enablerepo=#{repo}"] }.flatten)
|
72
71
|
args.concat(disablerepo.map { |repo| ["--disablerepo=#{repo}"] }.flatten)
|
72
|
+
args.concat(enablerepo.map { |repo| ["--enablerepo=#{repo}"] }.flatten)
|
73
73
|
args.concat(disableexcludes.map { |repo| ["--disableexcludes=#{repo}"] }.flatten)
|
74
74
|
|
75
75
|
output = Puppet::Util::Execution.execute(args, :failonfail => false, :combine => false)
|
@@ -213,7 +213,7 @@ Puppet::Type.type(:package).provide :yum, :parent => :rpm, :source => :rpm do
|
|
213
213
|
|
214
214
|
# What's the latest package version available?
|
215
215
|
def latest
|
216
|
-
upd = self.class.latest_package_version(@resource[:name],
|
216
|
+
upd = self.class.latest_package_version(@resource[:name], disablerepo, enablerepo, disableexcludes)
|
217
217
|
unless upd.nil?
|
218
218
|
# FIXME: there could be more than one update for a package
|
219
219
|
# because of multiarch
|
@@ -203,7 +203,7 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
|
|
203
203
|
[:expiry, :password_min_age, :password_max_age, :password].each do |shadow_property|
|
204
204
|
define_method(shadow_property) do
|
205
205
|
if Puppet.features.libshadow?
|
206
|
-
if ent = Shadow::Passwd.getspnam(@
|
206
|
+
if ent = Shadow::Passwd.getspnam(@canonical_name)
|
207
207
|
method = self.class.option(shadow_property, :method)
|
208
208
|
return unmunge(shadow_property, ent.send(method))
|
209
209
|
end
|
@@ -32,7 +32,7 @@ config = Puppet::Util::Reference.newreference(:configuration, :depth => 1, :doc
|
|
32
32
|
val = 'Unix/Linux: /var/run/puppetlabs -- Windows: C:\ProgramData\PuppetLabs\puppet\var\run -- Non-root user: ~/.puppetlabs/var/run'
|
33
33
|
elsif name.to_s == 'logdir'
|
34
34
|
val = 'Unix/Linux: /var/log/puppetlabs/puppet -- Windows: C:\ProgramData\PuppetLabs\puppet\var\log -- Non-root user: ~/.puppetlabs/var/log'
|
35
|
-
elsif name.to_s == '
|
35
|
+
elsif name.to_s == 'hiera_config'
|
36
36
|
val = '$confdir/hiera.yaml. However, if a file exists at $codedir/hiera.yaml, Puppet uses that instead.'
|
37
37
|
end
|
38
38
|
|
data/lib/puppet/resource.rb
CHANGED
@@ -168,25 +168,23 @@ class Puppet::Resource
|
|
168
168
|
end
|
169
169
|
|
170
170
|
def self.value_to_pson_data(value)
|
171
|
-
if value.is_a?
|
171
|
+
if value.is_a?(Array)
|
172
172
|
value.map{|v| value_to_pson_data(v) }
|
173
|
-
elsif value.is_a?
|
173
|
+
elsif value.is_a?(Hash)
|
174
|
+
result = {}
|
175
|
+
value.each_pair { |k, v| result[value_to_pson_data(k)] = value_to_pson_data(v) }
|
176
|
+
result
|
177
|
+
elsif value.is_a?(Puppet::Resource)
|
174
178
|
value.to_s
|
179
|
+
elsif value.is_a?(Symbol) && value == :undef
|
180
|
+
nil
|
175
181
|
else
|
176
182
|
value
|
177
183
|
end
|
178
184
|
end
|
179
185
|
|
180
186
|
def yaml_property_munge(x)
|
181
|
-
|
182
|
-
when Hash
|
183
|
-
x.inject({}) { |h,kv|
|
184
|
-
k,v = kv
|
185
|
-
h[k] = self.class.value_to_pson_data(v)
|
186
|
-
h
|
187
|
-
}
|
188
|
-
else self.class.value_to_pson_data(x)
|
189
|
-
end
|
187
|
+
self.value.to_pson_data(x)
|
190
188
|
end
|
191
189
|
|
192
190
|
YAML_ATTRIBUTES = [:@file, :@line, :@exported, :@type, :@title, :@tags, :@parameters]
|
@@ -231,6 +231,7 @@ class Puppet::Resource::TypeCollection
|
|
231
231
|
debug_once "Not attempting to load #{type} #{fqname} as this object was missing during a prior compilation"
|
232
232
|
end
|
233
233
|
else
|
234
|
+
fqname = munge_name(fqname)
|
234
235
|
result = loader.try_load_fqname(type, fqname)
|
235
236
|
@notfound[ fqname ] = result.nil?
|
236
237
|
end
|
data/lib/puppet/type/exec.rb
CHANGED
@@ -241,10 +241,14 @@ module Puppet
|
|
241
241
|
end
|
242
242
|
|
243
243
|
newparam(:refresh) do
|
244
|
-
desc "
|
245
|
-
|
246
|
-
|
247
|
-
for
|
244
|
+
desc "An alternate command to run when the `exec` receives a refresh event
|
245
|
+
from another resource. By default, Puppet runs the main command again.
|
246
|
+
For more details, see the notes about refresh behavior above, in the
|
247
|
+
description for this resource type.
|
248
|
+
|
249
|
+
Note that this alternate command runs with the same `provider`, `path`,
|
250
|
+
`user`, and `group` as the main command. If the `path` isn't set, you
|
251
|
+
must fully qualify the command's name."
|
248
252
|
|
249
253
|
validate do |command|
|
250
254
|
provider.validatecmd(command)
|
@@ -406,8 +410,10 @@ module Puppet
|
|
406
410
|
|
407
411
|
newcheck(:unless) do
|
408
412
|
desc <<-'EOT'
|
409
|
-
|
410
|
-
the
|
413
|
+
A test command that checks the state of the target system and restricts
|
414
|
+
when the `exec` can run. If present, Puppet runs this test command
|
415
|
+
first, then runs the main command unless the test has an exit code of 0
|
416
|
+
(success). For example:
|
411
417
|
|
412
418
|
exec { '/bin/echo root >> /usr/lib/cron/cron.allow':
|
413
419
|
path => '/usr/bin:/usr/sbin:/bin',
|
@@ -417,17 +423,16 @@ module Puppet
|
|
417
423
|
This would add `root` to the cron.allow file (on Solaris) unless
|
418
424
|
`grep` determines it's already there.
|
419
425
|
|
420
|
-
Note that this command
|
421
|
-
|
422
|
-
|
423
|
-
It also uses the same provider as the main command, so any behavior
|
424
|
-
that differs by provider will match.
|
426
|
+
Note that this test command runs with the same `provider`, `path`,
|
427
|
+
`user`, and `group` as the main command. If the `path` isn't set, you
|
428
|
+
must fully qualify the command's name.
|
425
429
|
|
426
|
-
|
430
|
+
This parameter can also take an array of commands. For example:
|
427
431
|
|
428
432
|
unless => ['test -f /tmp/file1', 'test -f /tmp/file2'],
|
429
433
|
|
430
|
-
This
|
434
|
+
This `exec` would only run if every command in the array has a
|
435
|
+
non-zero exit code.
|
431
436
|
EOT
|
432
437
|
|
433
438
|
validate do |cmds|
|
@@ -457,28 +462,29 @@ module Puppet
|
|
457
462
|
|
458
463
|
newcheck(:onlyif) do
|
459
464
|
desc <<-'EOT'
|
460
|
-
|
461
|
-
the
|
465
|
+
A test command that checks the state of the target system and restricts
|
466
|
+
when the `exec` can run. If present, Puppet runs this test command
|
467
|
+
first, and only runs the main command if the test has an exit code of 0
|
468
|
+
(success). For example:
|
462
469
|
|
463
470
|
exec { 'logrotate':
|
464
|
-
path
|
465
|
-
|
471
|
+
path => '/usr/bin:/usr/sbin:/bin',
|
472
|
+
provider => shell,
|
473
|
+
onlyif => 'test `du /var/log/messages | cut -f1` -gt 100000',
|
466
474
|
}
|
467
475
|
|
468
|
-
This would run `logrotate` only if that test
|
469
|
-
|
470
|
-
Note that this command follows the same rules as the main command,
|
471
|
-
such as which user and group it's run as.
|
472
|
-
This also means it must be fully qualified if the path is not set.
|
476
|
+
This would run `logrotate` only if that test returns true.
|
473
477
|
|
474
|
-
|
475
|
-
|
478
|
+
Note that this test command runs with the same `provider`, `path`,
|
479
|
+
`user`, and `group` as the main command. If the `path` isn't set, you
|
480
|
+
must fully qualify the command's name.
|
476
481
|
|
477
|
-
|
482
|
+
This parameter can also take an array of commands. For example:
|
478
483
|
|
479
484
|
onlyif => ['test -f /tmp/file1', 'test -f /tmp/file2'],
|
480
485
|
|
481
|
-
This
|
486
|
+
This `exec` would only run if every command in the array has an
|
487
|
+
exit code of 0 (success).
|
482
488
|
EOT
|
483
489
|
|
484
490
|
validate do |cmds|
|
@@ -13,6 +13,10 @@ module Puppet
|
|
13
13
|
notation. This value **must** be specified as a string; do not use
|
14
14
|
un-quoted numbers to represent file modes.
|
15
15
|
|
16
|
+
If the mode is omitted (or explicitly set to `undef`), Puppet does not
|
17
|
+
enforce permissions on existing files and creates new files with
|
18
|
+
permissions of `0644`.
|
19
|
+
|
16
20
|
The `file` type uses traditional Unix permission schemes and translates
|
17
21
|
them to equivalent permissions for systems which represent permissions
|
18
22
|
differently, including Windows. For detailed ACL controls on Windows,
|
@@ -2,94 +2,97 @@
|
|
2
2
|
|
3
3
|
module Puppet::Util::CharacterEncoding
|
4
4
|
class << self
|
5
|
-
#
|
5
|
+
# Given a string, attempts to convert a copy of the string to UTF-8. Conversion uses
|
6
|
+
# encode - the string's internal byte representation is modifed to UTF-8.
|
7
|
+
#
|
8
|
+
# This method is intended for situations where we generally trust that the
|
9
|
+
# string's bytes are a faithful representation of the current encoding
|
10
|
+
# associated with it, and can use it as a starting point for transcoding
|
11
|
+
# (conversion) to UTF-8.
|
12
|
+
#
|
6
13
|
# @api public
|
7
|
-
# @param [String] string a string to transcode
|
8
|
-
# @return [String] string
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
def convert_to_utf_8!(string)
|
13
|
-
currently_valid = string.valid_encoding?
|
14
|
-
|
14
|
+
# @param [String] string a string to transcode
|
15
|
+
# @return [String] copy of the original string, in UTF-8 if transcodable
|
16
|
+
def convert_to_utf_8(string)
|
17
|
+
original_encoding = string.encoding
|
18
|
+
string_copy = string.dup
|
15
19
|
begin
|
16
|
-
if
|
17
|
-
if
|
18
|
-
|
19
|
-
|
20
|
-
# If a string is currently believed to be UTF-8, but is also not
|
21
|
-
# valid_encoding?, we have no recourse but to fail because we have no
|
22
|
-
# idea what encoding this string originally came from where it *was*
|
23
|
-
# valid - all we know is it's not currently valid UTF-8.
|
24
|
-
raise EncodingError
|
20
|
+
if original_encoding == Encoding::UTF_8
|
21
|
+
if !string_copy.valid_encoding?
|
22
|
+
Puppet.debug(_("%{value} is already labeled as UTF-8 but this encoding is invalid. It cannot be transcoded by Puppet.") %
|
23
|
+
{ value: string.dump })
|
25
24
|
end
|
26
|
-
|
27
|
-
|
28
|
-
# currently constitued (in its non-UTF-8 encoding), and if it is, limit
|
29
|
-
# ourselves to setting the external encoding of the string to UTF-8
|
30
|
-
# rather than actually transcoding it. We do this to handle
|
31
|
-
# a couple scenarios:
|
32
|
-
|
33
|
-
# The first scenario is that the string was originally valid UTF-8 but
|
34
|
-
# the current puppet run is not in a UTF-8 environment. In this case,
|
35
|
-
# the string will likely have invalid byte sequences (i.e.,
|
36
|
-
# string.valid_encoding? == false), and attempting to transcode will
|
37
|
-
# fail with Encoding::InvalidByteSequenceError, referencing the
|
38
|
-
# invalid byte sequence in the original, pre-transcode, string. We
|
39
|
-
# might have gotten here, for example, if puppet is run first in a
|
40
|
-
# user context with UTF-8 encoding (setting the "is" value to UTF-8)
|
41
|
-
# and then later run via cron without UTF-8 specified, resulting in in
|
42
|
-
# EN_US (ISO-8859-1) on many systems. In this scenario we're
|
43
|
-
# effectively best-guessing this string originated as UTF-8 and only
|
44
|
-
# set external encoding to UTF-8 - transcoding would have failed
|
45
|
-
# anyway.
|
46
|
-
|
47
|
-
# The second scenario (more rare, I expect) is that this string does
|
48
|
-
# NOT have invalid byte sequences (string.valid_encoding? == true),
|
49
|
-
# but is *ALSO valid unicode*.
|
50
|
-
# Our example case is "\u16A0" - "RUNIC LETTER FEHU FEOH FE"
|
51
|
-
# http://www.fileformat.info/info/unicode/char/16A0/index.htm
|
52
|
-
# 0xE1 0x9A 0xA0 / 225 154 160
|
53
|
-
# These bytes are valid in ISO-8859-1 but the character they represent
|
54
|
-
# transcodes cleanly in ruby to *different* characters in UTF-8.
|
55
|
-
# That's not what we want if the user intended the original string as
|
56
|
-
# UTF-8. We can only guess, so if the string is valid UTF-8 as
|
57
|
-
# currently constituted, we default to assuming the string originated
|
58
|
-
# in UTF-8 and do not transcode it - we only set external encoding.
|
59
|
-
return string.force_encoding(Encoding::UTF_8)
|
60
|
-
elsif currently_valid
|
61
|
-
# If the string is not currently valid UTF-8 but it can be transcoded
|
62
|
-
# (it is valid in its current encoding), we can guess this string was
|
63
|
-
# not originally unicode. Transcode it to UTF-8. For strings with
|
64
|
-
# original encodings like SHIFT_JIS, this should be the final result.
|
65
|
-
return string.encode!(Encoding::UTF_8)
|
25
|
+
# String is aleady valid UTF-8 - noop
|
26
|
+
return string_copy
|
66
27
|
else
|
67
|
-
# If the string
|
68
|
-
#
|
69
|
-
|
28
|
+
# If the string comes to us as BINARY encoded, we don't know what it
|
29
|
+
# started as. However, to encode! we need a starting place, and our
|
30
|
+
# best guess is whatever the system currently is (default_external).
|
31
|
+
# So set external_encoding to default_external before we try to
|
32
|
+
# transcode to UTF-8.
|
33
|
+
string_copy.force_encoding(Encoding.default_external) if original_encoding == Encoding::BINARY
|
34
|
+
return string_copy.encode(Encoding::UTF_8)
|
70
35
|
end
|
71
36
|
rescue EncodingError => detail
|
37
|
+
# Set the encoding on our copy back to its original if we modified it
|
38
|
+
string_copy.force_encoding(original_encoding) if original_encoding == Encoding::BINARY
|
39
|
+
|
72
40
|
# Catch both our own self-determined failure to transcode as well as any
|
73
41
|
# error on ruby's part, ie Encoding::UndefinedConversionError on a
|
74
42
|
# failure to encode!.
|
75
|
-
Puppet.debug(_("%{error}: %{value}
|
43
|
+
Puppet.debug(_("%{error}: %{value} cannot be transcoded by Puppet.") %
|
76
44
|
{ error: detail.inspect, value: string.dump })
|
77
|
-
return
|
45
|
+
return string_copy
|
78
46
|
end
|
79
47
|
end
|
80
48
|
|
81
|
-
|
49
|
+
# Given a string, tests if that string's bytes represent valid UTF-8, and if
|
50
|
+
# so return a copy of the string with external enocding set to UTF-8. Does
|
51
|
+
# not modify the byte representation of the string. If the string does not
|
52
|
+
# represent valid UTF-8, does not set the external encoding.
|
53
|
+
#
|
54
|
+
# This method is intended for situations where we do not believe that the
|
55
|
+
# encoding associated with a string is an accurate reflection of its actual
|
56
|
+
# bytes, i.e., effectively when we believe Ruby is incorrect in its
|
57
|
+
# assertion of the encoding of the string.
|
58
|
+
#
|
59
|
+
# @api public
|
60
|
+
# @param [String] string to set external encoding (re-label) to utf-8
|
61
|
+
# @return [String] a copy of string with external encoding set to utf-8, or
|
62
|
+
# a copy of the original string if override would result in invalid encoding.
|
63
|
+
def override_encoding_to_utf_8(string)
|
64
|
+
string_copy = string.dup
|
65
|
+
original_encoding = string_copy.encoding
|
66
|
+
return string_copy if original_encoding == Encoding::UTF_8
|
67
|
+
if string_copy.force_encoding(Encoding::UTF_8).valid_encoding?
|
68
|
+
return string_copy
|
69
|
+
else
|
70
|
+
Puppet.debug(_("%{value} is not valid UTF-8 and result of overriding encoding would be invalid.") % { value: string.dump })
|
71
|
+
# Set copy back to its original encoding before returning
|
72
|
+
return string_copy.force_encoding(original_encoding)
|
73
|
+
end
|
74
|
+
end
|
82
75
|
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
76
|
+
REPLACEMENT_CHAR_MAP = {
|
77
|
+
Encoding::UTF_8 => "\uFFFD",
|
78
|
+
Encoding::UTF_16LE => "\xFD\xFF".force_encoding(Encoding::UTF_16LE),
|
79
|
+
}
|
80
|
+
|
81
|
+
# Given a string, return a copy of that string with any invalid byte
|
82
|
+
# sequences in its current encoding replaced with the replacement character
|
83
|
+
# "\uFFFD" (UTF-8) if the string is UTF-8 or UTF-16LE, or "?" otherwise.
|
84
|
+
# @param string a string to remove invalid byte sequences from
|
85
|
+
# @return a copy of string invalid byte sequences replaced by the unicode
|
86
|
+
# replacement character or "?" character
|
87
|
+
# @note does not modify encoding, but new string will have different bytes
|
88
|
+
# from original. Only needed for ruby 1.9.3 support.
|
89
|
+
def scrub(string)
|
90
|
+
if string.respond_to?(:scrub)
|
91
|
+
string.scrub
|
92
|
+
else
|
93
|
+
replacement_character = REPLACEMENT_CHAR_MAP[string.encoding] || '?'
|
94
|
+
string.chars.map { |c| c.valid_encoding? ? c : replacement_character }.join
|
95
|
+
end
|
93
96
|
end
|
94
97
|
end
|
95
98
|
end
|