Take the 2-minute tour ×
Server Fault is a question and answer site for system and network administrators. It's 100% free, no registration required.

Is it possible to declare variable in node and than propage it way down to the erb template?

Example:

node basenode {
  $myvar = "bar" # default
  include myclass
}

node mynode extends basenode {
  $myvar = "foo"
}

class myclass {
  file { "/root/myfile":
    content => template("myclass/mytemplate.erb")
    ensure  => present,
  }
}

Source of mytemplate.erb:

myvar has value: <%= myvar %>

I know that my example might be complicated. But I'm trying to propagate file on (almost) all my nodes and I want its content to be altered depending on the node which requests the file. The $myvar = "bar" statement should be default when node does not override its value.

Is there a solution to my problem? I'm using puppet 0.24.5

Edit: The problem here is probably variable inheritance order. This $myvar variable won't have foo value in mynode node. The solution here would be to include myclass directly in mynode. But I really don't want to do that. Is there an option to override class variable value after the class has been included?

share|improve this question
    
Darn: mailinglistarchive.com/html/puppet-users@googlegroups.com/… Seems like this approach will never work ... –  Michal Bryxí Jan 11 '11 at 6:37
    
More precisely: docs.puppetlabs.com/guides/… –  Michal Bryxí Jan 11 '11 at 6:53
    
That's kind of what I assumed was happening. Too bad, the idea of node inheritance is neat. –  Scott Pack Jan 11 '11 at 18:29

3 Answers 3

up vote 3 down vote accepted

Puppet node inheritance is not the same as inheritance in most other programming languages . Included classes are evaluated immediatelly when the child is evaluated. And the parent node is evaluated after that. Therefore my example will never work. If you want to know recommended solution for this, read puppet - common misconceptions. I did it this way and it works.

Although I have to admit that I'm pretty disappointed right now, because complex puppet syntax might be confusing for starters.

share|improve this answer
    
I'm being pedantic, but declarative languages like Puppet's DSL are programming languages every bit as much as procedural programming languages (which is what you probably meant) like C. –  jgoldschrafe Jan 20 '11 at 3:42
    
Changed my statement so it does not sound like I don't accept puppet language as programming langugage :) –  Michal Bryxí Jan 22 '11 at 12:14

Other answers have already pointed out the scoping problem. What you probably want to do is use the base node only for variable definitions, and separate out the actual logic (including your base class definitions) into a separate class that's included by all of your nodes. This preserves the scoping the way that you want, and only adds a single extra line to all of your node definitions.

node basenode {
  $myvar = "bar" # default
}

node mynode extends basenode {
  $myvar = "foo"
  include baseclass
}

class baseclass {
  include myclass
}

class myclass {
  file { "/root/myfile":
    content => template("myclass/mytemplate.erb"),
    ensure  => present
  }
}
share|improve this answer

Instead of declaring the default value within basenode, I would declare the default within the template itself. Since ERB is largely based on ruby, you can get away with some fairly extensive logic. Here is an example from the template I use for managing the snort config file.

var DNS_SERVERS <% if has_variable?("dns_servers") then %>[<%= dns_servers.flatten.join(',') %>]<% else %>$HOME_NET<% end %>

In this case I am using an array that, if it exists, gets turned into a comma separated list for inclusion. Otherwise the default $HOME_NET gets used. If we simplify it to your example we could use:

myvar has value <% if has_variable?("myvar") %><% then %><%= myvar %><% else %>bar<% end %>

Again, if the variable myvar has been set then that will be expanded, otherwise the string "bar" will be printed. This way the variable myvar can be set, or not, in your node definitions with impunity.

share|improve this answer
    
This is probably a good point. But my main point here is that I'm not able to use variables from node definition within erb templates (which are used inside classes). Is there something bad in my example? My real situation is much more complicated than this, but I think that main point is here. Are there any limits of the scope in which the variable will be propagated? –  Michal Bryxí Jan 10 '11 at 20:42
    
Ah, sorry, I didn't realize you meant that you tried it, but didn't work. I am doing exactly what you are, and it works fine. It could be that your ERB syntax is wonky, or you've run into an ordering problem. I'll have to do some more testing. –  Scott Pack Jan 10 '11 at 21:04

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.