Ask Your Question
1

How to ensure that the «if» statement gets parsed _before_ a given resource/class?

asked 2014-04-23 11:56:14 -0500

Adam Ryczkowski gravatar image

updated 2014-04-23 12:01:57 -0500

Sometimes there are complicated interactions between packages. To avoid class interface with countless, seemingly unrelated parameters, I though about using tags, defined(<resource>) function to let the resources slightly change their behaviour based on the rest of the configuration (not facts).

Unfortunately I can't figure out a way to let the Puppet first parse the class that can generate conditions, and only then parse the class which behaviour implicitly (via e.g. tags) depends on the way the first class got executed.

Suppose here is a class, that manages a place, where a specific user stores his sensitive personal data. The class can e.g. create the partition (possibly encrypted), or just maintain an external folder (on e.g. /mnt/user). Or it can keep the folders where they are by default, i.e. in the /home/user (spurcetype=>'none')

class userdocs ( $sourcetype) {
  case $sourcetype {
    'cryptpartition' : {
      tag 'dedicated_user_docs_partition'
      ...
    }
    'partition' : {
      tag 'dedicated_user_docs_partition'
      ...
    }
    'none' : {
      ...
    }
  }
  ...
}

Apart from fairly standard set of folders, that a user might want to forward to his partition, there are folders which existence depends on the particular software running, like thunderbird or virtualbox. Creation of the link (instead of folder) for e.g. virtualbox should be done only, if two conditions are satisfied: a) user manages separate partition (tagged('dedicated_user_docs_partition')) and user installs VirtualBox.

There must be a place, where I can put that extra code, that checks for those two conditions. I can put it into the class, that manages the virtualbox:

class vbox {
  if tagged('dedicated_user_docs_partition') {
    file { "${userhome}/.VirtualBox": ensure=>link, require=>Class['userdocs'] ...
    }
  } else {
    file { "${userhome}/.VirtualBox": ensure=>directory, require=>Class['userdocs'] ...
    }
  }
  ...
}

The problem is, that although I explicitly require the file resource to be executed before the userdocs class, the file resource is evaluated after that, and puppet wrongly assumes, that user doesn't have the dedicated_user_docs_partition and executes wrong branch of the if statement.

Is there any way to solve this problem?


Adding class {'vbox': require => Class['userdoc'], } in the node declaration does not help. This syntax changes resource-dependency, not the order in which the parser works.

One person have suggested to use custom facts instead of a variable, but I think this is rather last resort idea. Facts are instantiated only once, at the beginning. I would need to run a manifest twice (which is not elegant), and handle three states in place of two: "dedicateddocs", "nodedicateddocs", "firstrun". Besides in real situation (not this mock-up example), both vbox and userdocs are in fact a define, not class, and they have user name as a namevar. I understand, that I would need to have as many facts as there are users, which would greatly proliferate the namespace

Another idea is to use stages. But then I would need awfully lot of stages, if I'd start to handle resource interactions that way.


This is cross-post from Server Fault

edit retag flag offensive close merge delete

2 Answers

Sort by » oldest newest most voted
1

answered 2014-04-23 15:31:52 -0500

lavaman gravatar image

Assuming you are managing the software with puppet as well (which appears to be the case from your sample code), I would use virtual resources in the software modules that get collected by the module handling the mounts.

http://docs.puppetlabs.com/puppet/lat...

edit flag offensive delete link more

Comments

I guess this is the way to go. I've never used the Virtual Resources before.

Adam Ryczkowski gravatar imageAdam Ryczkowski ( 2014-04-24 06:57:48 -0500 )edit

I've copied your answer on http://serverfault.com/questions/590762/how-to-ensure-that-the-if-statement-gets-parsed-before-a-given-resource-clas/591053#591053 . If you want you can post this answer from yourself and I'll accept it.

Adam Ryczkowski gravatar imageAdam Ryczkowski ( 2014-04-24 07:02:43 -0500 )edit
1

answered 2014-04-23 14:06:03 -0500

ffrank gravatar image

Do not try to build anything that is evaluation order dependent. There is only pain down this road, because in a complex manifest, it is nigh impossible to predict the order in which the parser will be walking your definitions.

Point in fact, we are working on deprecating and removing the defined function altogether to keep users from shooting their feet.

I shall elaborate over on Server Fault when I get a chance.

edit flag offensive delete link more

Comments

Thank you. I'm open to suggestions.

Adam Ryczkowski gravatar imageAdam Ryczkowski ( 2014-04-23 15:19:30 -0500 )edit

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account.

Add Answer

Question Tools

1 follower

Stats

Asked: 2014-04-23 11:56:14 -0500

Seen: 139 times

Last updated: Apr 23 '14