puppet 5.5.20-universal-darwin → 5.5.21-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.
- checksums.yaml +4 -4
- data/Gemfile.lock +19 -19
- data/lib/puppet/agent.rb +3 -3
- data/lib/puppet/application/agent.rb +3 -1
- data/lib/puppet/daemon.rb +1 -1
- data/lib/puppet/defaults.rb +2 -2
- data/lib/puppet/file_system/uniquefile.rb +4 -0
- data/lib/puppet/network/http/api/indirected_routes.rb +1 -1
- data/lib/puppet/network/http/api/master/v3/environment.rb +3 -0
- data/lib/puppet/parser/compiler/catalog_validator/env_relationship_validator.rb +2 -0
- data/lib/puppet/parser/compiler/catalog_validator/site_validator.rb +2 -0
- data/lib/puppet/parser/environment_compiler.rb +3 -0
- data/lib/puppet/parser/resource.rb +3 -2
- data/lib/puppet/parser/resource/param.rb +6 -0
- data/lib/puppet/pops/issues.rb +5 -0
- data/lib/puppet/pops/resource/resource_type_impl.rb +2 -0
- data/lib/puppet/pops/validation/checker4_0.rb +10 -0
- data/lib/puppet/pops/validation/validator_factory_4_0.rb +1 -0
- data/lib/puppet/provider/package/dnfmodule.rb +24 -4
- data/lib/puppet/provider/package/pip.rb +6 -4
- data/lib/puppet/provider/package/zypper.rb +1 -0
- data/lib/puppet/provider/service/systemd.rb +22 -4
- data/lib/puppet/provider/user/useradd.rb +16 -5
- data/lib/puppet/resource/type.rb +8 -0
- data/lib/puppet/test/test_helper.rb +8 -10
- data/lib/puppet/type.rb +6 -0
- data/lib/puppet/type/package.rb +16 -1
- data/lib/puppet/type/service.rb +1 -7
- data/lib/puppet/type/user.rb +1 -7
- data/lib/puppet/util.rb +12 -13
- data/lib/puppet/util/log/destinations.rb +1 -10
- data/lib/puppet/util/windows/api_types.rb +45 -32
- data/lib/puppet/util/windows/eventlog.rb +1 -6
- data/lib/puppet/util/windows/principal.rb +8 -6
- data/lib/puppet/util/windows/registry.rb +11 -11
- data/lib/puppet/version.rb +1 -1
- data/locales/puppet.pot +97 -93
- data/man/man5/puppet.conf.5 +2 -2
- data/man/man8/puppet-agent.8 +2 -2
- data/man/man8/puppet-apply.8 +1 -1
- data/man/man8/puppet-ca.8 +1 -1
- data/man/man8/puppet-catalog.8 +1 -1
- data/man/man8/puppet-cert.8 +1 -1
- data/man/man8/puppet-certificate.8 +1 -1
- data/man/man8/puppet-certificate_request.8 +1 -1
- data/man/man8/puppet-certificate_revocation_list.8 +1 -1
- data/man/man8/puppet-config.8 +1 -1
- data/man/man8/puppet-describe.8 +1 -1
- data/man/man8/puppet-device.8 +1 -1
- data/man/man8/puppet-doc.8 +1 -1
- data/man/man8/puppet-epp.8 +1 -1
- data/man/man8/puppet-facts.8 +1 -1
- data/man/man8/puppet-filebucket.8 +1 -1
- data/man/man8/puppet-generate.8 +1 -1
- data/man/man8/puppet-help.8 +1 -1
- data/man/man8/puppet-key.8 +1 -1
- data/man/man8/puppet-lookup.8 +1 -1
- data/man/man8/puppet-man.8 +1 -1
- data/man/man8/puppet-master.8 +1 -1
- data/man/man8/puppet-module.8 +1 -1
- data/man/man8/puppet-node.8 +1 -1
- data/man/man8/puppet-parser.8 +1 -1
- data/man/man8/puppet-plugin.8 +1 -1
- data/man/man8/puppet-report.8 +1 -1
- data/man/man8/puppet-resource.8 +1 -1
- data/man/man8/puppet-script.8 +1 -1
- data/man/man8/puppet-status.8 +1 -1
- data/man/man8/puppet.8 +2 -2
- data/spec/fixtures/unit/provider/package/dnfmodule/{dnf-module-list-enabled.txt → dnf-module-list.txt} +6 -0
- data/spec/fixtures/unit/provider/service/systemd/list_unit_files_services +9 -0
- data/spec/integration/defaults_spec.rb +1 -2
- data/spec/integration/parser/compiler_spec.rb +11 -0
- data/spec/integration/util/windows/adsi_spec.rb +5 -0
- data/spec/integration/util/windows/registry_spec.rb +7 -7
- data/spec/unit/agent_spec.rb +1 -1
- data/spec/unit/daemon_spec.rb +0 -1
- data/spec/unit/file_system/uniquefile_spec.rb +11 -0
- data/spec/unit/network/http/api/indirected_routes_spec.rb +2 -1
- data/spec/unit/parser/environment_compiler_spec.rb +7 -0
- data/spec/unit/provider/package/dnfmodule_spec.rb +25 -5
- data/spec/unit/provider/package/pip_spec.rb +42 -16
- data/spec/unit/provider/package/zypper_spec.rb +13 -0
- data/spec/unit/provider/service/systemd_spec.rb +93 -20
- data/spec/unit/provider/user/openbsd_spec.rb +1 -0
- data/spec/unit/provider/user/useradd_spec.rb +30 -16
- data/spec/unit/test/test_helper_spec.rb +17 -0
- data/spec/unit/type/service_spec.rb +9 -8
- data/spec/unit/type/user_spec.rb +19 -13
- data/spec/unit/util/log/destinations_spec.rb +1 -29
- data/spec/unit/util/windows/api_types_spec.rb +104 -40
- metadata +7 -7
- data/spec/integration/test/test_helper_spec.rb +0 -31
@@ -26,7 +26,8 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
|
|
26
26
|
def self.instances
|
27
27
|
i = []
|
28
28
|
output = systemctl('list-unit-files', '--type', 'service', '--full', '--all', '--no-pager')
|
29
|
-
output.scan(/^(\S+)\s+(disabled|enabled|masked|indirect)\s*$/i).each do |m|
|
29
|
+
output.scan(/^(\S+)\s+(disabled|enabled|masked|indirect|bad|static)\s*$/i).each do |m|
|
30
|
+
Puppet.debug("#{m[0]} marked as bad by `systemctl`. It is recommended to be further checked.") if m[1] == "bad"
|
30
31
|
i << new(:name => m[0])
|
31
32
|
end
|
32
33
|
return i
|
@@ -34,6 +35,22 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
|
|
34
35
|
return []
|
35
36
|
end
|
36
37
|
|
38
|
+
# Static services cannot be enabled or disabled manually. Indirect services
|
39
|
+
# should not be enabled or disabled due to limitations in systemd (see
|
40
|
+
# https://github.com/systemd/systemd/issues/6681).
|
41
|
+
def enabled_insync?(current)
|
42
|
+
case cached_enabled?[:output]
|
43
|
+
when 'static'
|
44
|
+
Puppet.debug("Unable to enable or disable static service #{@resource[:name]}")
|
45
|
+
return true
|
46
|
+
when 'indirect'
|
47
|
+
Puppet.debug("Service #{@resource[:name]} is in 'indirect' state and cannot be enabled/disabled")
|
48
|
+
return true
|
49
|
+
else
|
50
|
+
current == @resource[:enable]
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
37
54
|
# This helper ensures that the enable state cache is always reset
|
38
55
|
# after a systemctl enable operation. A particular service state is not guaranteed
|
39
56
|
# after such an operation, so the cache must be emptied to prevent inconsistencies
|
@@ -65,12 +82,13 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
|
|
65
82
|
def cached_enabled?
|
66
83
|
return @cached_enabled if @cached_enabled
|
67
84
|
cmd = [command(:systemctl), 'is-enabled', '--', @resource[:name]]
|
68
|
-
|
85
|
+
result = execute(cmd, :failonfail => false)
|
86
|
+
@cached_enabled = { output: result.chomp, exitcode: result.exitstatus }
|
69
87
|
end
|
70
88
|
|
71
89
|
def enabled?
|
72
|
-
output = cached_enabled?
|
73
|
-
code =
|
90
|
+
output = cached_enabled?[:output]
|
91
|
+
code = cached_enabled?[:exitcode]
|
74
92
|
|
75
93
|
# The masked state is equivalent to the disabled state in terms of
|
76
94
|
# comparison so we only care to check if it is masked if we want to keep
|
@@ -21,7 +21,11 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
|
|
21
21
|
options :expiry, :method => :sp_expire,
|
22
22
|
:munge => proc { |value|
|
23
23
|
if value == :absent
|
24
|
-
''
|
24
|
+
if Facter.value(:operatingsystem)=='SLES' && Facter.value(:operatingsystemmajrelease) == "11"
|
25
|
+
-1
|
26
|
+
else
|
27
|
+
''
|
28
|
+
end
|
25
29
|
else
|
26
30
|
case Facter.value(:operatingsystem)
|
27
31
|
when 'Solaris'
|
@@ -134,10 +138,17 @@ Puppet::Type.type(:user).provide :useradd, :parent => Puppet::Provider::NameServ
|
|
134
138
|
|
135
139
|
def check_manage_home
|
136
140
|
cmd = []
|
137
|
-
if @resource.managehome?
|
138
|
-
|
139
|
-
|
140
|
-
|
141
|
+
if @resource.managehome?
|
142
|
+
# libuser does not implement the -m flag
|
143
|
+
cmd << "-m" unless @resource.forcelocal?
|
144
|
+
else
|
145
|
+
osfamily = Facter.value(:osfamily)
|
146
|
+
osversion = Facter.value(:operatingsystemmajrelease).to_i
|
147
|
+
# SLES 11 uses pwdutils instead of shadow, which does not have -M
|
148
|
+
# Solaris and OpenBSD use different useradd flavors
|
149
|
+
unless osfamily =~ /Solaris|OpenBSD/ || osfamily == 'Suse' && osversion <= 11
|
150
|
+
cmd << "-M"
|
151
|
+
end
|
141
152
|
end
|
142
153
|
cmd
|
143
154
|
end
|
data/lib/puppet/resource/type.rb
CHANGED
@@ -11,6 +11,7 @@ class Puppet::Resource::Type
|
|
11
11
|
include Puppet::Util::Warnings
|
12
12
|
include Puppet::Util::Errors
|
13
13
|
|
14
|
+
# @deprecated application orchestration will be removed in puppet 7 (capability_mapping, application, site)
|
14
15
|
RESOURCE_KINDS = [:hostclass, :node, :definition, :capability_mapping, :application, :site]
|
15
16
|
|
16
17
|
# Map the names used in our documentation to the names used internally
|
@@ -69,6 +70,8 @@ class Puppet::Resource::Type
|
|
69
70
|
|
70
71
|
# Evaluate the resources produced by the given resource. These resources are
|
71
72
|
# evaluated in a separate but identical scope from the rest of the resource.
|
73
|
+
#
|
74
|
+
# @deprecated application orchestration will be removed in puppet 7
|
72
75
|
def evaluate_produces(resource, scope)
|
73
76
|
# Only defined types and classes can produce capabilities
|
74
77
|
return unless definition? || hostclass?
|
@@ -159,19 +162,23 @@ class Puppet::Resource::Type
|
|
159
162
|
@module_name = options[:module_name]
|
160
163
|
end
|
161
164
|
|
165
|
+
# @deprecated application orchestration will be removed in puppet 7
|
162
166
|
def produces
|
163
167
|
@produces || EMPTY_ARRAY
|
164
168
|
end
|
165
169
|
|
170
|
+
# @deprecated application orchestration will be removed in puppet 7
|
166
171
|
def consumes
|
167
172
|
@consumes || EMPTY_ARRAY
|
168
173
|
end
|
169
174
|
|
175
|
+
# @deprecated application orchestration will be removed in puppet 7
|
170
176
|
def add_produces(blueprint)
|
171
177
|
@produces ||= []
|
172
178
|
@produces << blueprint
|
173
179
|
end
|
174
180
|
|
181
|
+
# @deprecated application orchestration will be removed in puppet 7
|
175
182
|
def add_consumes(blueprint)
|
176
183
|
@consumes ||= []
|
177
184
|
@consumes << blueprint
|
@@ -233,6 +240,7 @@ class Puppet::Resource::Type
|
|
233
240
|
when :node
|
234
241
|
:node
|
235
242
|
when :site
|
243
|
+
# @deprecated application orchestration will be removed in puppet 7
|
236
244
|
:site
|
237
245
|
end
|
238
246
|
|
@@ -68,7 +68,14 @@ module Puppet::Test
|
|
68
68
|
# any individual tests.
|
69
69
|
# @return nil
|
70
70
|
def self.before_all_tests()
|
71
|
-
#
|
71
|
+
# The process environment is a shared, persistent resource.
|
72
|
+
# Can't use Puppet.features.microsoft_windows? as it may be mocked out in a test. This can cause test recurring test failures
|
73
|
+
if (!!File::ALT_SEPARATOR)
|
74
|
+
mode = :windows
|
75
|
+
else
|
76
|
+
mode = :posix
|
77
|
+
end
|
78
|
+
$old_env = Puppet::Util.get_environment(mode)
|
72
79
|
end
|
73
80
|
|
74
81
|
# Call this method once, at the end of a test run, when no more tests
|
@@ -118,15 +125,6 @@ module Puppet::Test
|
|
118
125
|
}
|
119
126
|
end
|
120
127
|
|
121
|
-
# The process environment is a shared, persistent resource.
|
122
|
-
# Can't use Puppet.features.microsoft_windows? as it may be mocked out in a test. This can cause test recurring test failures
|
123
|
-
if (!!File::ALT_SEPARATOR)
|
124
|
-
mode = :windows
|
125
|
-
else
|
126
|
-
mode = :posix
|
127
|
-
end
|
128
|
-
$old_env = Puppet::Util.get_environment(mode)
|
129
|
-
|
130
128
|
# So is the load_path
|
131
129
|
$old_load_path = $LOAD_PATH.dup
|
132
130
|
|
data/lib/puppet/type.rb
CHANGED
@@ -110,8 +110,10 @@ class Type
|
|
110
110
|
|
111
111
|
# Allow declaring that a type is actually a capability
|
112
112
|
class << self
|
113
|
+
# @deprecated application orchestration will be removed in puppet 7
|
113
114
|
attr_accessor :is_capability
|
114
115
|
|
116
|
+
# @deprecated application orchestration will be removed in puppet 7
|
115
117
|
def is_capability?
|
116
118
|
c = is_capability
|
117
119
|
c.nil? ? false : c
|
@@ -123,6 +125,8 @@ class Type
|
|
123
125
|
# represent application instances, this implementation always returns
|
124
126
|
# +false+. Having this method though makes code checking whether a
|
125
127
|
# resource is an application instance simpler
|
128
|
+
#
|
129
|
+
# @deprecated application orchestration will be removed in puppet 7
|
126
130
|
def self.application?
|
127
131
|
false
|
128
132
|
end
|
@@ -1667,6 +1671,7 @@ class Type
|
|
1667
1671
|
}
|
1668
1672
|
end
|
1669
1673
|
|
1674
|
+
# @deprecated application orchestration will be removed in puppet 7
|
1670
1675
|
newmetaparam(:export, :parent => RelationshipMetaparam, :attributes => {:direction => :out, :events => :NONE}) do
|
1671
1676
|
desc <<EOS
|
1672
1677
|
Export a capability resource.
|
@@ -1692,6 +1697,7 @@ web { server:
|
|
1692
1697
|
EOS
|
1693
1698
|
end
|
1694
1699
|
|
1700
|
+
# @deprecated application orchestration will be removed in puppet 7
|
1695
1701
|
newmetaparam(:consume, :parent => RelationshipMetaparam, :attributes => {:direction => :in, :events => :NONE}) do
|
1696
1702
|
desc <<EOS
|
1697
1703
|
Consume a capability resource.
|
data/lib/puppet/type/package.rb
CHANGED
@@ -61,6 +61,9 @@ module Puppet
|
|
61
61
|
passed to the installer command."
|
62
62
|
feature :uninstall_options, "The provider accepts options to be
|
63
63
|
passed to the uninstaller command."
|
64
|
+
feature :disableable, "The provider can disable packages. This feature is used by specifying `disabled` as the
|
65
|
+
desired value for the package.",
|
66
|
+
:methods => [:disable]
|
64
67
|
feature :supports_flavors, "The provider accepts flavors, which are specific variants of packages."
|
65
68
|
feature :package_settings, "The provider accepts package_settings to be
|
66
69
|
ensured for the given package. The meaning and format of these settings is
|
@@ -104,6 +107,10 @@ module Puppet
|
|
104
107
|
provider.deprecated_hold
|
105
108
|
end
|
106
109
|
|
110
|
+
newvalue(:disabled, :required_features => :disableable) do
|
111
|
+
provider.disable
|
112
|
+
end
|
113
|
+
|
107
114
|
# Alias the 'present' value.
|
108
115
|
aliasvalue(:installed, :present)
|
109
116
|
|
@@ -151,7 +158,7 @@ module Puppet
|
|
151
158
|
@should.each { |should|
|
152
159
|
case should
|
153
160
|
when :present
|
154
|
-
return true unless [:absent, :purged, :held].include?(is)
|
161
|
+
return true unless [:absent, :purged, :held, :disabled].include?(is)
|
155
162
|
when :latest
|
156
163
|
# Short-circuit packages that are not present
|
157
164
|
return false if is == :absent || is == :purged
|
@@ -404,6 +411,11 @@ module Puppet
|
|
404
411
|
newproperty(:flavor, :required_features => :supports_flavors) do
|
405
412
|
desc "OpenBSD and DNF modules support 'flavors', which are
|
406
413
|
further specifications for which type of package you want."
|
414
|
+
validate do |value|
|
415
|
+
if [:disabled, "disabled"].include?(@resource[:ensure]) && value
|
416
|
+
raise ArgumentError, _('Cannot have both `ensure => disabled` and `flavor`')
|
417
|
+
end
|
418
|
+
end
|
407
419
|
end
|
408
420
|
|
409
421
|
newparam(:source) do
|
@@ -502,6 +514,9 @@ module Puppet
|
|
502
514
|
if [true, :true, "true"].include?(value) && @resource[:flavor]
|
503
515
|
raise ArgumentError, _('Cannot have both `enable_only => true` and `flavor`')
|
504
516
|
end
|
517
|
+
if [:disabled, "disabled"].include?(@resource[:ensure])
|
518
|
+
raise ArgumentError, _('Cannot have both `ensure => disabled` and `enable_only => true`')
|
519
|
+
end
|
505
520
|
end
|
506
521
|
end
|
507
522
|
|
data/lib/puppet/type/service.rb
CHANGED
@@ -78,14 +78,8 @@ module Puppet
|
|
78
78
|
provider.delayed_start
|
79
79
|
end
|
80
80
|
|
81
|
-
# This only makes sense on systemd systems. Static services cannot be enabled
|
82
|
-
# or disabled manually.
|
83
81
|
def insync?(current)
|
84
|
-
|
85
|
-
Puppet.debug("Unable to enable or disable static service #{@resource[:name]}")
|
86
|
-
return true
|
87
|
-
end
|
88
|
-
|
82
|
+
return provider.enabled_insync?(current) if provider.respond_to?(:enabled_insync?)
|
89
83
|
super(current)
|
90
84
|
end
|
91
85
|
|
data/lib/puppet/type/user.rb
CHANGED
@@ -719,17 +719,11 @@ module Puppet
|
|
719
719
|
value = test_sym if [:true, :false].include? test_sym
|
720
720
|
|
721
721
|
return [] if value == :false
|
722
|
-
home = resource[:home]
|
723
|
-
if value == :true and not home
|
724
|
-
raise ArgumentError, _("purge_ssh_keys can only be true for users with a defined home directory")
|
725
|
-
end
|
722
|
+
home = resource[:home] || Dir.home(resource[:name])
|
726
723
|
|
727
724
|
return [ "#{home}/.ssh/authorized_keys" ] if value == :true
|
728
725
|
# value is an array - munge each value
|
729
726
|
[ value ].flatten.map do |entry|
|
730
|
-
if entry =~ /^~|^%h/ and not home
|
731
|
-
raise ArgumentError, _("purge_ssh_keys value '%{value}' meta character ~ or %{home_placeholder} only allowed for users with a defined home directory") % { value: value, home_placeholder: '%h' }
|
732
|
-
end
|
733
727
|
entry.gsub!(/^~\//, "#{home}/")
|
734
728
|
entry.gsub!(/^%h\//, "#{home}/")
|
735
729
|
entry
|
data/lib/puppet/util.rb
CHANGED
@@ -27,21 +27,20 @@ module Util
|
|
27
27
|
|
28
28
|
extend Puppet::Util::SymbolicFileMode
|
29
29
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
module_function :default_env
|
30
|
+
DEFAULT_ENV = if Puppet::Util::Platform.windows?
|
31
|
+
:windows
|
32
|
+
else
|
33
|
+
:posix
|
34
|
+
end.freeze
|
36
35
|
|
37
36
|
# @param name [String] The name of the environment variable to retrieve
|
38
37
|
# @param mode [Symbol] Which operating system mode to use e.g. :posix or :windows. Use nil to autodetect
|
39
38
|
# @return [String] Value of the specified environment variable. nil if it does not exist
|
40
39
|
# @api private
|
41
|
-
def get_env(name, mode =
|
40
|
+
def get_env(name, mode = DEFAULT_ENV)
|
42
41
|
if mode == :windows
|
43
|
-
Puppet::Util::Windows::Process.get_environment_strings.
|
44
|
-
if name.casecmp(key) == 0
|
42
|
+
Puppet::Util::Windows::Process.get_environment_strings.find do |key, value|
|
43
|
+
if name.casecmp(key) == 0
|
45
44
|
return value
|
46
45
|
end
|
47
46
|
end
|
@@ -55,7 +54,7 @@ module Util
|
|
55
54
|
# @param mode [Symbol] Which operating system mode to use e.g. :posix or :windows. Use nil to autodetect
|
56
55
|
# @return [Hash] A hashtable of all environment variables
|
57
56
|
# @api private
|
58
|
-
def get_environment(mode =
|
57
|
+
def get_environment(mode = DEFAULT_ENV)
|
59
58
|
case mode
|
60
59
|
when :posix
|
61
60
|
ENV.to_hash
|
@@ -70,7 +69,7 @@ module Util
|
|
70
69
|
# Removes all environment variables
|
71
70
|
# @param mode [Symbol] Which operating system mode to use e.g. :posix or :windows. Use nil to autodetect
|
72
71
|
# @api private
|
73
|
-
def clear_environment(mode =
|
72
|
+
def clear_environment(mode = DEFAULT_ENV)
|
74
73
|
case mode
|
75
74
|
when :posix
|
76
75
|
ENV.clear
|
@@ -88,7 +87,7 @@ module Util
|
|
88
87
|
# @param value [String] The value to set the variable to. nil deletes the environment variable
|
89
88
|
# @param mode [Symbol] Which operating system mode to use e.g. :posix or :windows. Use nil to autodetect
|
90
89
|
# @api private
|
91
|
-
def set_env(name, value = nil, mode =
|
90
|
+
def set_env(name, value = nil, mode = DEFAULT_ENV)
|
92
91
|
case mode
|
93
92
|
when :posix
|
94
93
|
ENV[name] = value
|
@@ -103,7 +102,7 @@ module Util
|
|
103
102
|
# @param name [Hash] Environment variables to merge into the existing environment. nil values will remove the variable
|
104
103
|
# @param mode [Symbol] Which operating system mode to use e.g. :posix or :windows. Use nil to autodetect
|
105
104
|
# @api private
|
106
|
-
def merge_environment(env_hash, mode =
|
105
|
+
def merge_environment(env_hash, mode = DEFAULT_ENV)
|
107
106
|
case mode
|
108
107
|
when :posix
|
109
108
|
env_hash.each { |name, val| ENV[name.to_s] = val }
|
@@ -90,18 +90,9 @@ Puppet::Util::Log.newdesttype :file do
|
|
90
90
|
end
|
91
91
|
end
|
92
92
|
|
93
|
-
file = File.open(path,
|
93
|
+
file = File.open(path, File::WRONLY|File::CREAT|File::APPEND)
|
94
94
|
file.puts('[') if need_array_start
|
95
95
|
|
96
|
-
# Give ownership to the user and group puppet will run as
|
97
|
-
if Puppet.features.root? && !Puppet::Util::Platform.windows? && !file_exists
|
98
|
-
begin
|
99
|
-
FileUtils.chown(Puppet[:user], Puppet[:group], path)
|
100
|
-
rescue ArgumentError, Errno::EPERM
|
101
|
-
Puppet.err _("Unable to set ownership to %{user}:%{group} for log file: %{path}") % { user: Puppet[:user], group: Puppet[:group], path: path }
|
102
|
-
end
|
103
|
-
end
|
104
|
-
|
105
96
|
@file = file
|
106
97
|
|
107
98
|
@autoflush = Puppet[:autoflush]
|
@@ -19,15 +19,11 @@ module Puppet::Util::Windows::APITypes
|
|
19
19
|
|
20
20
|
class ::FFI::Pointer
|
21
21
|
NULL_HANDLE = 0
|
22
|
+
WCHAR_NULL = "\0\0".encode('UTF-16LE').freeze
|
22
23
|
|
23
24
|
def self.from_string_to_wide_string(str, &block)
|
24
25
|
str = Puppet::Util::Windows::String.wide_string(str)
|
25
|
-
FFI::MemoryPointer.
|
26
|
-
# uchar here is synonymous with byte
|
27
|
-
ptr.put_array_of_uchar(0, str.bytes.to_a)
|
28
|
-
|
29
|
-
yield ptr
|
30
|
-
end
|
26
|
+
FFI::MemoryPointer.from_wide_string(str, &block)
|
31
27
|
|
32
28
|
# ptr has already had free called, so nothing to return
|
33
29
|
nil
|
@@ -53,11 +49,17 @@ module Puppet::Util::Windows::APITypes
|
|
53
49
|
alias_method :read_word, :read_uint16
|
54
50
|
alias_method :read_array_of_wchar, :read_array_of_uint16
|
55
51
|
|
56
|
-
def read_wide_string(char_length, dst_encoding = Encoding::UTF_8, encode_options = {})
|
52
|
+
def read_wide_string(char_length, dst_encoding = Encoding::UTF_8, strip = false, encode_options = {})
|
57
53
|
# char_length is number of wide chars (typically excluding NULLs), *not* bytes
|
58
54
|
str = get_bytes(0, char_length * 2).force_encoding('UTF-16LE')
|
55
|
+
|
56
|
+
if strip
|
57
|
+
i = str.index(WCHAR_NULL)
|
58
|
+
str = str[0, i] if i
|
59
|
+
end
|
60
|
+
|
59
61
|
str.encode(dst_encoding, str.encoding, encode_options)
|
60
|
-
rescue
|
62
|
+
rescue EncodingError => e
|
61
63
|
Puppet.debug "Unable to convert value #{str.nil? ? 'nil' : str.dump} to encoding #{dst_encoding} due to #{e.inspect}"
|
62
64
|
raise
|
63
65
|
end
|
@@ -68,32 +70,31 @@ module Puppet::Util::Windows::APITypes
|
|
68
70
|
# null_terminator = :double_null, then the terminating sequence is four bytes of zero. This is UNIT32 = 0
|
69
71
|
# @param encode_options [Hash] Accepts the same option hash that may be passed to String#encode in Ruby
|
70
72
|
def read_arbitrary_wide_string_up_to(max_char_length = 512, null_terminator = :single_null, encode_options = {})
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
73
|
+
idx = case null_terminator
|
74
|
+
when :single_null
|
75
|
+
# find index of wide null between 0 and max (exclusive)
|
76
|
+
(0...max_char_length).find do |i|
|
77
|
+
get_uint16(i * 2) == 0
|
78
|
+
end
|
79
|
+
when :double_null
|
80
|
+
# find index of double-wide null between 0 and max - 1 (exclusive)
|
81
|
+
(0...max_char_length - 1).find do |i|
|
82
|
+
get_uint32(i * 2) == 0
|
83
|
+
end
|
84
|
+
else
|
85
|
+
raise _("Unable to read wide strings with %{null_terminator} terminal nulls") % { null_terminator: null_terminator }
|
86
|
+
end
|
87
|
+
|
88
|
+
read_wide_string(idx || max_char_length, Encoding::UTF_8, false, encode_options)
|
85
89
|
end
|
86
90
|
|
87
91
|
def read_win32_local_pointer(&block)
|
88
|
-
ptr =
|
92
|
+
ptr = read_pointer
|
89
93
|
begin
|
90
|
-
ptr = read_pointer
|
91
94
|
yield ptr
|
92
95
|
ensure
|
93
|
-
if ptr &&
|
94
|
-
|
95
|
-
Puppet.debug "LocalFree memory leak"
|
96
|
-
end
|
96
|
+
if !ptr.null? && FFI::WIN32::LocalFree(ptr.address) != FFI::Pointer::NULL_HANDLE
|
97
|
+
Puppet.debug "LocalFree memory leak"
|
97
98
|
end
|
98
99
|
end
|
99
100
|
|
@@ -102,23 +103,35 @@ module Puppet::Util::Windows::APITypes
|
|
102
103
|
end
|
103
104
|
|
104
105
|
def read_com_memory_pointer(&block)
|
105
|
-
ptr =
|
106
|
+
ptr = read_pointer
|
106
107
|
begin
|
107
|
-
ptr = read_pointer
|
108
108
|
yield ptr
|
109
109
|
ensure
|
110
|
-
FFI::WIN32::CoTaskMemFree(ptr)
|
110
|
+
FFI::WIN32::CoTaskMemFree(ptr) unless ptr.null?
|
111
111
|
end
|
112
112
|
|
113
113
|
# ptr has already had CoTaskMemFree called, so nothing to return
|
114
114
|
nil
|
115
115
|
end
|
116
116
|
|
117
|
-
|
118
117
|
alias_method :write_dword, :write_uint32
|
119
118
|
alias_method :write_word, :write_uint16
|
120
119
|
end
|
121
120
|
|
121
|
+
class FFI::MemoryPointer
|
122
|
+
# Return a MemoryPointer that points to wide string. This is analogous to the
|
123
|
+
# FFI::MemoryPointer.from_string method.
|
124
|
+
def self.from_wide_string(wstr)
|
125
|
+
ptr = FFI::MemoryPointer.new(:uchar, wstr.bytesize + 2)
|
126
|
+
ptr.put_array_of_uchar(0, wstr.bytes.to_a)
|
127
|
+
ptr.put_uint16(wstr.bytesize, 0)
|
128
|
+
|
129
|
+
yield ptr if block_given?
|
130
|
+
|
131
|
+
ptr
|
132
|
+
end
|
133
|
+
end
|
134
|
+
|
122
135
|
# FFI Types
|
123
136
|
# https://github.com/ffi/ffi/wiki/Types
|
124
137
|
|