how to use variables elsewhere that's defined in a define() type?

85 views
Skip to first unread message

Sans

unread,
Jun 5, 2014, 7:06:55 AM6/5/14
to puppet...@googlegroups.com

I have a class something like this, where I'm passing a [hiera] hash (zpack_hash) to it:

class installer::zenpack($zpack_hash) {

    define zpack_installer($sure='present', $inst='false') {

        $z_pack  = $installer::zenpack::zpack_hash[$name]
        $zp_ver  = inline_template("<%= @z_pack['ver'].to_s.chomp %>")
        $zp_repo = inline_template("<%= @z_pack['rep'].to_s.chomp %>")
        $zp_rqed = inline_template("<%= @z_pack['req'].to_s.chomp %>")

        package { $name:
            ensure     => $sure ? { present => $zp_ver, default => $sure },
            notify     => Exec[ 'refresh_zenpack_daemons', 'create_default_conf' ],
            require    => [
                            File[ '/opt/zenpack/etc/global.conf' ],
                            Yumrepo[ $zp_repo ],
                          ];
        }
    }
    $my_zpack_list = keys($zpack_hash)
    zpack_installer { $my_zpack_list: }
}
 
Later in my module, how can I use any of the variables (e.g. $zp_repo) that are already defined in the zpack_installer? I tried something like this:

class packages::zenpacks::core {
        $hr_zenoss_zpack_core = hiera_hash('zenoss_four::zpack_core', undef)

    class { 'installer::zenpack':
        zpack_hash => $hr_zenoss_zpack_core,
        require    => [
                        Yumrepo[ $installer::zenpack::zpack_installer::zp_repo ],
                        File[ '/opt/zenoss/etc/global.conf' ],
                        Installer::Zenpack::Zpack_installer[ $installer::zenpack::zpack_installer::zp_rqed ],
                      ];
    }
}

but that's not working; throwing in errors like:


err: Failed to apply catalog: Could not find dependency Yumrepo[undef] for Class[Installer::Zenpack]


on the lines that marked in red. It works just fine if I comment out these two lines. any help/suggestion from any one?

Felix Frank

unread,
Jun 5, 2014, 7:47:32 AM6/5/14
to puppet...@googlegroups.com
On 06/05/2014 01:06 PM, Sans wrote:
> Later in my module, how can I use any of the variables (e.g. $zp_repo)
> that are already defined in the zpack_installer?

I strongly disbelieve that this can work.

You can access variables defined in classes, but I would be mildly
disturbed if there was a similar feature for accessing interna of
defined type instances.

If you have Hiera, you likely want to have your data in structured hiera
values, so that you can look them up from all parts of your manifest.

As an aside - inline_templates in defined types can be performance
sinks, evaluating them is rather costly for the compiler.

HTH,
Felix
Message has been deleted

Sans

unread,
Jun 5, 2014, 9:07:32 AM6/5/14
to puppet...@googlegroups.com
Thanks Felix, for the heads up!
I was also thinking along the line that variables define() type variables are not accessible from elsewhere.

w.r.t. inline_templates, what else would you suggest? The hiera hash that I'm using here is something like this:

zpack_four::zpack_core:
    zenpack-apachemonitor:
        ver: latest
        repo: "zenpack-four-%{environment}"
        req: zenpack-apachemonitor
    zenpack-digmonitor:
        ver: latest
        repo: "zenpack-four-%{environment}"
        rqed: zenpack-apachemonitor


-San

Felix Frank

unread,
Jun 5, 2014, 9:17:39 AM6/5/14
to puppet...@googlegroups.com
On 06/05/2014 03:07 PM, Sans wrote:
>
> w.r.t. inline_templates, what else would you suggest? The hiera hash
> that I'm using here is something like this:

That looks nice. Why don't you structure your define zpack_installer()
so that you can use

create_resources('zpack_installer', $hash)

As for variable value reuse - you should rethink your requirements. The
class cannot require resources it declares itself.

As for the yumrepos, that makes more sense (I guess?) but for that you
want to
1. create a custom function that consumes your hash and returns the
repo names
2. write that to a variable (which stores an array value then) so that
you can
3. require Yumrepo[$my_repo_list]

HTH,
Felix

Sans

unread,
Jun 6, 2014, 8:07:40 AM6/6/14
to puppet...@googlegroups.com
Okay, here comes the follow-up question.
I've changed the zpack_installer, which doesn't do any inline_template() things any more,  instead it looks something like this now:

define installer::zpack_installer($sure='present',
                                  $inst='false',
                                  $zp_ver, $zp_rep) {
    ....
    ....
}

and then:

class packages::zenpacks::core {

    $zpack_list = keys($hr_zpack_core)
    ##
$hr_zpack_core is the hash, comes from nodes.pp

   
installer::zpack_installer { $zpack_list:
        zp_ver   => inline_template("<%= @hr_zpack_core[@name]['ver'].to_s.chomp %>"),
        zp_rep   =>
inline_template("<%= @hr_zpack_core[@name]['rep'].to_s.chomp %>"),
        require  => Installer::Z
pack_installer[ inline_template("<%= @hr_zpack_core[@name]['req'].to_s.chomp %>") ],
    }
}


But it's failing with: err: Failed to parse inline template: undefined method `[]' for nil:NilClass
 
I think, the problem is coming from the @name bit. Is it right way of doing it?
if I do the same thing in a ruby console, replacing @name with a 'key', I get exactly what I expect. Any pointer??

-San

Felix Frank

unread,
Jun 6, 2014, 8:27:17 AM6/6/14
to puppet...@googlegroups.com
On 06/06/2014 02:07 PM, Sans wrote:
>
> I think, the problem is coming from the @namebit. Is it right way of
> doing it?

@name is indeed the issue - it is bound to a foreign value in this scope.

> if I do the same thing in a ruby console, replacing @name with a 'key',
> I get exactly what I expect. Any pointer??

Again - my proposal is to strive for a create_resources() based solution
without *any* need to resort to templating.

From the data you supplied, there is just no reason for neither invoking
to_s nor chomp on your hash values.

Sans

unread,
Jun 6, 2014, 10:21:34 AM6/6/14
to puppet...@googlegroups.com
I never used the create_resources() and trying to get my head around it. 
So, how do I [re]write my define() type to work with 
create_resources() to do the same thing similar to this:

class packages::zenpacks::core($pkgs_hash) {


    define installer::zpack_installer($sure='present',
                                      $inst='false',
                                      $zp_ver, $zp_rep)) {
        package { $name:
            ensure   => $zp_ver,
            require  => [
                          Yumrepo[ $zp_rep ],
                          Package[ 'zenpack-tools', 'patchutils' ],
                        ];
        }
                  .......
                  .......
    }

    create_resources(installer::zpack_installer, $pkgs_hash)
}


For my purpose,  I think I still need to use inline_template() for the rqed key. When I install the individual zenpacks, I actually need to do this to complete the installation:


installer::zpack_installer {
    'zenpack-digmonitor':
    require  => Installer::Zpack_installer[ 'zenpack-apachemonitor' ];
}

How do I handle that?

-San

Reply all
Reply to author
Forward
0 new messages