accessing variable from another manifest

405 views
Skip to first unread message

Tim Dunphy

unread,
Jan 21, 2014, 11:22:41 PM1/21/14
to puppet...@googlegroups.com
Hello all,

 I'm attempting to follow along in the puppet book with the ssh module lesson. I'm at the part where I'm attempting to use a variable that's been set in another class called ssh::params. When I run the puppet on the client I get the following error: 

[root@beta:~] #puppet agent --test --server puppet.mydomain.com
info: Caching catalog for beta.mydomain.com
err: Failed to apply catalog: Parameter path failed on File[undef]: File paths must be fully qualified, not 'undef' at /etc/puppet/modules/ssh/manifests/config.pp:10

This is what my ssh modules directory looks like:

modules/ssh
├── files
│   └── sshd_config
├── manifests
│   ├── config.pp
│   ├── init.pp
│   ├── install.pp
│   ├── params.pp
│   └── service.pp
└── templates


Here is the definition I have setup in my config.pp manifest that is generating the error: 

class ssh::config {
     file { $ssh::params::ssh_service_config:
      ensure => present,
      owner => 'root',
      group => 'root',
      mode => 0600,
      source => "puppet:///modules/ssh/sshd_config",
      require => Class["ssh::install"],
      notify => Class["ssh::service"],
      }
}


The  $ssh::params::ssh_service_config variable is what's throwing the undefined error when I run puppet on the client.

And this is my config.pp manifest in which that variable is defined:

class ssh::params {
    case $operatingsystem {
     Solaris: {
       $ssh_package_name = 'openssh'
       $ssh_service_config = '/etc/ssh/sshd_config'
       $ssh_service_name = 'sshd'
     }
     /(Ubuntu|Debian)/: {
        $ssh_package_name = 'openssh-server'
        $ssh_service_config = '/etc/ssh/sshd_config'
        $ssh_service_name = 'sshd'
     }
     /(RedHat|CentOS|Fedora)/: {
        $ssh_package_name = 'openssh-server'
        $ssh_service_config = '/etc/ssh/sshd_config'
        $ssh_service_name = 'sshd'
     }
  }
}



I was hoping someone out there could help determine why this variable is undef?

Thanks,
Tim
--
GPG me!!

gpg --keyserver pool.sks-keyservers.net --recv-keys F186197B

Tim Dunphy

unread,
Jan 22, 2014, 12:49:15 AM1/22/14
to puppet...@googlegroups.com
Hey all,

 Sorry but I forgot to include a key piece of information in that last email.

 In the ssh class I have defined in the modules init.pp I had this definition:

 class ssh {
      include ssh::install, ssh::config, ssh::service, ssh::params
}


But then I read on into the book a little more and found out about the require function. So I changed the ssh class definition to this: 

class ssh {
      require ssh::params
      include ssh::install, ssh::config, ssh::service
}

And that solved the problem! Still curious as to why the original class definition failed to work with the include function specifying ssh::params. So if anyone out there cares to enlighten on that issue, that'd be great. 

Glad however that I was able to get this working.

Thanks!
Tim

jcbollinger

unread,
Jan 22, 2014, 9:21:32 AM1/22/14
to puppet...@googlegroups.com


On Tuesday, January 21, 2014 11:49:15 PM UTC-6, bluethundr wrote:
Hey all,

 Sorry but I forgot to include a key piece of information in that last email.

 In the ssh class I have defined in the modules init.pp I had this definition:

 class ssh {
      include ssh::install, ssh::config, ssh::service, ssh::params
}


But then I read on into the book a little more and found out about the require function. So I changed the ssh class definition to this: 

class ssh {
      require ssh::params
      include ssh::install, ssh::config, ssh::service
}

And that solved the problem! Still curious as to why the original class definition failed to work with the include function specifying ssh::params. So if anyone out there cares to enlighten on that issue, that'd be great. 

Glad however that I was able to get this working.


You have a misapprehension.  It was not changing from 'include' to 'require' that made the difference.  It was putting the 'require' statement before the 'include's in your manifest.  Provided you leave it positioned where it now is, you could change the 'require' back to an 'include' without breaking anything (and you should do).

The underlying problem is that class ssh::config depends on class ssh::params, but does not explicitly tell Puppet so.  Generally speaking, if class A uses class variables of class B, then class A should 'include' class B at the top of its body.  That expresses the compile-time dependency in a way that Puppet understands.  If it does not express the dependency to Puppet, then whether class B is evaluated first is unspecified.

The above comes with some qualifications and provisos, however, among them:
  1. If you use parameterized-style class declarations in your manifests then other declarations of the same classes serve documentary purposes only.  Compilation will fail if a parameterized-style declaration of class P (class { 'p': [parameters ...] }) is encountered when class P has already been declared, and no additional declaration is needed one has already been evaluated.
  2. If class A has both compile-time and order-of-application dependencies on class B, then both dependencies can be expressed together via a 'require' statement.  For code clarity, you should avoid 'require' except in such cases.
I have long maintained that (1) is an outstanding reason to avoid parameterized class declaration syntax.  In Puppet 3, you can rely instead on automated data binding via hiera, at least where you "must" use parameterized classes at all.  (There is never an absolute need to do so, but it may be convenient, especially when third-party modules are involved.)  With some care, parameterized-style declarations can safely be used within a module to declare internal classes of that same module, but that's about it.


John

Reply all
Reply to author
Forward
0 new messages