FAQ
Afternoon all

Is it possible to pass an array of key=value pairs to a provider param, and
have the provider split and handle each key=value pair?

Basically, I've defined a new provider and type as follows:
http://pastebin.com/WdekYPAh

I've set '*:array_matching => all*' on the relevant newparam.

However the puppet run is failing as follows:

Error: Could not set 'present' on ensure: $_ value need to be String (nil
given) at 48:/etc/puppet/manifests/site.pp
Error: Could not set 'present' on ensure: $_ value need to be String (nil
given) at 48:/etc/puppet/manifests/site.pp
Wrapped exception:
$_ value need to be String (nil given)
Error:
/Stage[main]//Node[actint-star-nactl01]/Netapp_volume_options[v_puppet_test12111508]/ensure:
change from absent to present failed: Could not set 'present' on ensure: $_
value need to be String (nil given) at 48:/etc/puppet/manifests/site.pp
Debug logging shows:
^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: checking
value of Netapp Volume option on Volume v_puppet_test12111508
^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: setting
Netapp Volume options against volume v_puppet_test12111508.
^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Options:
x=ay=b
^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Option: x=a
So it looks to me like it's getting the values correctly, and its trying to
iterate through each value.

If I strip out the code on line 17-19, then the logs show the following
additional line. The puppet run also completes without error.
^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Option: y=b
So, any ideas???

Thanks in advance for any replies.

Regards
Gavin

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/neCIMOkh1JUJ.
To post to this group, send email to puppet-users@googlegroups.com.
To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.

