Setting var to undef does not override class or define defaults

22 views
Skip to first unread message

Erik Anderson

unread,
Apr 26, 2016, 10:38:24 AM4/26/16
to Puppet Users
On Puppet 4.4.1

I ran the following: 

class testingclass(
  $cmd_path
= 'PluginDir',
){
  $message_ntfy
= "cmd_path is set to: ${cmd_path} for ${name}"
  notify
{ $message_ntfy: }
}


define testingdefine
(
  $cmd_path
= 'PluginDir',
){
  $message_ntfy
= "cmd_path is set to: ${cmd_path} for ${name}"
  notify
{ $message_ntfy: }
}


node
default {


 
class {'testingclass':
    cmd_path
=> undef,
 
}


 testingdefine
{ 'testingdefinedefaults': }
 testingdefine
{ 'testingdefineundef':
  cmd_path
=> undef,
 
}
}

I expect cmd_path to be set to undef for the class and testingdefineundef. Instead it looks like all three end up with the same value for cmd_path: 

erik.anderson@puppetmaster1:~$ sudo puppet apply test.pp
Warning: Config file /etc/puppetlabs/code/hiera.yaml not found, using Hiera defaults
Notice: Compiled catalog for sa-sand-puppetmaster1.sa.moneydesktop.com in environment production in 0.15 seconds
Notice: cmd_path is set to: PluginDir for testingclass
Notice: /Stage[main]/Testingclass/Notify[cmd_path is set to: PluginDir for testingclass]/message: defined 'message' as 'cmd_path is set to: PluginDir for testingclass'
Notice: cmd_path is set to: PluginDir for testingdefinedefaults
Notice: /Stage[main]/Main/Node[default]/Testingdefine[testingdefinedefaults]/Notify[cmd_path is set to: PluginDir for testingdefinedefaults]/message: defined 'message' as 'cmd_path is set to: PluginDir for testingdefinedefaults'
Notice: cmd_path is set to: PluginDir for testingdefineundef
Notice: /Stage[main]/Main/Node[default]/Testingdefine[testingdefineundef]/Notify[cmd_path is set to: PluginDir for testingdefineundef]/message: defined 'message' as 'cmd_path is set to: PluginDir for testingdefineundef'
Notice: Applied catalog in 0.35 seconds

Any ideas on why it is behaving this way and is it intentional?

Rob Nelson

unread,
Apr 26, 2016, 11:16:01 AM4/26/16
to puppet...@googlegroups.com
Passing undef to a parameter doesn't unset it. It's the same as not passing it. I do not believe there is a standard way to unset a parameter with a default value. You can set it to '', 0, false, or another appropriate "unset" value depending on how it is to be used, though.

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/26d1f9c0-61b6-47d3-a7fc-350fee0f2035%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Johan De Wit

unread,
Apr 27, 2016, 6:03:54 AM4/27/16
to puppet...@googlegroups.com



-----Original message-----
From: Rob Nelson <rnel...@gmail.com>
Sent: Tuesday 26th April 2016 17:15
To: puppet...@googlegroups.com
Subject: Re: [Puppet Users] Setting var to undef does not override class or define defaults

Passing undef to a parameter doesn't unset it. It's the same as not passing it. I do not believe there is a standard way to unset a parameter with a default value. You can set it to '', 0, false, or another appropriate "unset" value depending on how it is to be used, though.

When you want a way to be able to unset it,

you could use a second parameter, manage_<paramx> = boolean. 


(as rob told me :) )




jcbollinger

unread,
Apr 27, 2016, 9:22:45 AM4/27/16
to Puppet Users


As Rob explained, yes, it is intentional.  The symbol undef does not represent a value; rather, it represents the absence of any value.  You can use it in some places where a value is expected, to affirmatively express that you are not providing a value.  That is a bit different from not saying anything about a value at all, but for most purposes the two alternatives have the same effect.  Using undef has some utility for various kinds of overrides and defaults, but it does not and cannot work the way you expected.

One way to look at it is that the effect of undef is necessarily localized to the point where it appears.  This must be so because undef is not a value, and therefore cannot be propagated.  Thus, in your example, the undefs have all the effect they ever will have in the class and resource declarations where they appear, and the fact that they appear in those declarations is invisible in the definitions of the corresponding class and type, where parameter defaults are defined.

Moving on a bit, you have to decide for every a class or resource parameter whether you want to insist that users of the class / resource provide a value for that parameter.  If so, then you avoid specifying a default value for that parameter in the class / resource definition.  If not, then you do specify a default.  If you want a way to express that the class / resource should ignore the parameter, then the conventional way is to define a value that has local significance as a nonsense value.  That might be an empty string, for example, or maybe the string 'UNDEF'.  Ideally, this would be something that could never be a valid value of the parameter.  You then have the choice of making that the parameter default, or documenting its use for clients of your class / resource type.


John

Reply all
Reply to author
Forward
0 new messages