Hi,

Le 18/09/2014 16:40, jcbollinger a écrit :

> Sorry, I worded that very poorly.

Really no problem. ;)

> Class my_module inherits my_module::params.  Absent my_module declaring its 
> own local variables $foo1 and $foo2, the inheritance results in variables 
> $::my_module::params::foo1 and $::my_module::params::foo2 being accessible 
> unqualified in class my_module's namespace.  Because those variables are 
> accessible unqualified in class my_module, they are also accessible 
> elsewhere qualified by namespace my_module (i.e. $::my_module::foo1) -- 
> *that* little bit of evil should not be used.  Instead, always qualify 
> variable references with the namespace in which the variable is actually 
> declared (my_module::params in this case).

Ok. Indeed I have read in Puppet documentation that it's better to avoid
unqualified variable (I have seen it's a "wolf trap") and it's better to
use fully qualified variable.

So, finally, is this way below a correct and good way to use the "params"
pattern?

-----------------------------------------------------
# Example of declaration for the "test" class.
class { test:
  var1 => 'specific_var1',
}

#### test module with its classes ####
class test::params {
  # API
  $var1 = 'default_var1'
  $var2 = 'default_var2'

  # Shared variables
  $foo1 = 'value_foo1'
  $foo2 = 'value_foo2'
}

# The main class of the module

# I use fully qualified variable names exclusively!
class test (
  $var1 = $::test::params::var1,
  $var2 = $::test::params::var2,
) inherits test::params {

  include ::test::internal

  notify { 'v1': message => "var1 = $::test::var1", }
  notify { 'v2': message => "var2 = $::test::var2", }
  notify { 'f1': message => "foo1 = $::test::foo1", }
  notify { 'f2': message => "foo2 = $::test::foo2", }

}

class test::internal {

  notify { 'iv1': message => "Internal var1 = $::test::var1", }
  notify { 'iv2': message => "Internal var2 = $::test::var2", }
  notify { 'if1': message => "Internal foo1 = $::test::foo1", }
  notify { 'if2': message => "Internal foo2 = $::test::foo2", }

  # So, in templates, I use the syntax scope['::test::var']
  # (I'm using Puppet 3.7.1 so -> scope[...])
  file { '/temp/internal.txt':
    content => inline_template("var1=<%= scope['::test::var1'] %>\nfoo2=<%= 
scope['::test::foo2'] %>\n"),
  }
}
-----------------------------------------------------

I use $::test::xxx in class::internal not $::test::params::xxx
because when xxx is "var1" or "var2", I want to have the value of
var1 and var2 given as parameters of the test class (I don't want
the default value of var1 and var2).

Like this, it all seems to you correct?

> No, not in the slightest.  I mean that if class my_module::params has a 
> local variable with unqualified name "foo1", then that variable can be 
> referenced from any class in any module as $my_module::params::foo1, 
> regardless of any inheritance or include / require / contain statements 
> anywhere.  

Hum... there is exception, isn't? For instance, it depends of the
order of the class in the catalog, I'm wrong?

For instance, with this manifest:

-----------------------------------------------------
include ::test1
include ::test2

class test1 {
  $var1 = "var1"
  notify { 'm1': message => "var2 = $::test2::var2", }
}

class test2 {
  $var2 = "var2"
  notify { 'm2': message => "var1 = $::test1::var1", }
}
-----------------------------------------------------

I have this result:

~$ puppet apply manifest.pp 
Warning: Scope(Class[Test1]): Could not look up qualified variable 
'::test2::var2'; class ::test2 has not been evaluated
Notice: Compiled catalog for wheezy-clean.chezmoi.priv in environment 
production in 0.02 seconds
Notice: var1 = var1
Notice: /Stage[main]/Test2/Notify[m2]/message: defined 'message' as 'var1 = 
var1'
Notice: var2 = 
Notice: /Stage[main]/Test1/Notify[m1]/message: defined 'message' as 'var2 = '
Notice: Finished catalog run in 0.41 seconds

>> I can give you a precise and quick (if you have already a Debian Wheezy) 
>> process to reproduct this. I take a Debian Wheezy, updated and cleaned 
>> (it's a simple VM in Virtualbox). And here is the process: 
>>
>>
> 
> I'm not prepared to set up and run this test, 

Ok. Let me show you an even faster test than the previous test (no installation
of puppetmaster just the puppet agent) :

root@wheezy-clean:~# lsb_release -sc
wheezy

root@wheezy-clean:~# wget 
https://apt.puppetlabs.com/puppetlabs-release-$(lsb_release -sc).deb
root@wheezy-clean:~# dpkg -i puppetlabs-release-$(lsb_release -sc).deb
root@wheezy-clean:~# apt-get update
root@wheezy-clean:~# apt-get install puppet
root@wheezy-clean:~# puppet -V
3.7.1

# Just comment the "templatedir" line in puppet.conf (which is deprecated)
root@wheezy-clean:~# sed -i -r 's/^(templatedir.*)$/#\1/g' 
/etc/puppet/puppet.conf

# Create a simple manifest.
root@wheezy-clean:~# vim manifest.pp

Here is my (very) simple manifest:

------------------------------
include ::test

class test {
  $var1 = "value_var1"       # LINE A
  include ::test::internal   # LINE B
}

class test::internal {
  notify { 'n1': message => "var1 = $var1", }

  file { '/tmp/internal.txt':
    content => inline_template("var1 = <%= @var1 %>\n"),
  }
}
------------------------------

# Apply the manifest.
root@wheezy-clean:~# puppet apply manifest.pp 
Notice: Compiled catalog for wheezy-clean.chezmoi.priv in environment 
production in 0.06 seconds
Notice: /Stage[main]/Test::Internal/File[/tmp/internal.txt]/ensure: defined 
content as '{md5}90e1f6ab3dc65719105f56f3b58dee5d'
Notice: var1 = 
Notice: /Stage[main]/Test::Internal/Notify[n1]/message: defined 'message' as 
'var1 = '
Notice: Finished catalog run in 0.15 seconds

root@wheezy-clean:~# cat /tmp/internal.txt 
var1 = value_var1

As you can see, in the local scope of test::internal, there is
no defined "var1" (and notify prints "var1 =") but in the
template, @var1 has been replaced by "value_var1".

And now, if I just swap LINE A with LINE B, I have this:

root@wheezy-clean:~# puppet apply manifest.pp 
Notice: Compiled catalog for wheezy-clean.chezmoi.priv in environment 
production in 0.06 seconds
Notice: /Stage[main]/Test::Internal/File[/tmp/internal.txt]/content: content 
changed '{md5}90e1f6ab3dc65719105f56f3b58dee5d' to 
'{md5}62d0ae15ddb3f27d78aa9a04c7c9cc4d'
Notice: var1 = 
Notice: /Stage[main]/Test::Internal/Notify[n1]/message: defined 'message' as 
'var1 = '
Notice: Finished catalog run in 0.03 seconds

root@wheezy-clean:~# cat /tmp/internal.txt 
var1 = 

Honestly, I don't understand. Is it normal, is it a bug... I don't know.

And if I try this (just fully qualified names):

------------------------------
include ::test

class test {
  $var1 = "value_var1"       # LINE A
  include ::test::internal   # LINE B
}

class test::internal {
  notify { 'n1': message => "var1 = $::test::var1", }

  file { '/tmp/internal.txt':
    content => inline_template("var1 = <%= scope['::test::var1'] %>\n"),
  }
}
------------------------------

I have:

root@wheezy-clean:~# puppet apply manifest.pp 
Notice: Compiled catalog for wheezy-clean.chezmoi.priv in environment 
production in 0.06 seconds
Notice: /Stage[main]/Test::Internal/File[/tmp/internal.txt]/content: content 
changed '{md5}62d0ae15ddb3f27d78aa9a04c7c9cc4d' to 
'{md5}90e1f6ab3dc65719105f56f3b58dee5d'
Notice: var1 = value_var1
Notice: /Stage[main]/Test::Internal/Notify[n1]/message: defined 'message' as 
'var1 = value_var1'
Notice: Finished catalog run in 0.08 seconds

root@wheezy-clean:~# cat /tmp/internal.txt 
var1 = value_var1

In this case, I'm ok (cool). But if I swap again LINE A and LINE B, I have:

root@wheezy-clean:~# puppet apply manifest.pp 
Notice: Compiled catalog for wheezy-clean.chezmoi.priv in environment 
production in 0.06 seconds
Notice: /Stage[main]/Test::Internal/File[/tmp/internal.txt]/content: content 
changed '{md5}90e1f6ab3dc65719105f56f3b58dee5d' to 
'{md5}62d0ae15ddb3f27d78aa9a04c7c9cc4d'
Notice: var1 = 
Notice: /Stage[main]/Test::Internal/Notify[n1]/message: defined 'message' as 
'var1 = '
Notice: Finished catalog run in 0.03 seconds

root@wheezy-clean:~# cat /tmp/internal.txt 
var = 

And in this case, I don't understand. I thought that :

  $var1 = "value_var1"       # LINE A
  include ::test::internal   # LINE B

and

  include ::test::internal   # LINE B
  $var1 = "value_var1"       # LINE A

was completely equivalent. Am I wrong?

I will probably make au bug report but perhaps is it more sure to
wait if somebody has the same behaviour as me...

Thanks for your help.
François Lafont

-- 
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 [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/puppet-users/541B63ED.4090500%40gmail.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to