Search Discussions

  • Jcbollinger at Nov 13, 2012 at 3:12 pm

    On Tuesday, November 13, 2012 8:47:00 AM UTC-6, Gavin Williams wrote:
    Afternoon all

    Is it possible to pass an array of key=value pairs to a provider param,
    and have the provider split and handle each key=value pair?

    Basically, I've defined a new provider and type as follows:
    http://pastebin.com/WdekYPAh

    I can't see your code because pastebin is blocked to me, but I may be able
    to give you some advice anyway:

    1. You can pass an array of key=value pairs as a parameter to a
    provider, and the provider can parse it any way you like.
    2. BUT you should not try to populate *other* parameters' values that
    way. If you define a parameter that accepts a complex, structured value,
    then the entire value belongs to the parameter to which it is assigned.
    3. Wouldn't a hash be a better fit to the data than an array of
    key/value pairs anyway?

    What are you trying to achieve by this approach? There is likely a better
    way.


    John

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/yDOmbdqEY_sJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Fatmcgav at Nov 13, 2012 at 3:33 pm
    John

    Cheers for the response.

    As per my other threads, I'm writing a NetApp Network device module for
    Puppet.

    One of the functions required is the ability to set 'options' against a
    given volume.
    What I want to do is create a provider that accepts a volume name and a
    list of volume options with their corresponding settings, and then iterate
    through the provided list making a webservice call for each option.

    So to give a better example of the provider in pastebin:
    netapp_volume_options { 'v_puppet_test12111508':
    options => ['convert_ucode=on', 'no_atime_update=on'],
    }

    Have just pushed my latest code to Github here:
    https://github.com/fatmcgav/fatmcgav-netapp/tree/master/lib/puppet/provider/netapp_volume_options

    I did manage to get it working after a bit of googling... However am happy
    to take suggestions if there is a better method :)

    Cheers
    Gavin


    On 13 November 2012 15:12, jcbollinger wrote:


    On Tuesday, November 13, 2012 8:47:00 AM UTC-6, Gavin Williams wrote:

    Afternoon all

    Is it possible to pass an array of key=value pairs to a provider param,
    and have the provider split and handle each key=value pair?

    Basically, I've defined a new provider and type as follows:
    http://pastebin.com/WdekYPAh

    I can't see your code because pastebin is blocked to me, but I may be able
    to give you some advice anyway:

    1. You can pass an array of key=value pairs as a parameter to a
    provider, and the provider can parse it any way you like.
    2. BUT you should not try to populate *other* parameters' values that
    way. If you define a parameter that accepts a complex, structured value,
    then the entire value belongs to the parameter to which it is assigned.
    3. Wouldn't a hash be a better fit to the data than an array of
    key/value pairs anyway?

    What are you trying to achieve by this approach? There is likely a better
    way.


    John

    --
    You received this message because you are subscribed to the Google Groups
    "Puppet Users" group.
    To view this discussion on the web visit
    https://groups.google.com/d/msg/puppet-users/-/yDOmbdqEY_sJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to
    puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/puppet-users?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Nan Liu at Nov 13, 2012 at 6:59 pm

    On Tue, Nov 13, 2012 at 7:33 AM, fatmcgav wrote:

    One of the functions required is the ability to set 'options' against a
    given volume.
    What I want to do is create a provider that accepts a volume name and a
    list of volume options with their corresponding settings, and then iterate
    through the provided list making a webservice call for each option.

    So to give a better example of the provider in pastebin:
    netapp_volume_options { 'v_puppet_test12111508':
    options => ['convert_ucode=on', 'no_atime_update=on'],
    }
    Yeah this seems to make more sense as a hash:

    options => { 'convert_ucode' => 'on', 'no_atime_update' => 'on' }

    I'm assuming this is just parameter, if it's a property add the following
    method to the type and you should get a reasonable output:

    def should_to_s(v)
    v.inspect
    end

    def is_to_s(v)
    v.inspect
    end

    Thanks,

    Nan

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Fatmcgav at Nov 13, 2012 at 7:04 pm
    Nan

    Cheers for the response.

    Yes this is just a parameter...

    What's the easiest way to work with them in the provider?

    Cheers
    Gavin
    On Nov 13, 2012 7:00 PM, "Nan Liu" wrote:
    On Tue, Nov 13, 2012 at 7:33 AM, fatmcgav wrote:

    One of the functions required is the ability to set 'options' against a
    given volume.
    What I want to do is create a provider that accepts a volume name and a
    list of volume options with their corresponding settings, and then iterate
    through the provided list making a webservice call for each option.

    So to give a better example of the provider in pastebin:
    netapp_volume_options { 'v_puppet_test12111508':
    options => ['convert_ucode=on', 'no_atime_update=on'],
    }
    Yeah this seems to make more sense as a hash:

    options => { 'convert_ucode' => 'on', 'no_atime_update' => 'on' }

    I'm assuming this is just parameter, if it's a property add the following
    method to the type and you should get a reasonable output:

    def should_to_s(v)
    v.inspect
    end

    def is_to_s(v)
    v.inspect
    end

    Thanks,

    Nan

    --
    You received this message because you are subscribed to the Google Groups
    "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to
    puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/puppet-users?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Gavin Williams at Nov 13, 2012 at 7:19 pm
    After a quick google, came up with:

    #!/usr/bin/env ruby
    grades = { "Bob" => 82,
    "Jim" => 94,
    "Billy" => 58
    }

    grades.each do|name,grade|
    puts "#{name}: #{grade}"
    end

    So now all I need to do is pull the existing options values and compile a
    hash to compare in the exists?, and use the above in the create...

    Quick question on the create - how will it handle one property that
    matches, but one property that doesn't?

    Cheers
    Gavin
    On Tuesday, 13 November 2012 19:04:31 UTC, Gavin Williams wrote:

    Nan

    Cheers for the response.

    Yes this is just a parameter...

    What's the easiest way to work with them in the provider?

    Cheers
    Gavin
    On Nov 13, 2012 7:00 PM, "Nan Liu" wrote:
    On Tue, Nov 13, 2012 at 7:33 AM, fatmcgav wrote:

    One of the functions required is the ability to set 'options' against a
    given volume.
    What I want to do is create a provider that accepts a volume name and a
    list of volume options with their corresponding settings, and then iterate
    through the provided list making a webservice call for each option.

    So to give a better example of the provider in pastebin:
    netapp_volume_options { 'v_puppet_test12111508':
    options => ['convert_ucode=on', 'no_atime_update=on'],
    }
    Yeah this seems to make more sense as a hash:

    options => { 'convert_ucode' => 'on', 'no_atime_update' => 'on' }

    I'm assuming this is just parameter, if it's a property add the following
    method to the type and you should get a reasonable output:

    def should_to_s(v)
    v.inspect
    end

    def is_to_s(v)
    v.inspect
    end

    Thanks,

    Nan

    --
    You received this message because you are subscribed to the Google Groups
    "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to
    puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/puppet-users?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/mc453A4A648J.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Nan Liu at Nov 13, 2012 at 7:50 pm

    On Tue, Nov 13, 2012 at 11:19 AM, Gavin Williams wrote:

    After a quick google, came up with:

    #!/usr/bin/env ruby
    grades = { "Bob" => 82,
    "Jim" => 94,
    "Billy" => 58
    }

    grades.each do|name,grade|
    puts "#{name}: #{grade}"
    end

    So now all I need to do is pull the existing options values and compile a
    hash to compare in the exists?, and use the above in the create...


    Quick question on the create - how will it handle one property that
    matches, but one property that doesn't?
    You need a hash diff between current values and desired values and iterate
    through the difference. Hash properties are a bit more work, because the
    retrieve method may return more options than you care to set. You have the
    option to either munge and include default value to the user supplied
    value, or override insync? method so the comparison operation does not
    invoke option= method if the user specified value is a subset of the return
    hash from the option method.

    Alternatively if you only have a short number of options, you can just
    implement them as properties instead.

    Thanks,

    Nan

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Fatmcgav at Nov 13, 2012 at 7:58 pm
    Nan

    Cheers again...

    Looks like overriding the 'insync?' method is the way to go, as I'm only
    interested in checking/setting property values that are being passed
    through...

    Any insync? examples that I could refer to?

    Cheers
    Gavin

    On 13 November 2012 19:50, Nan Liu wrote:
    On Tue, Nov 13, 2012 at 11:19 AM, Gavin Williams wrote:

    After a quick google, came up with:

    #!/usr/bin/env ruby
    grades = { "Bob" => 82,
    "Jim" => 94,
    "Billy" => 58
    }

    grades.each do|name,grade|
    puts "#{name}: #{grade}"
    end

    So now all I need to do is pull the existing options values and compile a
    hash to compare in the exists?, and use the above in the create...


    Quick question on the create - how will it handle one property that
    matches, but one property that doesn't?
    You need a hash diff between current values and desired values and iterate
    through the difference. Hash properties are a bit more work, because the
    retrieve method may return more options than you care to set. You have the
    option to either munge and include default value to the user supplied
    value, or override insync? method so the comparison operation does not
    invoke option= method if the user specified value is a subset of the return
    hash from the option method.

    Alternatively if you only have a short number of options, you can just
    implement them as properties instead.

    Thanks,

    Nan

    --
    You received this message because you are subscribed to the Google Groups
    "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to
    puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/puppet-users?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Nan Liu at Nov 13, 2012 at 9:56 pm

    On Tue, Nov 13, 2012 at 11:58 AM, fatmcgav wrote:

    Looks like overriding the 'insync?' method is the way to go, as I'm only
    interested in checking/setting property values that are being passed
    through...

    Any insync? examples that I could refer to?
    There's a simple example here:
    https://github.com/puppetlabs/puppetlabs-f5/blob/master/lib/puppet/type/f5_virtualserver.rb#L13-15

    Search puppet source code lib/puppet/type/ for additional ones.

    Thanks,

    Nan

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Gavin Williams at Nov 14, 2012 at 12:04 pm
    Ok, I've just pushed the latest code to Github:
    https://github.com/fatmcgav/fatmcgav-netapp/commit/d5ae999fc49b1de6726e8f4b7027648cf2eb64a2

    I've managed to get the *create *functioning correctly, and updating the
    NetApp options as required.

    *exists?* has also been fleshed out a lot.
    Logic is that it will pull back a list of the current options set against
    the referenced volume, and then construct a hash of the returned key=>value
    pairs.
    The matching keys are then pulled from the current options and the setting
    options hashes, and the values of those keys compared.
    If they are different, then the *create *should be triggered.

    This is working fine in principle.

    However the current issue is that the *exists?* will *return false*whenever a single property value doesn't match. The create will then
    process the whole list of setting options, rather than just the mis-matched
    one(s)...

    An example run gives:

    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    no_atime_update. Current value = off. New value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options:
    no_atime_update values don't match.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: setting
    Netapp Volume options against volume v_puppet_test12111508.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    no_atime_update, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    no_atime_update set against Volume v_puppet_test12111508.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    convert_ucode, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    convert_ucode set against Volume v_puppet_test12111508.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Options set successfully against Volume v_puppet_test12111508.
    This is based on a config of:
    netapp_volume_options { 'v_puppet_test12111508':
    options => {'convert_ucode' => 'on', 'no_atime_update' =>
    'on'},
    require => Netapp_volume['v_puppet_test12111508']
    }
    *convert_ucode* should match, and *no_atime_update* obviously didn't...

    Any ideas?

    Haven't as yet done anything with *insync?* yet, as if I'm honest it
    slightly baffles me currently...

    Cheers
    Gavin
    On Tuesday, 13 November 2012 21:57:01 UTC, Nan Liu wrote:

    On Tue, Nov 13, 2012 at 11:58 AM, fatmcgav <fatm...@gmail.com<javascript:>
    wrote:
    Looks like overriding the 'insync?' method is the way to go, as I'm only
    interested in checking/setting property values that are being passed
    through...

    Any insync? examples that I could refer to?
    There's a simple example here:

    https://github.com/puppetlabs/puppetlabs-f5/blob/master/lib/puppet/type/f5_virtualserver.rb#L13-15

    Search puppet source code lib/puppet/type/ for additional ones.

    Thanks,

    Nan
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/rKYLDjFxXJAJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Jcbollinger at Nov 14, 2012 at 2:49 pm

    On Wednesday, November 14, 2012 6:04:11 AM UTC-6, Gavin Williams wrote:
    Ok, I've just pushed the latest code to Github:
    https://github.com/fatmcgav/fatmcgav-netapp/commit/d5ae999fc49b1de6726e8f4b7027648cf2eb64a2

    I've managed to get the *create *functioning correctly, and updating the
    NetApp options as required.

    *exists?* has also been fleshed out a lot.
    Logic is that it will pull back a list of the current options set against
    the referenced volume, and then construct a hash of the returned key=>value
    pairs.
    The matching keys are then pulled from the current options and the setting
    options hashes, and the values of those keys compared.
    If they are different, then the *create *should be triggered.

    This is working fine in principle.

    However the current issue is that the *exists?* will *return false*whenever a single property value doesn't match. The create will then
    process the whole list of setting options, rather than just the mis-matched
    one(s)...

    Your design sounds flawed to me. I think you're getting tripped up by the
    difference between modelling all the options as a group (as you are doing)
    and modelling individual options. I'm not certain that it makes sense for *
    exists?* ever to return false, for even an empty set of options is still a
    set of options. If it never returns false then your *create* method will
    never be called, so it can be empty.

    Notably missing from your code, however, is a non-trivial implementation of
    *options=*, the setter method for your main property. Puppet will invoke
    that method at least if it finds that the target value assigned to the
    resource differs from the actual value read from the provider. It would
    normally be in that method that your provider does the actual work of
    modifying the existing target resource (i.e. setting the options). If you
    don't want to re-set all the options, then this would be a good place to
    check what changed, and set only those.


    An example run gives:

    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    no_atime_update. Current value = off. New value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options:
    no_atime_update values don't match.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: setting
    Netapp Volume options against volume v_puppet_test12111508.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    no_atime_update, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option no_atime_update set against Volume v_puppet_test12111508.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    convert_ucode, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option convert_ucode set against Volume v_puppet_test12111508.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Options set successfully against Volume v_puppet_test12111508.
    This is based on a config of:
    netapp_volume_options { 'v_puppet_test12111508':
    options => {'convert_ucode' => 'on', 'no_atime_update' =>
    'on'},
    require => Netapp_volume['v_puppet_test12111508']
    }
    *convert_ucode* should match, and *no_atime_update* obviously didn't...

    Any ideas?

    Haven't as yet done anything with *insync?* yet, as if I'm honest it
    slightly baffles me currently...

    I'm not sure you need to do anything for insync?. I think Puppet by
    default compares the actual property values (obtained from the provider via
    their getter methods) with the ones set on the resource (as parsed from the
    manifest), and considers the resource to be in sync if they all are equal.


    John

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/9SBH1F9q4kIJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Gavin Williams at Nov 14, 2012 at 4:56 pm
    John

    Cheers for the response... Looks like I've got some more reading to do to
    get my head around some of the more complex stuff...

    Think you're right in that I'm trying to treat the options as a whole,
    rather than individual items...

    Am I better off moving to a prefetch/flush style provider, rather than the
    getter/setting method?

    Cheers
    Gavin
    On Wednesday, 14 November 2012 14:49:53 UTC, jcbollinger wrote:


    On Wednesday, November 14, 2012 6:04:11 AM UTC-6, Gavin Williams wrote:

    Ok, I've just pushed the latest code to Github:
    https://github.com/fatmcgav/fatmcgav-netapp/commit/d5ae999fc49b1de6726e8f4b7027648cf2eb64a2

    I've managed to get the *create *functioning correctly, and updating the
    NetApp options as required.

    *exists?* has also been fleshed out a lot.
    Logic is that it will pull back a list of the current options set against
    the referenced volume, and then construct a hash of the returned key=>value
    pairs.
    The matching keys are then pulled from the current options and the
    setting options hashes, and the values of those keys compared.
    If they are different, then the *create *should be triggered.

    This is working fine in principle.

    However the current issue is that the *exists?* will *return false*whenever a single property value doesn't match. The create will then
    process the whole list of setting options, rather than just the mis-matched
    one(s)...

    Your design sounds flawed to me. I think you're getting tripped up by the
    difference between modelling all the options as a group (as you are doing)
    and modelling individual options. I'm not certain that it makes sense for
    *exists?* ever to return false, for even an empty set of options is still
    a set of options. If it never returns false then your *create* method
    will never be called, so it can be empty.

    Notably missing from your code, however, is a non-trivial implementation
    of *options=*, the setter method for your main property. Puppet will
    invoke that method at least if it finds that the target value assigned to
    the resource differs from the actual value read from the provider. It
    would normally be in that method that your provider does the actual work of
    modifying the existing target resource (i.e. setting the options). If you
    don't want to re-set all the options, then this would be a good place to
    check what changed, and set only those.


    An example run gives:

    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    no_atime_update. Current value = off. New value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options:
    no_atime_update values don't match.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: setting
    Netapp Volume options against volume v_puppet_test12111508.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    no_atime_update, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option no_atime_update set against Volume v_puppet_test12111508.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    convert_ucode, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option convert_ucode set against Volume v_puppet_test12111508.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Options set successfully against Volume v_puppet_test12111508.
    This is based on a config of:
    netapp_volume_options { 'v_puppet_test12111508':
    options => {'convert_ucode' => 'on', 'no_atime_update'
    => 'on'},
    require => Netapp_volume['v_puppet_test12111508']
    }
    *convert_ucode* should match, and *no_atime_update* obviously didn't...

    Any ideas?

    Haven't as yet done anything with *insync?* yet, as if I'm honest it
    slightly baffles me currently...

    I'm not sure you need to do anything for insync?. I think Puppet by
    default compares the actual property values (obtained from the provider via
    their getter methods) with the ones set on the resource (as parsed from the
    manifest), and considers the resource to be in sync if they all are equal.


    John
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/By9h4HHOYrIJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Nan Liu at Nov 14, 2012 at 5:37 pm

    On Wed, Nov 14, 2012 at 8:56 AM, Gavin Williams wrote:

    Cheers for the response... Looks like I've got some more reading to do to
    get my head around some of the more complex stuff...
    I'm not sure why netapp_volume_options is a separate resource. You are
    already managing the volume state in netapp_volume, and all netapp volume
    options should be properties in netapp_volume instead.

    Think you're right in that I'm trying to treat the options as a whole,
    rather than individual items...
    The resource seems to make more sense modeled as:

    netapp_volume { 'example':
    ensure => present,
    initsize => '2GB',
    convert_ucode => 'on',
    no_atime_update => 'on',
    }

    The provider exists? method should simply return true if the volume is
    present and it should not compare the property values (that's what Puppet
    does for you). One key difference is volume options should be newproperty.
    So far you implemented all attributes as parameters, and puppet will not
    retrieve and compare parameter values (i.e. it will not call
    initsize/initsize= method).

    The convert_ucode method return the option value. and convert_ucode= method
    updates the setting.

    Am I better off moving to a prefetch/flush style provider, rather than the
    getter/setting method?
    I would avoid prefetch/flush until you have the provider working with
    individual get/set first.

    Thanks,

    Nan

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Fatmcgav at Nov 14, 2012 at 5:44 pm
    Nan

    Cheers again for the info...

    Now I think more about it, you may well be right in that it should be part
    of the netapp_volume provider...

    However I'm not sure that having individual params/properties for each
    volume option is the right way - The list of possible volume options
    currently stands at 36.. I don't really fancy having to implement a
    param/property for each of those... However I could see a single 'options'
    hash param/prop working for that... Although then I'm back to the same
    challenge of making sure each volume option is set & maintained
    correctly...

    The other challenge is that to set volume options is a different webservice
    call to the volume-list/volume-create method, but I'm guessing I can just
    get that handled with another def in the provider...

    Thoughts?

    Cheers
    Gav

    On 14 November 2012 17:29, Nan Liu wrote:
    On Wed, Nov 14, 2012 at 8:56 AM, Gavin Williams wrote:

    Cheers for the response... Looks like I've got some more reading to do to
    get my head around some of the more complex stuff...
    I'm not sure why netapp_volume_options is a separate resource. You are
    already managing the volume state in netapp_volume, and all netapp volume
    options should be properties in netapp_volume instead.

    Think you're right in that I'm trying to treat the options as a whole,
    rather than individual items...
    The resource seems to make more sense modeled as:

    netapp_volume { 'example':
    ensure => present,
    initsize => '2GB',
    convert_ucode => 'on',
    no_atime_update => 'on',
    }

    The provider exists? method should simply return true if the volume is
    present and it should not compare the property values (that's what Puppet
    does for you). One key difference is volume options should be newproperty.
    So far you implemented all attributes as parameters, and puppet will not
    retrieve and compare parameter values (i.e. it will not call
    initsize/initsize= method).

    The convert_ucode method return the option value. and convert_ucode=
    method updates the setting.

    Am I better off moving to a prefetch/flush style provider, rather than
    the getter/setting method?
    I would avoid prefetch/flush until you have the provider working with
    individual get/set first.

    Thanks,

    Nan

    --
    You received this message because you are subscribed to the Google Groups
    "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to
    puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/puppet-users?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Nan Liu at Nov 14, 2012 at 6:08 pm

    On Wed, Nov 14, 2012 at 9:44 AM, fatmcgav wrote:

    However I'm not sure that having individual params/properties for each
    volume option is the right way - The list of possible volume options
    currently stands at 36.. I don't really fancy having to implement a
    param/property for each of those... However I could see a single 'options'
    hash param/prop working for that... Although then I'm back to the same
    challenge of making sure each volume option is set & maintained
    correctly...
    Creating 36 options is a bit of work, but they will be documented as
    resource properties, and puppet takes care of some of problem of which
    option needs to be updated and only call the setter for a specific option
    when necessary. I suspect the option values getter/setter are very similar
    so you can use define_method to reduce boilerplate code. Certainly you can
    create a single property with a hash value to manage all 36 options, but in
    this case the option property need to do a few extra things:

    1. option method should return all 36 options in a hash.
    2. insync? should return true as long the user specified subset of option
    values is the same as the one returned by the previous method. It might
    make sense to maintain the list of option that needs to be updated for the
    setter method.
    3. option= should determine which options need update and perform them.

    The other challenge is that to set volume options is a different webservice
    call to the volume-list/volume-create method, but I'm guessing I can just
    get that handled with another def in the provider...
    If it makes sense to have them in one resource, whether it's one or more
    api call is just something the provider abstracts away. I wouldn't be
    concerned how many api/commands the provider uses to manage a resource.

    HTH,

    Nan

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Gavin Williams at Nov 16, 2012 at 11:23 am
    Ok, after a considerable amount of reading, and some expermentation, I
    think I've got a working netapp_volume type/provider which can handle
    setting volume options! :D

    Have branched the code to play with, so it's available here:
    https://github.com/fatmcgav/fatmcgav-netapp/tree/volume_options_testing

    Overall, it seems to work quite well. When first creating volumes, it
    correctly creates the volume using *create*, and then drops into *options=*to set the volume options, as shown in this log exert:

    ^[[0;32mInfo^[[0m: Applying configuration version '1353061861'
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_export[/vol/v_puppet_test1611120925/q_puppet_test1611120925]/require:
    requires Netapp_qtree[q_puppet_test1611120925]
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_qtree[q_puppet_test1611120925]/require:
    requires Netapp_volume[v_puppet_test1611120925]
    ^[[0;36mDebug^[[0m: Stage[main]: Skipping host resources because running
    on a device
    ^[[0;36mDebug^[[0m: Class[Main]: Skipping host resources because running
    on a device
    ^[[0;36mDebug^[[0m: Node[actint-star-nactl01]: Skipping host resources
    because running on a device
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: checking existance of
    Netapp Volume v_puppet_test1611120925
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Vol Info: <results
    errno="13040" reason="No volume named 'v_puppet_test1611120925' exists"
    status="failed"></results>
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Volume doesn't exist.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: creating Netapp
    Volume v_puppet_test1611120925 of initial size 10g in Aggregate aggr01
    using space reserve of none.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Volume
    v_puppet_test1611120925 created successfully. Setting options...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Got to options=
    setter...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    try_first, Value = volume_grow
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    try_first set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    no_atime_update, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    no_atime_update set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    convert_ucode, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    convert_ucode set against Volume v_puppet_test1611120925.
    /Stage[main]//Node[actint-star-nactl01]/Netapp_volume[v_puppet_test1611120925]/ensure:
    created
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_volume[v_puppet_test1611120925]:
    The container Node[actint-star-nactl01] will propagate my refresh event
    ^[[0;36mDebug^[[0m: Class[Settings]: Skipping host resources because
    running on a device
    ^[[0;36mDebug^[[0m: Class[Settings]: Skipping host resources because
    running on a device
    When running against a volume that already exists, I can see it dropping
    into *options*, pulling a list of the current volume options, and then
    comparing that list against the resource *:options *value.

    However I don't think the insync is still quite right... It still appears
    to be going through the whole *:options* list, even if they all match...
    ^[[0;32mInfo^[[0m: Applying configuration version '1353061861'
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_qtree[q_puppet_test1611120925]/require:
    requires Netapp_volume[v_puppet_test1611120925]
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_export[/vol/v_puppet_test1611120925/q_puppet_test1611120925]/require:
    requires Netapp_qtree[q_puppet_test1611120925]
    ^[[0;36mDebug^[[0m: Stage[main]: Skipping host resources because running
    on a device
    ^[[0;36mDebug^[[0m: Class[Main]: Skipping host resources because running
    on a device
    ^[[0;36mDebug^[[0m: Node[actint-star-nactl01]: Skipping host resources
    because running on a device
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: checking existance of
    Netapp Volume v_puppet_test1611120925
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Vol Info: <results
    status="passed">
    ...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Volume exists.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Vol Options: <results
    status="passed">
    ...
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    convert_ucode. Current value = on. New value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    try_first. Current value = volume_grow. New value = volume_grow
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    no_atime_update. Current value = on. New value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Result is a hash.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Returning result...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Got to options=
    setter...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    convert_ucode, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    convert_ucode set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    try_first, Value = volume_grow
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    try_first set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    no_atime_update, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    no_atime_update set against Volume v_puppet_test1611120925.
    /Stage[main]//Node[actint-star-nactl01]/Netapp_volume[v_puppet_test1611120925]/options:
    options changed '{}' to '[{"convert_ucode"=>"on",
    "try_first"=>"volume_grow", "no_atime_update"=>"on"}]'
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_volume[v_puppet_test1611120925]:
    The container Node[actint-star-nactl01] will propagate my refresh event
    ^[[0;36mDebug^[[0m: Class[Settings]: Skipping host resources because
    running on a device
    ^[[0;36mDebug^[[0m: Class[Settings]: Skipping host resources because
    running on a device

    As you can see, all 3 options match, but all 3 options are then set in *
    options=*.

    Any ideas?

    Cheers
    Gavin
    On Wednesday, 14 November 2012 18:08:41 UTC, Nan Liu wrote:

    On Wed, Nov 14, 2012 at 9:44 AM, fatmcgav <fatm...@gmail.com <javascript:>
    wrote:
    However I'm not sure that having individual params/properties for each
    volume option is the right way - The list of possible volume options
    currently stands at 36.. I don't really fancy having to implement a
    param/property for each of those... However I could see a single 'options'
    hash param/prop working for that... Although then I'm back to the same
    challenge of making sure each volume option is set & maintained
    correctly...
    Creating 36 options is a bit of work, but they will be documented as
    resource properties, and puppet takes care of some of problem of which
    option needs to be updated and only call the setter for a specific option
    when necessary. I suspect the option values getter/setter are very similar
    so you can use define_method to reduce boilerplate code. Certainly you
    can create a single property with a hash value to manage all 36 options,
    but in this case the option property need to do a few extra things:

    1. option method should return all 36 options in a hash.
    2. insync? should return true as long the user specified subset of option
    values is the same as the one returned by the previous method. It might
    make sense to maintain the list of option that needs to be updated for the
    setter method.
    3. option= should determine which options need update and perform them.

    The other challenge is that to set volume options is a different
    webservice call to the volume-list/volume-create method, but I'm guessing I
    can just get that handled with another def in the provider...
    If it makes sense to have them in one resource, whether it's one or more
    api call is just something the provider abstracts away. I wouldn't be
    concerned how many api/commands the provider uses to manage a resource.

    HTH,

    Nan
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/LH30IJ9IrigJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Gavin Williams at Nov 16, 2012 at 11:44 am
    Ok, think I've kinda answered my own question...

    Added some additional logging to *insync?*, and spotted a flaw in my *
    'options'* logic. I was stripping matching values at that level, rather
    than letting *insync *take care of that.

    So tweaked the *option* as follows:

    --- a/lib/puppet/provider/netapp_volume/netapp_volume.rb
    +++ b/lib/puppet/provider/netapp_volume/netapp_volume.rb
    @@ -77,7 +77,7 @@
    result = {}
    matched_options.each do |name|
    Puppet.debug("Puppet::Provider::netapp_volume_options: Matched Name
    #{name}. Current value = #{[current_options[name]]}. New value =
    #{[set_options[name]]} \n")
    - result[name] = current_options[name] unless current_options[name]
    == set_options[name]
    + result[name] = current_options[name]
    end
    Puppet.debug("Puppet::Provider::Netapp_volume: Returning result
    hash... \n")
    result
    Can now see *insync? *correctly iterating through, and where they all match
    *options=* doesn't get called :D

    However still looks like if one of the *:options *doesn't match, then the
    whole lot gets set again... I guess that's a reasonable logic in that if
    one doesn't match, it's quite possible other's don't match, so set them all
    to be safe... Unless I missed something?

    Example run of the above is:
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    try_first. Current value = volume_grow. New value = snap_delete
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    convert_ucode. Current value = on. New value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    no_atime_update. Current value = on. New value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Result is a hash.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Returning result...
    ^[[0;36mDebug^[[0m: Checking if is.class and should.class are both
    Hashes...
    ^[[0;36mDebug^[[0m: Both is.class and should.class are Hashes...
    ^[[0;36mDebug^[[0m: Comparing key values for try_first. Is = volume_grow
    Should = snap_delete
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Got to options=
    setter...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    try_first, Value = snap_delete
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    try_first set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    convert_ucode, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    convert_ucode set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    no_atime_update, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume Option
    no_atime_update set against Volume v_puppet_test1611120925.
    /Stage[main]//Node[actint-star-nactl01]/Netapp_volume[v_puppet_test1611120925]/options:
    options changed '{"convert_ucode"=>"on", "try_first"=>"volume_grow",
    "no_atime_update"=>"on"}' to '[{"try_first"=>"snap_delete",
    "convert_ucode"=>"on", "no_atime_update"=>"on"}]'
    Comments welcome.

    Cheers
    Gavin
    *
    *On Friday, 16 November 2012 11:23:41 UTC, Gavin Williams wrote:
    Ok, after a considerable amount of reading, and some expermentation, I
    think I've got a working netapp_volume type/provider which can handle
    setting volume options! :D

    Have branched the code to play with, so it's available here:
    https://github.com/fatmcgav/fatmcgav-netapp/tree/volume_options_testing

    Overall, it seems to work quite well. When first creating volumes, it
    correctly creates the volume using *create*, and then drops into *options=
    * to set the volume options, as shown in this log exert:

    ^[[0;32mInfo^[[0m: Applying configuration version '1353061861'
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_export[/vol/v_puppet_test1611120925/q_puppet_test1611120925]/require:
    requires Netapp_qtree[q_puppet_test1611120925]
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_qtree[q_puppet_test1611120925]/require:
    requires Netapp_volume[v_puppet_test1611120925]
    ^[[0;36mDebug^[[0m: Stage[main]: Skipping host resources because running
    on a device
    ^[[0;36mDebug^[[0m: Class[Main]: Skipping host resources because running
    on a device
    ^[[0;36mDebug^[[0m: Node[actint-star-nactl01]: Skipping host resources
    because running on a device
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: checking existance
    of Netapp Volume v_puppet_test1611120925
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Vol Info: <results
    errno="13040" reason="No volume named 'v_puppet_test1611120925' exists"
    status="failed"></results>
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Volume doesn't exist.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: creating Netapp
    Volume v_puppet_test1611120925 of initial size 10g in Aggregate aggr01
    using space reserve of none.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Volume
    v_puppet_test1611120925 created successfully. Setting options...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Got to options=
    setter...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    try_first, Value = volume_grow
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option try_first set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    no_atime_update, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option no_atime_update set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    convert_ucode, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option convert_ucode set against Volume v_puppet_test1611120925.
    /Stage[main]//Node[actint-star-nactl01]/Netapp_volume[v_puppet_test1611120925]/ensure:
    created
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_volume[v_puppet_test1611120925]:
    The container Node[actint-star-nactl01] will propagate my refresh event
    ^[[0;36mDebug^[[0m: Class[Settings]: Skipping host resources because
    running on a device
    ^[[0;36mDebug^[[0m: Class[Settings]: Skipping host resources because
    running on a device
    When running against a volume that already exists, I can see it dropping
    into *options*, pulling a list of the current volume options, and then
    comparing that list against the resource *:options *value.

    However I don't think the insync is still quite right... It still appears
    to be going through the whole *:options* list, even if they all match...
    ^[[0;32mInfo^[[0m: Applying configuration version '1353061861'
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_qtree[q_puppet_test1611120925]/require:
    requires Netapp_volume[v_puppet_test1611120925]
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_export[/vol/v_puppet_test1611120925/q_puppet_test1611120925]/require:
    requires Netapp_qtree[q_puppet_test1611120925]
    ^[[0;36mDebug^[[0m: Stage[main]: Skipping host resources because running
    on a device
    ^[[0;36mDebug^[[0m: Class[Main]: Skipping host resources because running
    on a device
    ^[[0;36mDebug^[[0m: Node[actint-star-nactl01]: Skipping host resources
    because running on a device
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: checking existance
    of Netapp Volume v_puppet_test1611120925
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Vol Info: <results
    status="passed">
    ...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Volume exists.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Vol Options:
    <results status="passed">
    ...
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    convert_ucode. Current value = on. New value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    try_first. Current value = volume_grow. New value = volume_grow
    ^[[0;36mDebug^[[0m: Puppet::Provider::netapp_volume_options: Matched Name
    no_atime_update. Current value = on. New value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Result is a hash.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Returning result...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume: Got to options=
    setter...
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    convert_ucode, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option convert_ucode set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    try_first, Value = volume_grow
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option try_first set against Volume v_puppet_test1611120925.
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Setting =
    no_atime_update, Value = on
    ^[[0;36mDebug^[[0m: Puppet::Provider::Netapp_volume_options: Volume
    Option no_atime_update set against Volume v_puppet_test1611120925.
    /Stage[main]//Node[actint-star-nactl01]/Netapp_volume[v_puppet_test1611120925]/options:
    options changed '{}' to '[{"convert_ucode"=>"on",
    "try_first"=>"volume_grow", "no_atime_update"=>"on"}]'
    ^[[0;36mDebug^[[0m:
    /Stage[main]//Node[actint-star-nactl01]/Netapp_volume[v_puppet_test1611120925]:
    The container Node[actint-star-nactl01] will propagate my refresh event
    ^[[0;36mDebug^[[0m: Class[Settings]: Skipping host resources because
    running on a device
    ^[[0;36mDebug^[[0m: Class[Settings]: Skipping host resources because
    running on a device

    As you can see, all 3 options match, but all 3 options are then set in *
    options=*.

    Any ideas?

    Cheers
    Gavin
    On Wednesday, 14 November 2012 18:08:41 UTC, Nan Liu wrote:
    On Wed, Nov 14, 2012 at 9:44 AM, fatmcgav wrote:

    However I'm not sure that having individual params/properties for each
    volume option is the right way - The list of possible volume options
    currently stands at 36.. I don't really fancy having to implement a
    param/property for each of those... However I could see a single 'options'
    hash param/prop working for that... Although then I'm back to the same
    challenge of making sure each volume option is set & maintained
    correctly...
    Creating 36 options is a bit of work, but they will be documented as
    resource properties, and puppet takes care of some of problem of which
    option needs to be updated and only call the setter for a specific option
    when necessary. I suspect the option values getter/setter are very similar
    so you can use define_method to reduce boilerplate code. Certainly you
    can create a single property with a hash value to manage all 36 options,
    but in this case the option property need to do a few extra things:

    1. option method should return all 36 options in a hash.
    2. insync? should return true as long the user specified subset of option
    values is the same as the one returned by the previous method. It might
    make sense to maintain the list of option that needs to be updated for the
    setter method.
    3. option= should determine which options need update and perform them.

    The other challenge is that to set volume options is a different
    webservice call to the volume-list/volume-create method, but I'm guessing I
    can just get that handled with another def in the provider...
    If it makes sense to have them in one resource, whether it's one or more
    api call is just something the provider abstracts away. I wouldn't be
    concerned how many api/commands the provider uses to manage a resource.

    HTH,

    Nan
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/VrrAotSP0IQJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Jcbollinger at Nov 26, 2012 at 5:42 pm

    On Friday, November 16, 2012 5:44:09 AM UTC-6, Gavin Williams wrote:
    However still looks like if one of the *:options *doesn't match, then the
    whole lot gets set again... I guess that's a reasonable logic in that if
    one doesn't match, it's quite possible other's don't match, so set them all
    to be safe... Unless I missed something?
    What you continue to miss is that you are treating all the options as a
    single property. That's ok, but it means that at the level of the resource
    / provider interface, Puppet cannot set individual options, only all of
    them as a group. You can't have it both ways.

    Inside your provider, however, you can implement the interface to the
    underlying tool any way you want. In particular, in your options=
    function, you can look at the current value and the value being set,
    extract the changes, and apply only those. I guess you were trying to do
    something like that in your insync? function, but if you're doing something
    like that then options= is probably where it should go.


    John

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/uFOu3gp_0kQJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Fatmcgav at Nov 26, 2012 at 6:19 pm
    John

    Cheers again, that could be a good alternative way of doing it... Use
    insync? just to trigger options=, and then work out what actually needs
    setting there...

    Cheers
    Gav
    On Nov 26, 2012 5:42 PM, "jcbollinger" wrote:


    On Friday, November 16, 2012 5:44:09 AM UTC-6, Gavin Williams wrote:

    However still looks like if one of the *:options *doesn't match, then
    the whole lot gets set again... I guess that's a reasonable logic in that
    if one doesn't match, it's quite possible other's don't match, so set them
    all to be safe... Unless I missed something?
    What you continue to miss is that you are treating all the options as a
    single property. That's ok, but it means that at the level of the resource
    / provider interface, Puppet cannot set individual options, only all of
    them as a group. You can't have it both ways.

    Inside your provider, however, you can implement the interface to the
    underlying tool any way you want. In particular, in your options=
    function, you can look at the current value and the value being set,
    extract the changes, and apply only those. I guess you were trying to do
    something like that in your insync? function, but if you're doing something
    like that then options= is probably where it should go.


    John

    --
    You received this message because you are subscribed to the Google Groups
    "Puppet Users" group.
    To view this discussion on the web visit
    https://groups.google.com/d/msg/puppet-users/-/uFOu3gp_0kQJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to
    puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/puppet-users?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Jcbollinger at Nov 26, 2012 at 7:37 pm

    On Monday, November 26, 2012 12:19:09 PM UTC-6, Gavin Williams wrote:
    John

    Cheers again, that could be a good alternative way of doing it... Use
    insync? just to trigger options=, and then work out what actually needs
    setting there...
    That's not just a good alternative, it's the right way to do it. The job
    of insync? is simply to determine whether all of the resource's properties
    have the expected target values. No more, no less. The job of property
    setter methods such as options= is to update the underlying resource(*) so
    that the affected property has the assigned value. It is there, at the
    interface between Puppet and the system, that you have flexibility.

    (*) The property setters of providers that implement flush() work a bit
    differently, but I don't think that's relevant here. I mention it for
    completeness.


    John

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/OEk9ZWDBvWUJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Fatmcgav at Nov 26, 2012 at 10:04 pm
    John,

    Again, very helpful...
    My knowledge of puppet is growing every day thanks to posts like this :-)

    Cheers
    Gavin
    On Nov 26, 2012 7:30 PM, "jcbollinger" wrote:


    On Monday, November 26, 2012 12:19:09 PM UTC-6, Gavin Williams wrote:

    John

    Cheers again, that could be a good alternative way of doing it... Use
    insync? just to trigger options=, and then work out what actually needs
    setting there...
    That's not just a good alternative, it's the right way to do it. The job
    of insync? is simply to determine whether all of the resource's properties
    have the expected target values. No more, no less. The job of property
    setter methods such as options= is to update the underlying resource(*) so
    that the affected property has the assigned value. It is there, at the
    interface between Puppet and the system, that you have flexibility.

    (*) The property setters of providers that implement flush() work a bit
    differently, but I don't think that's relevant here. I mention it for
    completeness.


    John

    --
    You received this message because you are subscribed to the Google Groups
    "Puppet Users" group.
    To view this discussion on the web visit
    https://groups.google.com/d/msg/puppet-users/-/OEk9ZWDBvWUJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to
    puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/puppet-users?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Gavin Williams at Jan 7, 2013 at 9:52 am
    Firstly, sorry for bringing this thread back - However I thought it
    probably best as it's got all the history of what I was working towards
    etc...

    Anyways, onto the problem at hand.
    I've created a new property against my netapp_volume provider called *
    :snapschedule*.
    This property is taking a hash, and doing something very similar to the *:options
    *property above...

    Code was committed under:
    https://github.com/fatmcgav/fatmcgav-netapp/commit/6427581c546f2ccb5ebf2f19826afad38b424b9d

    However it looks like something isnt quite right with the insync? def, as
    I'm seeing the following in puppet device run logs:
    Info: starting applying configuration to actint-star-nactl01 at
    actint-star-nactl01
    Warning: Local environment: "production" doesn't match server specified
    node environment "test", switching agent to "test".
    Info: Retrieving plugin
    Info: Caching catalog for actint-star-nactl01
    Info: Applying configuration version '1357295208'
    Processing Volume puppet_db02_oractrl
    /Stage[main]/Act::Storage::Netapp/Act::Util::Netapp::Volume[puppet_db02_oractrl]/Netapp_notify[volume_define_puppet_db02_oractrl]/message:
    defined 'message' as 'Processing Volume puppet_db02_oractrl'
    /Stage[main]/Act::Storage::Netapp/Act::Util::Netapp::Volume[puppet_db02_oractrl]/Netapp_volume[v_puppet_db02_oractrl]/snapschedule:
    snapschedule changed '{"days"=>0, "hours"=>0, "weeks"=>0, "minutes"=>0}' to
    '[{"hours"=>"0", "days"=>"0", "minutes"=>"0", "weeks"=>"0"}]'
    Processing Volume puppet_db02_oraarch
    /Stage[main]/Act::Storage::Netapp/Act::Util::Netapp::Volume[puppet_db02_oraarch]/Netapp_notify[volume_define_puppet_db02_oraarch]/message:
    defined 'message' as 'Processing Volume puppet_db02_oraarch'
    Processing Volume puppet_db02_data
    /Stage[main]/Act::Storage::Netapp/Act::Util::Netapp::Volume[puppet_db02_data]/Netapp_notify[volume_define_puppet_db02_data]/message:
    defined 'message' as 'Processing Volume puppet_db02_data'
    /Stage[main]/Act::Storage::Netapp/Act::Util::Netapp::Volume[puppet_db02_data]/Netapp_volume[v_puppet_db02_data]/snapschedule:
    snapschedule changed '{"days"=>0, "hours"=>0, "weeks"=>0, "minutes"=>0}' to
    '[{"hours"=>"0", "days"=>"0", "minutes"=>"0", "weeks"=>"0"}]'

    As you can see, the hash contents are identical... However the '*to*' hash
    is wrapped in an array...

    Any ideas where I could be going wrong?

    Cheers
    Gavin
    On Monday, 26 November 2012 22:04:18 UTC, Gavin Williams wrote:

    John,

    Again, very helpful...
    My knowledge of puppet is growing every day thanks to posts like this :-)

    Cheers
    Gavin
    On Nov 26, 2012 7:30 PM, "jcbollinger" wrote:


    On Monday, November 26, 2012 12:19:09 PM UTC-6, Gavin Williams wrote:

    John

    Cheers again, that could be a good alternative way of doing it... Use
    insync? just to trigger options=, and then work out what actually needs
    setting there...
    That's not just a good alternative, it's the right way to do it. The job
    of insync? is simply to determine whether all of the resource's properties
    have the expected target values. No more, no less. The job of property
    setter methods such as options= is to update the underlying resource(*) so
    that the affected property has the assigned value. It is there, at the
    interface between Puppet and the system, that you have flexibility.

    (*) The property setters of providers that implement flush() work a bit
    differently, but I don't think that's relevant here. I mention it for
    completeness.


    John

    --
    You received this message because you are subscribed to the Google Groups
    "Puppet Users" group.
    To view this discussion on the web visit
    https://groups.google.com/d/msg/puppet-users/-/OEk9ZWDBvWUJ.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to
    puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at
    http://groups.google.com/group/puppet-users?hl=en.
    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/DWXnKlb2V28J.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.
  • Jakov Sosic at Nov 21, 2012 at 4:42 pm

    On 11/13/2012 08:19 PM, Gavin Williams wrote:
    After a quick google, came up with:

    #!/usr/bin/env ruby

    grades = { "Bob" => 82,
    "Jim" => 94,
    "Billy" => 58
    }

    grades.each do|name,grade|
    puts "#{name}: #{grade}"
    end


    So now all I need to do is pull the existing options values and compile
    a hash to compare in the exists?, and use the above in the create...

    Quick question on the create - how will it handle one property that
    matches, but one property that doesn't?
    I've done a similar mangling (from/to hashes) in my Cobbler module, I
    could send it to you so you can learn by example, if you're interested.

    But to answer your main point - if the sorted hashes aren't the same,
    provider will try to change the state to the new hash.

    --
    You received this message because you are subscribed to the Google Groups "Puppet Users" group.
    To post to this group, send email to puppet-users@googlegroups.com.
    To unsubscribe from this group, send email to puppet-users+unsubscribe@googlegroups.com.
    For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.

Related Discussions

Discussion Navigation
viewthread | post
Discussion Overview
grouppuppet-users @
categoriespuppet
postedNov 13, '12 at 2:47p
activeJan 7, '13 at 9:52a
posts23
users4
websitepuppetlabs.com

People

Translate

site design / logo © 2022 Grokbase