Geoff Crompton
2009-Mar-20 21:20 UTC
[Puppet Users] scoping of variables in modules for reuse
Hi All, I wanted to make a module of mine to be more re-usable by declaring a variable somewhere in it. I wanted users to be able to override the variable, but I also wanted the module to work if they instantiated the class directly. I''m using puppet 0.24.5 (and the -3 debian subversion) and I found that if I do something like the following: class reprepro-test1 inherits reprepro { $reprepro_dir = "/tmp/reprepro_archive1" } class reprepro-test2 { $reprepro_dir = "/tmp/reprepro_archive2" include reprepro } node default { include reprepro-test1 include reprepro-test2 include reprepro } With the following file (reprepro/manifests/init.pp) on the module search path: class reprepro { $reprepro_dir = "/tmp/reprepro_archive_module" file { $reprepro_dir: ensure => directory, } } Then /tmp/reprepro_archive_module gets created with no warnings or errors (due to the node including reprepro), but /tmp/reprepro-test2 does not get created. My variable does not get overloaded. If I change the module to: $reprepro_dir = "/tmp/reprepro_archive_module" class reprepro { file { $reprepro_dir: ensure => directory, } } And I stop using class reprepro-test1 in the node (*): node default { #include reprepro-test1 include reprepro-test2 inclure reprepro } Then I only get "/tmp/reprepro_archive2" created, and no warnings. So I think the following statements are true: * variables in a module have scope of only that module. * The scope of variables inside classes bind tighter than those of module variables. * Class inheritance is limited (as the documentation says), you can''t override parent variables. * class includeness binds tighter than module variables, regardless of where in the module you declare the variable. I can''t think of how I can achieve what I want, where both "include reprepro-test2" and "include reprepro" do what I expect them to do. I also tried in a separate file: $reprepro_dir = "/tmp/reprepro_archive3" class reprepro-test3 inherits reprepro { } class reprepro-test4 { include reprepro } But it looks like class reprepro-test3 behaves exactly like reprepro-test1, and reprepro-test4 behaves exactly like class reprepro. The $reprepro_dir in that file gets global scope, and gets overridden by the definition of $reprepro_dir in the module, regardless of where in the module you declare it. So I think that the documentation here: http://reductivelabs.com/trac/puppet/wiki/LanguageTutorial#importing-manifests says: Puppet has an import keyword for importing other manifests. Code in those external manifests should always be stored in a class or definition or it will be imported into the main scope and applied to all nodes. Should be extended to describe how the scope of variables in modules works. But I''ve already spent an hour writing this email, so I''m not going to suggest a patch just now. (*) If you keep reprepro-test1 included, then when reprepro-test1 is evaluated the $reprepro_dir is not defined at all, and you see the following errors: err: Could not create : Parameter path failed: File paths must be fully qualified warning: Not using cache on failed catalog warning: Configuration could not be instantiated: Parameter path failed: File paths must be fully qualified --~--~---------~--~----~------------~-------~--~----~ 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 -~----------~----~----~----~------~----~------~--~---