How to use define type or variables

140 views
Skip to first unread message

linux....@gmail.com

unread,
Dec 29, 2015, 3:30:08 PM12/29/15
to Puppet Users
Hi,

I am new to puppet and I am trying to write a module to manage user .bashrc files. I managed to place the file to the desired location with following code for 1 user because the username is hardcoded. However, I tried different ways to manage the file for 10 different users using variables which fails. Can someone please help me with the same.

init.pp:
class profile (
  $bashrc                          = $profile::params::bashrc,
  $bashrc_host                  = $profile::params::bashrc_host,
) inherits profile::params {

  anchor { 'profile::begin': } ->
  class { '::profile::config': } ->
  anchor { 'profile::end': }
}

config.pp:
class profile::config inherits profile {
file { $bashrc:
       ensure => file,
       source  => "puppet:///$bashrc_host",
    }

params:pp:
class profile::params {
  $bashrc_host        = "modules/profile/$fqdn_user1_bashrc"
}
  case $::osfamily {
    'RedHat': {
      $bashrc                  = '/home/user1/.bashrc'
    }
    default: {
      fail("The ${module_name} module is not supported on an ${::osfamily} based system.")
    }
  }

Thank You

Lowe Schmidt

unread,
Jan 4, 2016, 10:27:54 AM1/4/16
to puppet...@googlegroups.com
Can you please provide the error messages you get.

--
Lowe Schmidt | +46 723 867 157

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/puppet-users/eda4893c-a09d-44cd-80c3-c9c0f0d67599%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

jcbollinger

unread,
Jan 4, 2016, 2:53:49 PM1/4/16
to Puppet Users


On Tuesday, December 29, 2015 at 9:30:08 AM UTC-6, linux....@gmail.com wrote:
Hi,

I am new to puppet and I am trying to write a module to manage user .bashrc files. I managed to place the file to the desired location with following code for 1 user because the username is hardcoded. However, I tried different ways to manage the file for 10 different users using variables which fails. Can someone please help me with the same.


Your subject suggests that you hope to solve your problem by creating a defined type, and that is indeed a reasonable direction in which to proceed.  I am uncertain how to answer your question in any detail, however.  The Puppet manual has a section on defined types.  Have you read it?  Do you have specific questions?


John

linux script

unread,
Jan 4, 2016, 4:12:48 PM1/4/16
to puppet...@googlegroups.com

Hi,

The below code works fine for me. However, I want to reframe the code by using define statement in params.pp instead of config.pp.

I wanted to define it in params.pp so that I can use only variables in config.pp(ex:I am using $home/$name/.bashrc as file path in config which should be something like $bashrc if I would be able to use define in params.pp)


init.pp:

class profile (
  $home                          = $profile::params::home,


  $bashrc_host                  = $profile::params::bashrc_host,

) inherits profile::params {

 profile::config::params {user1:}

 profile::config::params {user2:}

  anchor { 'profile::begin': } ->
  class { '::profile::config': } ->
  anchor { 'profile::end': }
}

config.pp:

class profile::config inherits profile {

define user (username=$name)

file { "$home/$name/.bashrc":
       ensure => file,
       source  => "puppet:///modules/profile/$fqdn_$name_bashrc",
    }

params:pp:

class profile::params {

