Hitting the wall while trying my hand at subclasses and parameters

27 views
Skip to first unread message

Jean-Francois Gratton

unread,
Dec 14, 2015, 10:42:53 AM12/14/15
to Puppet Users, jean-franc...@banquelaurentienne.ca
Good morning everyone,

I'm trying my hand with subclasses and using parametrized (sub-)classes.

Here's the module layout, and what I'm trying to acheive:

/etc/modules/users/manifests/sysadmins.pp
class users::sysadmins
{
        realize (Group['sysadmins'])
        include users::sysadmins::jfg1
        include users::sysadmins::jfg2
}
and then I'd have, in /etc/modules/users/manifests/sysadmins/jfg1.pp :
class users::sysadmins::jfg1
{
        @user   { 'jfg1' :
                        comment => 'JFG1 test accnt',
                        ensure => present,
                        gid => 'sysadmins',
[snip]
                     }
           realize (User['jfg1'])
}

Now, I'd want some common files to be put into $HOME, regardless of the user being created. I've thought of adding this:

/etc/puppet/modules/users/sysadmins/commonfiles.pp :
class users::sysadmins::commonfiles($homedirectory, $username)
{
        file    { "${homedirectory}/.profile" :
                        ensure => present,
                        owner => "${username}",
                        group => 'sysadmins',
                        source => "puppet:///modules/users/profiles/${username}-profile",
                }
[snip]
}
($homedirectory has to be explicitely passed to this module because $HOME could be /export/home, /home/ or other combinations -> /Users/$user on OSX, for instance)

Now, back to /etc/modules/users/manifests/sysadmins/jfg1.pp, right after the realize User[] line, I'd call the commonfiles subclass with:
  include users::sysadmins::commonfiles("/export/home/jfg1", "jfg1")

Except that I get this error:

Error: Unknown function users::sysadmins::commonfiles at /etc/puppet/modules/users/manifests/sysadmins/jfg1.pp:61 on node XXX


I'm not sure of what am I missing here.

Any pointers ?

Regards,

--Jeff

jcbollinger

unread,
Dec 15, 2015, 10:56:23 AM12/15/15
to Puppet Users


On Monday, December 14, 2015 at 9:42:53 AM UTC-6, Jean-Francois Gratton wrote:
Good morning everyone,

I'm trying my hand with subclasses and using parametrized (sub-)classes.


That's probably a mistake.  Class inheritance serves a comparatively special purpose in Puppet DSL, one whose importance is much less in modern Puppet than it was in the Puppet of five-ish years ago.  On the other hand, I don't think what you're doing actually has anything to do with subclasses / inheritance.

 

Here's the module layout, and what I'm trying to acheive:

/etc/modules/users/manifests/sysadmins.pp
class users::sysadmins
{
        realize (Group['sysadmins'])
        include users::sysadmins::jfg1
        include users::sysadmins::jfg2
}
and then I'd have, in /etc/modules/users/manifests/sysadmins/jfg1.pp :
class users::sysadmins::jfg1
{
        @user   { 'jfg1' :
                        comment => 'JFG1 test accnt',
                        ensure => present,
                        gid => 'sysadmins',
[snip]
                     }
           realize (User['jfg1'])
}



That's not a subclass, it's just a class whose fully-qualified name has two namespace segments.  Having the same first namespace segment puts that class and the previous one in the same module, but as far as Puppet is concerned, the coincidence between subsequent name segments does not imply any additional relationship between the two.

 
Now, I'd want some common files to be put into $HOME, regardless of the user being created. I've thought of adding this:

/etc/puppet/modules/users/sysadmins/commonfiles.pp :
class users::sysadmins::commonfiles($homedirectory, $username)
{
        file    { "${homedirectory}/.profile" :
                        ensure => present,
                        owner => "${username}",
                        group => 'sysadmins',
                        source => "puppet:///modules/users/profiles/${username}-profile",
                }
[snip]
}
($homedirectory has to be explicitely passed to this module because $HOME could be /export/home, /home/ or other combinations -> /Users/$user on OSX, for instance)

Now, back to /etc/modules/users/manifests/sysadmins/jfg1.pp, right after the realize User[] line, I'd call the commonfiles subclass with:
  include users::sysadmins::commonfiles("/export/home/jfg1", "jfg1")


If you want to bind values to your class parameters at the point where you declare the class, then you must use a resource-like class declaration:

class { 'users::sysadmins::commonfiles':
  homedirectory
=> '/export/home/jfg1',
  username      
=> 'jfg1'
}

But
  1. You should avoid resource-like class declarations under most circumstances.  Favor automated data binding (via Hiera) instead.  And more importantly,
  2. What you are trying to do appears unlikely to serve your purposes.
Expanding on the second point, if you want to be able to declare common files for more than one user, then you cannot use a class as you are trying to do, because classes are singletons.  You could not use that class to provide common files for more than one user.

You seem to be looking for a defined type instead. That might look something like this:

define users::sysadmins::commonfiles($homedirectory) {

  file
{ "${homedirectory}/.profile":
   
ensure => present,

    owner  
=> "${title}",
   
group  => 'sysadmins',
    source
=> "puppet:///modules/users/profiles/${title}-profile",
 
}

 
# ...
}

You would use it just like any other resource type, for instance

users::sysadmins::commonfiles { 'jfg1':
  homedirectory
=> '/export/home/jfg1'
}

Such a resource has all the properties and behavior common to resources -- you can chain it, collect it, declare resource defaults for it, etc..


John

Jean-Francois Gratton

unread,
Dec 17, 2015, 10:08:08 AM12/17/15
to Puppet Users, jean-franc...@banquelaurentienne.ca
That's the clearest explanation I've came across, thanks a lot !

I'll go with the define; I thought I had found a quick way to reuse some code; I was halfway there, looks like. :-)

Thanks again,

--Jeff
Reply all
Reply to author
Forward
0 new messages