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 <fatm...@gmail.com> 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+unsubscr...@googlegroups.com.
For more options, visit this group at 
http://groups.google.com/group/puppet-users?hl=en.

Reply via email to