  $bashrc_host        = "modules/profile/$fqdn_$name_bashrc"

}
  case $::osfamily {

    'RedHat': {
      $bashrc                  = '/home/$name/.bashrc'


    }
    default: {
      fail("The ${module_name} module is not supported on an ${::osfamily} based system.")
    }
  }

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.

jcbollinger

unread,
Jan 5, 2016, 2:32:17 PM1/5/16
to Puppet Users


On Monday, January 4, 2016 at 10:12:48 AM UTC-6, linux script wrote:

Hi,

The below code works fine for me.



I don't see how that could be, as your code contains syntax errors, and it appears to reference a non-existent defined type named "profile::config::params".

 

However, I want to reframe the code by using define statement in params.pp instead of config.pp.



Defined type definitions should appear at top scope in their own manifests.  Although it is syntactically allowed, it is poor form to nest defined type definitions inside class definitions.  Thus, a defined type in module "profile" with simple name "user" should take this general form:

modules/profile/manifests/user.pp:

define profile::user($param1, $param2) {
 
# ...
}

 

I wanted to define it in params.pp so that I can use only variables in config.pp(ex:I am using $home/$name/.bashrc as file path in config which should be something like $bashrc if I would be able to use define in params.pp)



You are not making sense.  Lexical nesting has no relationship to the accessibility of class variables.

It's unclear to me whether any of that actually speaks to your issue, however.  If not, then you'll have to explain more clearly what you are trying to do, because I'm not catching it.  I mean, I understand in a general sense what your configuration objective is, but I'm not sure I understand what your actual question is.


John

linux script

unread,
Jan 5, 2016, 5:01:57 PM1/5/16
to puppet...@googlegroups.com

John,

Sorry for the typos in the code.for some reason I had to type the code instead of  copying.I thought it would give a general idea about the format in which I wanted to write it.

Secondly, I used define inside a class because I could not see a way to call the define inside another class which is out of it.

Let's say if I define something like modules/profile/manifests/user.pp:
define user (username=$name){
}

I want to call it into parms.pp where I assign all my variables related to this module something like below.$name should expand into actual user name which is passed through init.pp

class profile::params {
  $bashrc_host        = "modules/profile/$fqdn_$name_bashrc"

  $bashrc                  = '/home/$name/.bashrc'
}

I am using puppet 2.7.hence I cannot use iterations to make it happen.



--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to puppet-users...@googlegroups.com.

jcbollinger

unread,
Jan 6, 2016, 2:17:31 PM1/6/16
to Puppet Users


On Tuesday, January 5, 2016 at 11:01:57 AM UTC-6, linux script wrote:

John,

Sorry for the typos in the code.for some reason I had to type the code instead of  copying.I thought it would give a general idea about the format in which I wanted to write it.

Secondly, I used define inside a class because I could not see a way to call the define inside another class which is out of it.

Let's say if I define something like modules/profile/manifests/user.pp:
define user (username=$name){
}



That declaration is not what you want.  Compare it to my example: you are declaring a defined type named "user", but you put it in the file where Puppet will look for one named "profile::user".  Puppet uses class and defined type names to find and load their definitions, but it does not use filesystem paths to assign class or defined type names.  You always get exactly the name you declare.  With the declaration you presented, in the file you specified, Puppet will not be able to find defined type "user" (it would look in file modules/user/manifests/init.pp, instead), and it will not be able to find any defined type "profile::user" because you have not, in fact, defined such a type.

 

I want to call it into parms.pp where I assign all my variables related to this module something like below.$name should expand into actual user name which is passed through init.pp

class profile::params {
  $bashrc_host        = "modules/profile/$fqdn_$name_bashrc"
  $bashrc                  = '/home/$name/.bashrc'
}



It seems unlikely to be a good design to declare defined-type instances in a params class, but once you get the name and location sorted out you certainly could do so.  You should reference it by its full name, for example

profile::user { 'user1': }

If you mean that you want profile::user instances to be able to access variables from class profile::params, then it could hardly be simpler: you can reference those variables from anywhere in your manifest set by means of their qualified names.  For example, $profile::params::bashrc.

The only caveat (and it applies everywhere), is that the definition of the host class (profile::params) must have been evaluated before that access -- but not necessarily in the same scope as the variable reference.  Because classes are singletons, and especially for unparameterized classes such as yours, it is safe to declare the same class multiple times via include-like declarations.  For Puppet 2.7, that means via either the 'include' function or the 'require' function.

As such, it might be entirely reasonable and appropriate for the defined type body to 'include' class profile::params:

define profile::user($param1, $param2) {
  include '::profile::params'
  # now assuredly safe to access $profile::params::bashrc, etc.

 
# ...
}

 

I am using puppet 2.7.hence I cannot use iterations to make it happen.



Puppet 4's iteration features are convenient, but not essential.  In any event, I don't see how it makes a difference for this purpose whether they are available or not.  That is, I know you must be using an array title to declare multiple defined type instances, but
  1. myself, I'd strongly consider doing this particular job that way anyway;
  2. as I already said, data access does not depend on lexical scope; and
  3. the central problem seems to revolve around how to create a defined type, which is substantially the same in Puppet 4 as it was in Puppet 2.


John

Reply all
Reply to author
Forward
0 new messages