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

I have a default node like so:

node default {
    include test_server
    # A bunch of other irrlevant includes
}

Then I have a node specification like so:

node linus inherit default {
    include production_server
}

I want to un-include test_server and have production_server since they are mutually exclusive.

How do I accomplish this?

share|improve this question
1  
FYI: Many things in the documentation suggest that inheritance is bad and you shouldn't use it any more. See: docs.puppetlabs.com/guides/… Inheritance should be avoided. In general, inheritance leads to code that is harder to read. Most use cases for inheritance can be replaced by exposing class parameters that can be used to configure resource attributes. –  Zoredache Dec 13 '11 at 18:00
1  
You may find the answer in my MTA question. –  Zoredache Dec 13 '11 at 18:14

3 Answers 3

up vote 4 down vote accepted

You are better off making a class called 'servertype' and distinguish based on a parameter.

class servertype($testing = false) {
  if ($testing) {
     ... resources from your testing class ...
  } else {
     ... resources from your production class ...
  }
}
share|improve this answer

Generally speaking, using an ENC (External Nodes Classifier) is the best option for applying classes to hosts, as opposed to node files. You can create "Hostgroups", where each group has multiple classes. This way you can avoid inheritance. There are several ENCs available so you don't have to create your own.

share|improve this answer

There's no notion of "uninclude" in Puppet; once you've included something, it's included. The best you can do is to make a single class you include that internally does dispatch to include either test_server or production_server, depending on circumstance (look at a fact, look at a passed in variable, etc).

Barring that, you can cause an error if both classes are included. An easy way to do this would be to simply include a sentinel resource in each class, where the resource has the same name in both spots:

notice { unused:
  loglevel => debug,
}

Attempting to include both classes will cause the compiler to fail, preventing the catalog from ever getting compiled.

Another option would be to use the defined function in each class to test if the other has been defined already. If so, fail:

if defined(Class["test_server"]) {
  fail "Can't include test_server and production_server at the same time"
}

defined has some peculiar semantics, though, as it's dependent on order, and Puppet doesn't really provide that many guarantees in terms of parse/evaluation ordering.

share|improve this answer

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.