On Tue, Aug 23, 2011 at 10:32:54AM -0400, David Kavanagh wrote:
> I did get this working. In a nutshell, I modified to_line like this;
> def self.to_line(hash)
> return super unless hash[:record_type] == :parsed
> "#{hash[:name]}=#{hash[:value]}"
> end
As I said, I wouldn't to that. Just pass a :to_line => proc {...} to your
record_line call because you will then just overwrite the to_line method
of that particular record_type.
>
> which handles the other line types. To handle wrapping values in
> quotes, I changed the type like this;
> newproperty(:value) do
> munge do |value|
> '"'+value.to_s+'"'
> end
> newvalues(/^\S+$/)
> end
>
> so, that line where value.to_s is wrapped with quotes seems to work nicely.
Hm, in my opinion using a regex that gets the value as an unqoted string
and put the quotes back to the string in the to_line method looks saner
than munging the value.
>
> My other problem now is that aside from handling these variations
>
> # comment lines
> key="value"
>
> I also need to handle this;
>
> key="value" #optional comment
>
> I could add to the regex for the line matching (in record_line
> :parsed). Then, I'm not sure how to get that into to_line for output.
You have to store the inlinecomment in the record hash and then put it
back in the to_line hook. So this should work
(to test the regex I recommend rubular.com)
record_line :parsed,
:fields => %w{name value comment},
:optional => %w{value comment},
:regex => /^\s*(.*?)(?:\s*=\s*(.*?))?(?:\s*#\s*(.*))?\s*$/,
:to_line => proc { |hash|
str = hash[:name]
str += "=\"#{hash[:value]}\"" if hash[:value] != :absent
str += " # #{hash[:comment]}" if hash[:comment] != :absent
str
}
>
> David
>
> On Mon, Aug 22, 2011 at 8:48 PM, David Kavanagh <[email protected]> wrote:
> > Thanks, I'll try to work through your suggestions. I took this from
> > the nova_config stuff on github, so that was my example.
> >
> > David
> >
> > On Mon, Aug 22, 2011 at 7:36 PM, Stefan Schulte
> > <[email protected]> wrote:
> >> On Mon, Aug 22, 2011 at 06:33:27PM -0400, David Kavanagh wrote:
> >>> I'm working on a type/provider for the eucalyptus.conf file. What I
> >>> have generally works for modifying properties. I have a couple of
> >>> issues and not being very experienced with Ruby and custom providers,
> >>> I wonder if anyone can help?
> >>> The code is included below. The key/value constructs in the file look
> >>> like:
> >>>
> >>> key="value"
> >>>
> >>> 1. I'm not getting the quotes surrounding the value, which I think I
> >>> can figure out myself.
> >>> 2. I get all blanks and comments replaced by "=", which is more of a
> >>> problem.
> >>>
> >>> David
> >>>
> >>>
> >>> require 'puppet/provider/parsedfile'
> >>>
> >>> eucaconf = "/etc/eucalyptus/eucalyptus.conf"
> >>>
> >>> Puppet::Type.type(:eucalyptus_config).provide(
> >>> :parsed,
> >>> :parent => Puppet::Provider::ParsedFile,
> >>> :default_target => eucaconf,
> >>> :filetype => :flat
> >>> ) do
> >>>
> >>> confine :exists => eucaconf
> >>> text_line :comment, :match => /^#/;
> >>> text_line :blank, :match => /^\s*$/;
> >>>
> >>> record_line :parsed,
> >>> :fields => %w{line},
> >>> :match => /(.*)/ ,
> >>> :post_parse => proc { |hash|
> >>> Puppet.debug("eucalyptus config line:#{hash[:line]} has been
> >>> parsed")
> >>> if hash[:line] =~ /^\s*(\S+)\s*=\s*(\S+)\s*$/
> >>> hash[:name]=$1
> >>> hash[:value]=$2
> >>> elsif hash[:line] =~ /^\s*(\S+)\s*$/
> >>> hash[:name]=$1
> >>> hash[:value]=false
> >>> else
> >>> raise Puppet::Error, "Invalid line: #{hash[:line]}"
> >>> end
> >>> }
> >>
> >> instead of the post_parse hook you can probably just change your regex
> >> :fields => %w{name value},
> >> :optional => %w{value},
> >> :match => /^\s*(.*?)(?:\s*=\s*"(\S+)")?\s*$/
> >>
> >> This matches line like
> >>
> >> foo
> >>
> >> and
> >>
> >> foo = "bar"
> >>
> >>>
> >>> def self.to_line(hash)
> >>> "#{hash[:name]}=#{hash[:value]}"
> >>> end
> >>
> >> If you just overwrite the to_line method you have to take care of the
> >> different record_types (you defined :comment, :text and :parsed).
> >> So you have to do
> >>
> >> def self.to_line(hash)
> >> return super unless hash[:record_type] == :parsed
> >> if hash[:value] == :absent
> >> hash[:name]
> >> else
> >> "#{hash[:name]}=\"#{hash[:value]}\""
> >> end
> >> end
> >>
> >> Nevertheless the "right" thing to do is to pass a block to the
> >> record_line method:
> >>
> >> record_line :parsed,
> >> :fields => ...,
> >> :match => ...,
> >> :to_line => proc { |hash|
> >> if hash[:value] == :absent
> >> hash[:name]
> >> else
> >> "#{hash[:name]}=\"#{hash[:value]}\""
> >> end
> >> }
> >>
> >> Hope that helps.
> >>
> >> -Stefan
> >>
> >
>
> --
> You received this message because you are subscribed to the Google Groups
> "Puppet Users" group.
> To post to this group, send email to [email protected].
> To unsubscribe from this group, send email to
> [email protected].
> For more options, visit this group at
> http://groups.google.com/group/puppet-users?hl=en.
>
pgpH9X2rIXtih.pgp
Description: PGP signature
