Title: Message Title
Liao Penghui updated an issue
Puppet / PUP-6418
File parsing error result flushing of file content
Change By:
Liao Penghui
When using resource types like ssh_authorized_keys or host, Puppet will use Puppet::Util::FileParsing module for file line parsing. Specifically, Puppet will call parse for file parsing method during prefetch stage, the parse method is like:{code:ruby} # Split a bunch of text into lines and then parse them individually. def parse(text)count = 1lines(text).collect do |line| count += 1 if val = parse_line(line)val elseerror = Puppet::ResourceError.new("Could not parse line #{line.inspect}")error.line = countraise error endend end{code}As the code above shows, Puppet will raise a Puppet::ResourceError if some line in the file can't be parsed correctly(May cause by wrong format) . This will lead to failure of prefetch method of a resource type. However, Puppet will still write content to the file cause the flush method in the provider of these resource types. For example, the flush method in ssh_authorized_keys provider will flush the ~/.ssh/authorized_keys file using content in @property_hash. But the flush will delete the original content in that file cause @property_hash is not set by prefetch method. See flush method below:{code:ruby} def flush# Make sure we've got a target and name set.# If the target isn't set, then this is our first modification, so# mark it for flushing.unless @property_hash[:target] @property_hash[:target] = @resource.should(:target) || self.class.default_target self.class.modified(@property_hash[:target])end@resource.class.key_attributes.each do |attr| @property_hash[attr] ||= @resource[attr]endself.class.flush(@property_hash) end{code}As above shows ,@property_hash is set by using resource attribute when it is empty. This will lead to lose original content in the file after flush the file.How to reproduce this bug:Say the ssh authorized_keys file is like:{code:bash}$ cat ~/.ssh/authorized_keysssh-rsa ORIGINAL_KEY COMMENTA LINE THAT CAN'T PARSE BY PUPPET{code}I apply a puppet manifest like:{code:puppet}ssh_authorized_key { 'test': user => 'root', type => 'ssh-rsa', key => 'A_NEW_KEY',}{code}the authorized_keys becomes like:{code:bash}$ cat ~/.ssh/authorized_keysssh-rsa A_NEW_KEY test{code}The original content in that file lost.
Add Comment