0

Previously on ServerFault, it was shown how to test if a Resource was defined: Puppet: Test if Resource is defined, or create it

if defined(File["/tmp/foo"]) {
  alert("/tmp/foo is defined")
} else {
  alert("/tmp/foo is not defined")
}

I'd like to test if a virtual resource is defined or exists, before realizing it via collector, but it doesn't seem to work with the same syntax.

create_resource('@package',hiera_hash('packages',{}),{})
if !defined(@Package['foo']) {
  alert('Hiera screwed up, critical virtual package is missing')
}
# Realize the critical packages
Package<| groups == critical |>

This gets me: Error: Could not parse for environment production: Virtual (@) can only be applied to a Resource Expression at test.pp..

The reason is that I want to do the realize via create_resources and collectors, and as testing, throw an error if it's not actually creating some critical virtual resource.

Edit 2014/11/12 19:07 UTC One of the answers suggested this instead, but it doesn't work, pasting it here because the answer comment box is too small.

class base::test1 {
  @package { 'cookietool':
    ensure => 'present',
  }
  realize(Package['cookietool'])
}

base::test2 has the identical content.

node testbox {
  include base::test1
  include base::test2 
}

This fails with the following error:

Error: Failed to compile catalog for node testbox: Evaluation Error: Error while evaluating a Resource Statement, Duplicate declaration: Package[cookietool] is already declared in file /var/lib/puppet/checkouts/environments/production/modules/base/manifests/test1.pp:2; cannot redeclare at /var/lib/puppet/checkouts/environments/production/modules/base/manifests/test2.pp:2 at /var/lib/puppet/checkouts/environments/production/modules/base/manifests/test2.pp:2:3 on node testbox

robbat2
  • 350
  • 5
  • 10
  • Your version here is not equivalent to Craig Watson's answer, which is correct. You are defining the virtual resource twice. – mc0e Dec 09 '16 at 00:50
  • @mc0e see my followup in his comments, clarifying that what I was after was how to introspect virtual resources WITHOUT realizing them. – robbat2 Dec 09 '16 at 22:39

2 Answers2

1

By definition, a virtual resource is not "defined" until it has been realized.

As with standard resources, you may only declare virtual resources once, but they can be realized many times - this is one of the major reasons why they're used.

Example

modules/packages/init.pp

class packages {
  @package { 'git':
    ensure => present,
  }
}

modules/git/init.pp

class git {
  realize Package['git']
}

modules/mymodule/init.pp

class mymodule {
  realize Package['git']
}

manifests/site.pp

node 'mynode' {
  include packages
  include git
  include mymodule
}

This will compile and ensure that the git package is installed.

Craig Watson
  • 9,575
  • 3
  • 32
  • 47
  • I moved my comment to the original post, because the box was too small, but your answer doesn't work (I changed to `cookietool` instead of `git`, because I wanted an inconsequential test package) – robbat2 Nov 12 '14 at 19:22
  • 2
    The **realize** calls can appear an arbitrary number of times. The **declaration** of the virtual resource must be unique (same as with non-virtual resources). – Felix Frank Nov 17 '14 at 17:01
  • @FelixFrank - thanks for the clarification, I've updated my answer. – Craig Watson Nov 17 '14 at 17:04
  • @robbat2 - does this help? – Craig Watson Nov 17 '14 at 17:04
  • It doesn't solve my original problem; it just corrects your use of virtual packages. I supposed really what I'm asking, is how to introspect virtual resources without realizing them. – robbat2 Nov 21 '14 at 17:16
0

Just declare a resource that depends on the resource you are realizing.

notify { 'important resources are declared':
    loglevel => debug,
    require => [
        Package['foo'],
        ...
    ],
}

The catalog will fail if Package[foo] is not being realized.

Using the defined function is outrageously bad practive anyway

Don't use it in this or almost any other scenario. It is evaluation order dependent on the compiler side, and its result cannot be relied on.

Felix Frank
  • 3,093
  • 1
  • 16
  • 22