Custom type file access race conditions

13 views
Skip to first unread message

jwil...@gmail.com

unread,
Oct 13, 2015, 3:21:17 PM10/13/15
to Puppet Users
Hi!

I'm working on a custom type for Java Util Preferences files.  The files are XML and, unfortunately, aren't handled correctly by Augeas' XML lens.  I'm using the nokogiri library to modify them, since that parser is more forgiving to some of the formatting errors that I have to deal with.  I've tested the type and it works fine with the Puppet resource command as far as adding, modifying, and removing individual entries from the file.  Unfortunately, it doesn't work correctly when I have multiple instances of the type in a catalog during an agent run.

What I've run into is that there appears to be a race condition when multiple instances of the type are executed.  My provider, if create() is called, will attempt to open the file for parsing and, if the file isn't found, create an empty file with a basic set of tags and then add in the entry and value that are expected.  After tracing through the code, I've found that the first execution of the provider will open an existing file that has readable XML contents, but subsequent instances of my provider think that the file does not exist and attempt to repopulate it with the skeleton XML file contents.  This results in a garbled file.

I tried looking at Puppet's host type, since it basically does what I want to do:  have multiple type instances add independent entries to a single file.  Unfortunately, the host type relies on a ParsedFile type which is record-based and buries its file IO routines under a couple of layers of Ruby code.  

I'm still trying to trace it, but I was hoping someone on the list would have some insight into the problem.   Do I need to do some file locking at the Ruby IO?  If I do, will that interfere with Puppet's execution model?  My current provider parses and modifies the file for exists?, create, destroy, and for the value setter.  Would I be better off parsing the document once and holding it in memory?  I went with parsing it every time as needed to try and get the most current view from the filesystem at any point.

Thanks in advance!
Reply all
Reply to author
Forward
0 new messages