Re: [Puppet Users] property file provider

David Kavanagh
Tue, 23 Aug 2011 00:48:33 -0000

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
<stefan.schulte@taunusstein.net> 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