puppet 3.3.0 → 3.3.1.rc1
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 +7 -0
- data/lib/puppet/configurer.rb +1 -7
- data/lib/puppet/defaults.rb +18 -6
- data/lib/puppet/file_bucket/file.rb +10 -1
- data/lib/puppet/forge/repository.rb +8 -2
- data/lib/puppet/graph/simple_graph.rb +1 -1
- data/lib/puppet/indirector/request.rb +18 -0
- data/lib/puppet/indirector/rest.rb +22 -1
- data/lib/puppet/indirector/status/local.rb +3 -1
- data/lib/puppet/indirector/yaml.rb +4 -18
- data/lib/puppet/network/http.rb +1 -0
- data/lib/puppet/network/http/handler.rb +11 -6
- data/lib/puppet/parser/yaml_trimmer.rb +1 -3
- data/lib/puppet/provider/package/dpkg.rb +2 -1
- data/lib/puppet/provider/package/rpm.rb +4 -2
- data/lib/puppet/provider/parsedfile.rb +9 -6
- data/lib/puppet/resource/status.rb +1 -1
- data/lib/puppet/status.rb +8 -0
- data/lib/puppet/transaction/additional_resource_generator.rb +1 -1
- data/lib/puppet/transaction/event.rb +1 -1
- data/lib/puppet/transaction/report.rb +6 -2
- data/lib/puppet/util/monkey_patches.rb +0 -52
- data/lib/puppet/util/storage.rb +5 -8
- data/lib/puppet/util/yaml.rb +23 -0
- data/lib/puppet/util/zaml.rb +14 -2
- data/lib/puppet/version.rb +1 -1
- data/spec/unit/agent_spec.rb +2 -0
- data/spec/unit/file_bucket/file_spec.rb +19 -13
- data/spec/unit/indirector/certificate/rest_spec.rb +1 -0
- data/spec/unit/indirector/report/rest_spec.rb +1 -0
- data/spec/unit/indirector/request_spec.rb +9 -0
- data/spec/unit/indirector/rest_spec.rb +22 -2
- data/spec/unit/indirector/run/local_spec.rb +3 -1
- data/spec/unit/indirector/status/local_spec.rb +11 -0
- data/spec/unit/indirector/status/rest_spec.rb +1 -1
- data/spec/unit/indirector/yaml_spec.rb +16 -40
- data/spec/unit/network/http/handler_spec.rb +17 -3
- data/spec/unit/pops/adaptable_spec.rb +0 -2
- data/spec/unit/provider/package/dpkg_spec.rb +31 -23
- data/spec/unit/provider/package/rpm_spec.rb +16 -8
- data/spec/unit/provider/parsedfile_spec.rb +86 -47
- data/spec/unit/transaction/report_spec.rb +5 -1
- data/spec/unit/transaction/resource_harness_spec.rb +1 -1
- data/spec/unit/util/monkey_patches_spec.rb +0 -13
- data/spec/unit/util/storage_spec.rb +49 -49
- data/spec/unit/util/yaml_spec.rb +41 -0
- metadata +2746 -2749
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 2a2479879d8532a3fb936537d8abaf317c563a49
|
4
|
+
data.tar.gz: 42bfd1c583faee771a10dfdd3f697bb91a30b734
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 78443b0f2e01f6fc4fb71b6e58df58bef370054815519fa468b7af5c5511cebf2ec69d7794425a4de7713d4734292c752cb8db875cd899330047dec4213b4362
|
7
|
+
data.tar.gz: 8026eecbf7556115c83c2bb3ec04c8755ca8766312b22fdb4a7da51aaca63ef5488a88e590b3b028e7c6e6788f9209228b8900d69a3d8a2e6c422025a920e3fb
|
data/lib/puppet/configurer.rb
CHANGED
@@ -142,6 +142,7 @@ class Puppet::Configurer
|
|
142
142
|
init_storage
|
143
143
|
|
144
144
|
Puppet::Util::Log.newdestination(report)
|
145
|
+
|
145
146
|
begin
|
146
147
|
unless Puppet[:node_name_fact].empty?
|
147
148
|
query_options = get_facts(options)
|
@@ -210,13 +211,6 @@ class Puppet::Configurer
|
|
210
211
|
Puppet::Transaction::Report.indirection.save(report, nil, :environment => @environment) if Puppet[:report]
|
211
212
|
rescue => detail
|
212
213
|
Puppet.log_exception(detail, "Could not send report: #{detail}")
|
213
|
-
if detail.message =~ /Could not intern from pson.*Puppet::Transaction::Report/
|
214
|
-
Puppet.notice("There was an error sending the report.")
|
215
|
-
Puppet.notice("This error is possibly caused by sending the report in a format the master can not handle.")
|
216
|
-
Puppet.notice("A puppet master older than 3.2.2 can not handle pson reports.")
|
217
|
-
Puppet.notice("Set report_serialization_format=yaml on the agent to send reports to older masters.")
|
218
|
-
Puppet.notice("See http://links.puppetlabs.com/deprecate_yaml_on_network for more information.")
|
219
|
-
end
|
220
214
|
end
|
221
215
|
|
222
216
|
def save_last_run_summary(report)
|
data/lib/puppet/defaults.rb
CHANGED
@@ -1092,12 +1092,24 @@ EOT
|
|
1092
1092
|
|
1093
1093
|
This should almost always be set to `pson`. It can be temporarily set to
|
1094
1094
|
`yaml` to let agents using this Puppet version connect to a puppet master
|
1095
|
-
running Puppet 3.0.0 through 3.2.
|
1096
|
-
|
1097
|
-
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1095
|
+
running Puppet 3.0.0 through 3.2.x.
|
1096
|
+
|
1097
|
+
Note that this is set to 'yaml' automatically if the agent detects an
|
1098
|
+
older master, so should never need to be set explicitly."
|
1099
|
+
},
|
1100
|
+
:legacy_query_parameter_serialization => {
|
1101
|
+
:default => false,
|
1102
|
+
:type => :boolean,
|
1103
|
+
:desc => "The serialization format to use when sending file_metadata
|
1104
|
+
query parameters. Older versions of puppet master expect certain query
|
1105
|
+
parameters to be serialized as yaml, which is deprecated.
|
1106
|
+
|
1107
|
+
This should almost always be false. It can be temporarily set to true
|
1108
|
+
to let agents using this Puppet version connect to a puppet master
|
1109
|
+
running Puppet 3.0.0 through 3.2.x.
|
1110
|
+
|
1111
|
+
Note that this is set to true automatically if the agent detects an
|
1112
|
+
older master, so should never need to be set explicitly."
|
1101
1113
|
},
|
1102
1114
|
:agent_catalog_run_lockfile => {
|
1103
1115
|
:default => "$statedir/agent_catalog_run.lock",
|
@@ -14,12 +14,16 @@ class Puppet::FileBucket::File
|
|
14
14
|
attr :bucket_path
|
15
15
|
|
16
16
|
def self.supported_formats
|
17
|
+
[:s, :pson]
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.default_format
|
17
21
|
# This should really be :raw, like is done for Puppet::FileServing::Content
|
18
22
|
# but this class hasn't historically supported `from_raw`, so switching
|
19
23
|
# would break compatibility between newer 3.x agents talking to older 3.x
|
20
24
|
# masters. However, to/from_s has been supported and achieves the desired
|
21
25
|
# result without breaking compatibility.
|
22
|
-
|
26
|
+
:s
|
23
27
|
end
|
24
28
|
|
25
29
|
def initialize(contents, options = {})
|
@@ -54,6 +58,11 @@ class Puppet::FileBucket::File
|
|
54
58
|
self.new(contents)
|
55
59
|
end
|
56
60
|
|
61
|
+
def to_pson
|
62
|
+
Puppet.deprecation_warning("Serializing Puppet::FileBucket::File objects to pson is deprecated.")
|
63
|
+
{ "contents" => contents }.to_pson
|
64
|
+
end
|
65
|
+
|
57
66
|
# This method is deprecated, but cannot be removed for awhile, otherwise
|
58
67
|
# older agents sending pson couldn't backup to filebuckets on newer masters
|
59
68
|
def self.from_pson(pson)
|
@@ -1,10 +1,13 @@
|
|
1
1
|
require 'net/https'
|
2
|
-
require 'zlib'
|
3
2
|
require 'digest/sha1'
|
4
3
|
require 'uri'
|
5
4
|
require 'puppet/util/http_proxy'
|
6
5
|
require 'puppet/forge/errors'
|
7
6
|
|
7
|
+
if Puppet.features.zlib? && Puppet[:zlib]
|
8
|
+
require 'zlib'
|
9
|
+
end
|
10
|
+
|
8
11
|
class Puppet::Forge
|
9
12
|
# = Repository
|
10
13
|
#
|
@@ -26,9 +29,12 @@ class Puppet::Forge
|
|
26
29
|
Net::HTTPHeaderSyntaxError,
|
27
30
|
Net::ProtocolError,
|
28
31
|
SocketError,
|
29
|
-
Zlib::GzipFile::Error,
|
30
32
|
]
|
31
33
|
|
34
|
+
if Puppet.features.zlib? && Puppet[:zlib]
|
35
|
+
NET_HTTP_EXCEPTIONS << Zlib::GzipFile::Error
|
36
|
+
end
|
37
|
+
|
32
38
|
# Instantiate a new repository instance rooted at the +url+.
|
33
39
|
# The agent will report +consumer_version+ in the User-Agent to
|
34
40
|
# the repository.
|
@@ -159,9 +159,27 @@ class Puppet::Indirector::Request
|
|
159
159
|
# Create the query string, if options are present.
|
160
160
|
def query_string
|
161
161
|
return "" if options.nil? || options.empty?
|
162
|
+
|
163
|
+
# For backward compatibility with older (pre-3.3) masters,
|
164
|
+
# this puppet option allows serialization of query parameter
|
165
|
+
# arrays as yaml. This can be removed when we remove yaml
|
166
|
+
# support entirely.
|
167
|
+
if Puppet.settings[:legacy_query_parameter_serialization]
|
168
|
+
replace_arrays_with_yaml
|
169
|
+
end
|
170
|
+
|
162
171
|
"?" + encode_params(expand_into_parameters(options.to_a))
|
163
172
|
end
|
164
173
|
|
174
|
+
def replace_arrays_with_yaml
|
175
|
+
options.each do |key, value|
|
176
|
+
case value
|
177
|
+
when Array
|
178
|
+
options[key] = YAML.dump(value)
|
179
|
+
end
|
180
|
+
end
|
181
|
+
end
|
182
|
+
|
165
183
|
def expand_into_parameters(data)
|
166
184
|
data.inject([]) do |params, key_value|
|
167
185
|
key, value = key_value
|
@@ -98,6 +98,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
98
98
|
end
|
99
99
|
|
100
100
|
if is_http_200?(response)
|
101
|
+
check_master_version(response)
|
101
102
|
content_type, body = parse_response(response)
|
102
103
|
result = deserialize_find(content_type, body)
|
103
104
|
result.name = request.key if result.respond_to?(:name=)
|
@@ -112,7 +113,12 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
112
113
|
http_head(request, indirection2uri(request), headers)
|
113
114
|
end
|
114
115
|
|
115
|
-
|
116
|
+
if is_http_200?(response)
|
117
|
+
check_master_version(response)
|
118
|
+
true
|
119
|
+
else
|
120
|
+
false
|
121
|
+
end
|
116
122
|
end
|
117
123
|
|
118
124
|
def search(request)
|
@@ -121,6 +127,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
121
127
|
end
|
122
128
|
|
123
129
|
if is_http_200?(response)
|
130
|
+
check_master_version(response)
|
124
131
|
content_type, body = parse_response(response)
|
125
132
|
deserialize_search(content_type, body) || []
|
126
133
|
else
|
@@ -136,6 +143,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
136
143
|
end
|
137
144
|
|
138
145
|
if is_http_200?(response)
|
146
|
+
check_master_version(response)
|
139
147
|
content_type, body = parse_response(response)
|
140
148
|
deserialize_destroy(content_type, body)
|
141
149
|
else
|
@@ -151,6 +159,7 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
151
159
|
end
|
152
160
|
|
153
161
|
if is_http_200?(response)
|
162
|
+
check_master_version(response)
|
154
163
|
content_type, body = parse_response(response)
|
155
164
|
deserialize_save(content_type, body)
|
156
165
|
else
|
@@ -191,6 +200,18 @@ class Puppet::Indirector::REST < Puppet::Indirector::Terminus
|
|
191
200
|
Net::HTTPError.new(message, response)
|
192
201
|
end
|
193
202
|
|
203
|
+
def check_master_version response
|
204
|
+
if !response[Puppet::Network::HTTP::HEADER_PUPPET_VERSION] &&
|
205
|
+
(Puppet[:legacy_query_parameter_serialization] == false || Puppet[:report_serialization_format] != "yaml")
|
206
|
+
Puppet.notice "Using less secure serialization of reports and query parameters for compatibility"
|
207
|
+
Puppet.notice "with older puppet master. To remove this notice, please upgrade your master(s) "
|
208
|
+
Puppet.notice "to Puppet 3.3 or newer."
|
209
|
+
Puppet.notice "See http://links.puppetlabs.com/deprecate_yaml_on_network for more information."
|
210
|
+
Puppet[:legacy_query_parameter_serialization] = true
|
211
|
+
Puppet[:report_serialization_format] = "yaml"
|
212
|
+
end
|
213
|
+
end
|
214
|
+
|
194
215
|
# Returns the content_type, stripping any appended charset, and the
|
195
216
|
# body, decompressed if necessary (content-encoding is checked inside
|
196
217
|
# uncompress_body)
|
@@ -1,28 +1,16 @@
|
|
1
1
|
require 'puppet/indirector/terminus'
|
2
|
+
require 'puppet/util/yaml'
|
2
3
|
|
3
4
|
# The base class for YAML indirection termini.
|
4
5
|
class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
|
5
|
-
if defined?(::Psych::SyntaxError)
|
6
|
-
YamlLoadExceptions = [::StandardError, ::ArgumentError, ::Psych::SyntaxError]
|
7
|
-
else
|
8
|
-
YamlLoadExceptions = [::StandardError, ::ArgumentError]
|
9
|
-
end
|
10
|
-
|
11
6
|
# Read a given name's file in and convert it from YAML.
|
12
7
|
def find(request)
|
13
8
|
file = path(request.key)
|
14
9
|
return nil unless FileTest.exist?(file)
|
15
10
|
|
16
|
-
yaml = nil
|
17
|
-
begin
|
18
|
-
yaml = ::File.read(file)
|
19
|
-
rescue => detail
|
20
|
-
raise Puppet::Error, "Could not read YAML data for #{indirection.name} #{request.key}: #{detail}"
|
21
|
-
end
|
22
|
-
|
23
11
|
begin
|
24
|
-
return
|
25
|
-
rescue
|
12
|
+
return Puppet::Util::Yaml.load_file(file)
|
13
|
+
rescue Puppet::Util::Yaml::YamlLoadError => detail
|
26
14
|
raise Puppet::Error, "Could not parse YAML data for #{indirection.name} #{request.key}: #{detail}"
|
27
15
|
end
|
28
16
|
end
|
@@ -39,9 +27,7 @@ class Puppet::Indirector::Yaml < Puppet::Indirector::Terminus
|
|
39
27
|
Dir.mkdir(basedir) unless FileTest.exist?(basedir)
|
40
28
|
|
41
29
|
begin
|
42
|
-
Puppet::Util.
|
43
|
-
f.print to_yaml(request.instance)
|
44
|
-
end
|
30
|
+
Puppet::Util::Yaml.dump(request.instance, file)
|
45
31
|
rescue TypeError => detail
|
46
32
|
Puppet.err "Could not save #{self.name} #{request.key}: #{detail}"
|
47
33
|
end
|
data/lib/puppet/network/http.rb
CHANGED
@@ -84,6 +84,8 @@ module Puppet::Network::HTTP::Handler
|
|
84
84
|
request_method = http_method(request)
|
85
85
|
request_path = path(request)
|
86
86
|
|
87
|
+
response[Puppet::Network::HTTP::HEADER_PUPPET_VERSION] = Puppet.version
|
88
|
+
|
87
89
|
configure_profiler(request_headers, request_params)
|
88
90
|
|
89
91
|
Puppet::Util::Profiler.profile("Processed request #{request_method} #{request_path}") do
|
@@ -97,7 +99,7 @@ module Puppet::Network::HTTP::Handler
|
|
97
99
|
rescue SystemExit,NoMemoryError
|
98
100
|
raise
|
99
101
|
rescue HTTPError => e
|
100
|
-
return
|
102
|
+
return do_http_control_exception(response, e)
|
101
103
|
rescue Exception => e
|
102
104
|
return do_exception(response, e)
|
103
105
|
ensure
|
@@ -121,11 +123,7 @@ module Puppet::Network::HTTP::Handler
|
|
121
123
|
status = 403 if status == 400
|
122
124
|
end
|
123
125
|
|
124
|
-
|
125
|
-
Puppet.log_exception(exception)
|
126
|
-
else
|
127
|
-
Puppet.notice(exception.to_s)
|
128
|
-
end
|
126
|
+
Puppet.log_exception(exception)
|
129
127
|
|
130
128
|
set_content_type(response, "text/plain")
|
131
129
|
set_response(response, exception.to_s, status)
|
@@ -219,6 +217,13 @@ module Puppet::Network::HTTP::Handler
|
|
219
217
|
|
220
218
|
private
|
221
219
|
|
220
|
+
def do_http_control_exception(response, exception)
|
221
|
+
msg = exception.message
|
222
|
+
Puppet.info(msg)
|
223
|
+
set_content_type(response, "text/plain")
|
224
|
+
set_response(response, msg, exception.status)
|
225
|
+
end
|
226
|
+
|
222
227
|
def report_if_deprecated(format)
|
223
228
|
if format.name == :yaml || format.name == :b64_zlib_yaml
|
224
229
|
Puppet.deprecation_warning("YAML in network requests is deprecated and will be removed in a future version. See http://links.puppetlabs.com/deprecate_yaml_on_network")
|
@@ -44,6 +44,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
|
|
44
44
|
self::DPKG_DESCRIPTION_DELIMITER = ':DESC:'
|
45
45
|
self::DPKG_QUERY_FORMAT_STRING = %Q{'${Status} ${Package} ${Version} #{self::DPKG_DESCRIPTION_DELIMITER} ${Description}\\n#{self::DPKG_DESCRIPTION_DELIMITER}\\n'}
|
46
46
|
self::FIELDS_REGEX = %r{^(\S+) +(\S+) +(\S+) (\S+) (\S*) #{self::DPKG_DESCRIPTION_DELIMITER} (.*)$}
|
47
|
+
self::DPKG_PACKAGE_NOT_FOUND_REGEX = /No packages found matching/
|
47
48
|
self::FIELDS= [:desired, :error, :status, :name, :ensure, :description]
|
48
49
|
self::END_REGEX = %r{^#{self::DPKG_DESCRIPTION_DELIMITER}$}
|
49
50
|
|
@@ -59,7 +60,7 @@ Puppet::Type.type(:package).provide :dpkg, :parent => Puppet::Provider::Package
|
|
59
60
|
|
60
61
|
line = pipe.gets
|
61
62
|
unless hash = parse_line(line)
|
62
|
-
Puppet.warning "Failed to match dpkg-query line #{line.inspect}"
|
63
|
+
Puppet.warning "Failed to match dpkg-query line #{line.inspect}" if !self::DPKG_PACKAGE_NOT_FOUND_REGEX.match(line)
|
63
64
|
return nil
|
64
65
|
end
|
65
66
|
|
@@ -13,6 +13,7 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr
|
|
13
13
|
# The query format by which we identify installed packages
|
14
14
|
self::NEVRA_FORMAT = %Q{'%{NAME} %|EPOCH?{%{EPOCH}}:{0}| %{VERSION} %{RELEASE} %{ARCH} #{self::RPM_DESCRIPTION_DELIMITER} %{SUMMARY}\\n'}
|
15
15
|
self::NEVRA_REGEX = %r{^(\S+) (\S+) (\S+) (\S+) (\S+)(?: #{self::RPM_DESCRIPTION_DELIMITER} ?(.*))?$}
|
16
|
+
self::RPM_PACKAGE_NOT_FOUND_REGEX = /package .+ is not installed/
|
16
17
|
self::NEVRA_FIELDS = [:name, :epoch, :version, :release, :arch, :description]
|
17
18
|
|
18
19
|
commands :rpm => "rpm"
|
@@ -76,7 +77,6 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr
|
|
76
77
|
rescue Puppet::ExecutionFailure
|
77
78
|
return nil
|
78
79
|
end
|
79
|
-
|
80
80
|
# FIXME: We could actually be getting back multiple packages
|
81
81
|
# for multilib and this will only return the first such package
|
82
82
|
@property_hash.update(self.class.nevra_to_hash(output))
|
@@ -150,7 +150,9 @@ Puppet::Type.type(:package).provide :rpm, :source => :rpm, :parent => Puppet::Pr
|
|
150
150
|
line.strip!
|
151
151
|
hash = {}
|
152
152
|
|
153
|
-
if
|
153
|
+
if self::RPM_PACKAGE_NOT_FOUND_REGEX.match(line)
|
154
|
+
# pass through, package was not found
|
155
|
+
elsif match = self::NEVRA_REGEX.match(line)
|
154
156
|
self::NEVRA_FIELDS.zip(match.captures) { |f, v| hash[f] = v }
|
155
157
|
hash[:provider] = self.name
|
156
158
|
hash[:ensure] = "#{hash[:version]}-#{hash[:release]}"
|
@@ -64,13 +64,15 @@ class Puppet::Provider::ParsedFile < Puppet::Provider
|
|
64
64
|
return unless defined?(@modified) and ! @modified.empty?
|
65
65
|
|
66
66
|
flushed = []
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
67
|
+
begin
|
68
|
+
@modified.sort { |a,b| a.to_s <=> b.to_s }.uniq.each do |target|
|
69
|
+
Puppet.debug "Flushing #{@resource_type.name} provider target #{target}"
|
70
|
+
flushed << target
|
71
|
+
flush_target(target)
|
72
|
+
end
|
73
|
+
ensure
|
74
|
+
@modified.reject! { |t| flushed.include?(t) }
|
71
75
|
end
|
72
|
-
|
73
|
-
@modified.reject! { |t| flushed.include?(t) }
|
74
76
|
end
|
75
77
|
|
76
78
|
# Make sure our file is backed up, but only back it up once per transaction.
|
@@ -92,6 +94,7 @@ class Puppet::Provider::ParsedFile < Puppet::Provider
|
|
92
94
|
records = target_records(target).reject { |r|
|
93
95
|
r[:ensure] == :absent
|
94
96
|
}
|
97
|
+
|
95
98
|
target_object(target).write(to_file(records))
|
96
99
|
end
|
97
100
|
|
data/lib/puppet/status.rb
CHANGED
@@ -38,7 +38,7 @@ class Puppet::Transaction::AdditionalResourceGenerator
|
|
38
38
|
generated = replace_duplicates_with_catalog_resources(resource.eval_generate)
|
39
39
|
return false if generated.empty?
|
40
40
|
rescue => detail
|
41
|
-
resource.log_exception(detail, "Failed to generate additional resources using 'eval_generate: #{detail}")
|
41
|
+
resource.log_exception(detail, "Failed to generate additional resources using 'eval_generate': #{detail}")
|
42
42
|
return false
|
43
43
|
end
|
44
44
|
add_resources(generated, resource)
|