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

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?


I've cross-posted this question on ask.puppet.com.


It is a an answer using virtual resources, that lavaman suggested.

I don't like the fact, that it forces me to put code with "VirtualBox" to the class, that I think should be logically independent to it. But I think it can be worked-around using delegated classes (like userdocs::virtualbox, defined completely elsewhere).

class userdocs ( $sourcetype) {
  case $sourcetype {
    'cryptpartition' : {
      @file { "${userhome}/.VirtualBox": ensure=>link, ...
      }
      ...
    }
    'partition' : {
      @file { "${userhome}/.VirtualBox": ensure=>link, ...
      }
      ...
    }
    'none' : {
      @file { "${userhome}/.VirtualBox": ensure=>directory, ...
      }
      ...
    }
  }
  ...
}

and

class vbox {
  realize File["${userhome}/.VirtualBox"]
  ...

}