Bug #8138
Puppet Host Resource purge file when encounter unknown entry (Parsefile)
| Status: | Accepted | Start date: | 06/29/2011 | |
|---|---|---|---|---|
| Priority: | Normal | Due date: | ||
| Assignee: | % Done: | 0% | ||
| Category: | host | |||
| Target version: | - | |||
| Affected Puppet version: | 2.6.9 | Branch: | ||
| Keywords: | ||||
Description
This is related to parsedfile and it’s discovered when writing a provider against it.
When parsedfile fails to process a line, instead of leaving it alone, it raises an error and throws away every record except for the resources in the catalog.
For example host file:
127.0.0.1 localhost
192.168.2.1 kermit
badrecord
If we apply the following puppet resource it will purge the entire file and only leave kermit (remove localhost, badrecord):
host { 'kermit':
ip => '192.168.1.1',
}
I can work around this issue by changing provider/host/parsed.rb:
43 else
44 #raise Puppet::Error, "Could not match '#{line}'"
45 hash = {:ip => line, :name => ''}
46 end
However it’s really not the right solution since it simply silently ignore the parse problem. I’ve looked at parsedfile.rb, it appears to be related to the specific section below, but I’m not sure what needs to be changed in fileparsing.rb parse which invokes parse_line.
249 begin
250 @target = path
251 return self.parse(text)
252 rescue Puppet::Error => detail
253 detail.file = @target
254 raise detail
255 ensure
Related issues
History
#1
Updated by Nan Liu almost 2 years ago
- Category set to host
- Affected Puppet version set to 2.6.9
#2
Updated by James Turnbull almost 2 years ago
- Status changed from Unreviewed to Needs More Information
- Assignee set to Luke Kanies
Luke – any ideas? ParsedFile hurts my feelings.
#3
Updated by Luke Kanies almost 2 years ago
It looks like there are 2-3 places that throw an exception, and at most one of them should.
I also recommend, for clarity, that FileParsing just be merged into ParsedFile – no other class uses it, and I think part of the confusion of ParsedFile is just that half of its functionality is in another file.
Anyway, I think this method:
# Split a bunch of text into lines and then parse them individually.
def parse(text)
count = 1
lines(text).collect do |line|
count += 1
if val = parse_line(line)
val
else
error = Puppet::Error.new("Could not parse line #{line.inspect}")
error.line = count
raise error
end
end
end
Should probably be changed to something like:
def parse(text)
count = 1
lines(text).collect do |line|
count += 1
begin
if val = parse_line(line)
val
else
Puppet.warning "Could not parse invalid line #{line.inspect}"
next
end
rescue => detail
Puppet.warning "Could not parse invalid line #{line.inspect}: #{detail}"
next
end
end.compact # remove nil values resulting from 'next'
end
Note that this has the side effect of actually discarding bad (according to Puppet) lines, and I think it will do so even in noop mode. It’s worth making sure that ParsedFile doesn’t even write if global noop mode is enabled.
#4
Updated by Matthaus Owens almost 2 years ago
- Status changed from Needs More Information to Accepted