Can't use ${path} in file resource as its namevar?

1,221 views
Skip to first unread message

jblaine

unread,
Aug 24, 2011, 5:23:49 PM8/24/11
to puppet...@googlegroups.com
2.7.3

The heck?  ${path} is expanding to the shell environment PATH when I reference it as a variable
in my file resource.  Isn't this supposed to be the "namevar" for file resources?

err: /Stage[main]/Ldapclient::Config/File[/etc/ldap.conf]: Could not evaluate: Could not retrieve information from environment production source(s) puppet:///modules/ldapclient/RedHat/usr/bin:/bin:/usr/sbin:/sbin at /etc/puppet/modules/ldapclient/manifests/config.pp:9

class ldapclient::config {
    case $operatingsystem {
        /(RedHat|CentOS|Fedora)/: {
            file { [ '/etc/openldap/ldap.conf', '/etc/ldap.conf' ]:
                source => "${ldapclient::params::fileroot}${path}",
                owner => "$ldapclient::params::ldapclient_user",
                mode => 0444,
                require => Class['ldapclient::install'],
            }
        }
    }
}

Nan Liu

unread,
Aug 24, 2011, 6:38:21 PM8/24/11
to puppet...@googlegroups.com
On Wed, Aug 24, 2011 at 2:23 PM, jblaine <cjbl...@gmail.com> wrote:
> 2.7.3
> The heck?  ${path} is expanding to the shell environment PATH when I
> reference it as a variable
> in my file resource.  Isn't this supposed to be the "namevar" for file
> resources?

No, you don't have access to resource namevar unless it's within the
defined resource.

> err: /Stage[main]/Ldapclient::Config/File[/etc/ldap.conf]: Could not
> evaluate: Could not retrieve information from environment production
> source(s) puppet:///modules/ldapclient/RedHat/usr/bin:/bin:/usr/sbin:/sbin
> at /etc/puppet/modules/ldapclient/manifests/config.pp:9
> class ldapclient::config {
>     case $operatingsystem {
>         /(RedHat|CentOS|Fedora)/: {
>             file { [ '/etc/openldap/ldap.conf', '/etc/ldap.conf' ]:
>                 source => "${ldapclient::params::fileroot}${path}",
>                 owner => "$ldapclient::params::ldapclient_user",
>                 mode => 0444,
>                 require => Class['ldapclient::install'],
>             }
>         }
>     }
> }

define ldapclient::conf {
file { $name:
source => ${ldapclient::params::fileroot}/${name},


owner => $ldapclient::params::ldapclient_user,

mode => '0444',


require => Class['ldapclient::install'],
}
}

ldapclient::conf { [ '/etc/openldap/ldap.conf', '/etc/ldap.conf' ]: }

Nan

Stefan Schulte

unread,
Aug 24, 2011, 8:09:36 PM8/24/11
to puppet...@googlegroups.com
On Wed, Aug 24, 2011 at 02:23:49PM -0700, jblaine wrote:
> 2.7.3
>
> The heck? ${path} is expanding to the shell environment PATH when I
> reference it as a variable

FWIW: It doesnt reference the environment variable directly. It references the
fact "path" which in turn is the path environment variable.

Just run »facter path« on the command line and you should get similar
results.

-Stefan

jblaine

unread,
Aug 25, 2011, 10:44:46 AM8/25/11
to puppet...@googlegroups.com
On Wednesday, August 24, 2011 6:38:21 PM UTC-4, Nan Liu wrote:
On Wed, Aug 24, 2011 at 2:23 PM, jblaine <cjbl...@gmail.com> wrote:
> 2.7.3
> The heck?  ${path} is expanding to the shell environment PATH when I
> reference it as a variable
> in my file resource.  Isn't this supposed to be the "namevar" for file
> resources?

No, you don't have access to resource namevar unless it's within the
defined resource.

Hi Nan,

Thanks for the reply (you too Stefan).

My reference to the resource's namevar *is within the defined resource*.

            file { [ '/etc/openldap/ldap.conf', '/etc/ldap.conf' ]:
                source => "${ldapclient::params::fileroot}${path}",
                owner => "$ldapclient::params::ldapclient_user",
                mode => 0444,
                require => Class['ldapclient::install'],
            }

From what I've read of all the Puppet documentation I have (the latest
2 books (1 unreleased yet) + the Puppetlabs docs), the above should
work without having to "define" a custom resource as you show below.
Where am I wrong in my reading/thinking?  I must be missing something
somewhere.

--------------------------------------------------------------------------

...
The namevar is the parameter used to uniquely identify a type instance. This is the parameter that gets assigned when a string is provided before the colon in a type declaration. In general, only developers will need to worry about which parameter is the namevar.
...
FILE
...
path
    namevar
The path to the file to manage. Must be fully qualified.
...
--------------------------------------------------------------------------

...
Example shown:

file { [ 'foo', 'bar', 'foobar' ]:
    owner => 'root',
    group => 'root',
    mode => '0600',
}
--------------------------------------------------------------------------

Stefan Schulte

unread,
Aug 25, 2011, 12:58:06 PM8/25/11
to puppet...@googlegroups.com
On Thu, Aug 25, 2011 at 07:44:46AM -0700, jblaine wrote:
> On Wednesday, August 24, 2011 6:38:21 PM UTC-4, Nan Liu wrote:
> >
> > On Wed, Aug 24, 2011 at 2:23 PM, jblaine <cjbl...@gmail.com> wrote:
> > > 2.7.3
> > > The heck? ${path} is expanding to the shell environment PATH when I
> > > reference it as a variable
> > > in my file resource. Isn't this supposed to be the "namevar" for file
> > > resources?
> >
> > No, you don't have access to resource namevar unless it's within the
> > defined resource.
> >
> Hi Nan,
>
> Thanks for the reply (you too Stefan).
>
> My reference to the resource's namevar *is within the defined resource*.
>
> file { [ '/etc/openldap/ldap.conf', '/etc/ldap.conf' ]:
> source => "${ldapclient::params::fileroot}${path}",
> owner => "$ldapclient::params::ldapclient_user",
> mode => 0444,
> require => Class['ldapclient::install'],
> }
>

You misunderstood the concept of a namevar. The namevar of the
file resource is `path`, for the exec resource it is `command`, for a
service resource it is `name` and so on.

Here is an example where I set the namevar.

file { 'sshconfig':
path => '/etc/ssh/sshd_config',
ensure => file,
mode => '0600',
}

So I set the namevar (path) explicitly. Note that `namevar` is more
from the viewpoint of a resource type developer. In a manifest it is
just a parameter of a resource.

If you do not specify the namevar explicitly, it is the text before the
first colon, so in other words the title of the resource.

So when I write

file { '/etc/ssh/sshd_config':
ensure => file,
mode => '0600',
}

I did not specify the path of the file directly. I just set the title
and so path is implicitly /etc/ssh/sshd_config in the example.

However you cannot access the path parameter as a variable in your
manifest. It just happened that there is a fact that is named `path` so
whenever you use $path you will just query that fact.

-Stefan

jblaine

unread,
Aug 25, 2011, 1:13:18 PM8/25/11
to puppet...@googlegroups.com
Ahhh.  I see: (thinking out loud for my own clarity) I'm trying to reference it as a variable available to me, but it exists as a variable a layer below my view.  I can only specify the value it should be set to, but not make reference to it explicitly as ${path} (or ${command} or...).  To do what I want, I need to do what Nan showed with a custom resource definition to call which will then let me reference the passed in value as a variable.

jblaine

unread,
Jan 27, 2012, 5:34:39 PM1/27/12
to puppet...@googlegroups.com
Thread back from the dead 5 months later :)

Nan, using your code example, I get this with PE 2.0.1:

err: Could not retrieve catalog from remote server: Error 400 on
SERVER: Could not match ${ldapclient::params::fileroot}/${name},
at /etc/puppetlabs/puppet/modules/ldapclient/manifests/config.pp:3

define ldapclient::conf ($mode, $notify = false) {
    file { $name:
        source => ${ldapclient::params::fileroot}/${name},
        owner => $ldapclient::params::ldapclient_user,
        mode => $mode,
        if $notify {
            notify => Class['ldapclient::service'],
        }
        require => Class['ldapclient::install'],
    }
}

class ldapclient::config {
    case $sys_sshortai {
        'RH5': {
            ldapclient::conf { '/etc/openldap/ldap.conf': mode => '444' }
            ldapclient::conf { '/etc/ldap.conf': mode => '444' }
        }
        'RH6': {
            ldapclient::conf { '/etc/openldap/ldap.conf': mode => '444' }
            ldapclient::conf { '/etc/nslcd.conf': mode => '444', notify = true }
        }
    }
}

jcbollinger

unread,
Jan 27, 2012, 5:54:12 PM1/27/12
to Puppet Users
Your code looks buggy:
1) you cannot use 'if' statements inside resource defnitions
2) you write "notify = true" where you want "notify => true"

There are a couple of ways to address the former problem, among them
replacing the 'if' block with a selector. Also, I consider it a
matter of good form to use quotes around strings and to bracket
variable references, so I'd write the definition like this:

define ldapclient::conf ($mode, $notify = false) {
file { "${name}":
source => "${ldapclient::params::fileroot}/${name}",
owner => "${ldapclient::params::ldapclient_user}",
mode => "${mode}",
notify => $notify ? { true => Class['ldapclient::service'],
default => undef },
require => Class['ldapclient::install'],
}
}


John

jblaine

unread,
Jan 27, 2012, 6:00:57 PM1/27/12
to puppet...@googlegroups.com
John, I've no doubt the code is trash.  I'm struggling through what I
consider to be an extremely obtuse declarative language.  Thank
you for the advice.

Nan Liu

unread,
Jan 27, 2012, 6:05:08 PM1/27/12
to puppet...@googlegroups.com
I think you are missing double quotes around:
${ldapclient::params::fileroot}/${name}

Sent from my iPhone
--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/_E4djfGmFHEJ.
To post to this group, send email to puppet...@googlegroups.com.
To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.

jblaine

unread,
Jan 27, 2012, 6:17:19 PM1/27/12
to puppet...@googlegroups.com
Indeed.

Trashing the entire defined resource idea 30 mins ago, and
simply trying:

class ldapclient::config {
    case $sys_sshortai {
        'RH6': {
            file { '/etc/openldap/ldap.conf':
                mode => '444',
                source => "${ldapclient::params::fileroot}/${name}",
                owner  => $ldapclient::params::ldapclient_user,
                require => Class['ldapclient::install'],
            }
            file { '/etc/nslcd.conf':
                mode => '444',
                source => "${ldapclient::params::fileroot}/${name}",
                owner  => $ldapclient::params::ldapclient_user,
                require => Class['ldapclient::install'],
                notify => Class['ldapclient::service'],
            }
        }
    }


is giving me:

err: /Stage[main]/Ldapclient::Config/File[/etc/nslcd.conf]: Could not evaluate: Could not retrieve information from environment production source(s) puppet:///modules/ldapclient/files/RH6/ldapclient::config at /etc/puppetlabs/puppet/modules/ldapclient/manifests/config.pp:30
err: /Stage[main]/Ldapclient::Config/File[/etc/openldap/ldap.conf]: Could not evaluate: Could not retrieve information from environment production source(s) puppet:///modules/ldapclient/files/RH6/ldapclient::config at /etc/puppetlabs/puppet/modules/ldapclient/manifests/config.pp:23 

This is maddening.  What do those errors even mean?  So vague :(

Denmat

unread,
Jan 27, 2012, 6:46:43 PM1/27/12
to puppet...@googlegroups.com
The errors are good at locating the source of your issues:

err: /Stage[main]/Ldapclient::Config/File[/etc/nslcd.conf]: Could not evaluate: Could not retrieve information from environment production source(s) puppet:///modules/ldapclient/files/RH6/ldapclient::config at /etc/puppetlabs/puppet/modules/ldapclient/manifests/config.pp:30


Line 30 of your config.pp is where your problem lies (one of them anyway). It can't find the source file.

file { '/etc/nslcd.conf':
mode => '444',
source => "${ldapclient::params::fileroot}/${name}",
owner => $ldapclient::params::ldapclient_user,
require => Class['ldapclient::install'],
notify => Class['ldapclient::service'],
}

So it is interpreting this:


"${ldapclient::params::fileroot}/${name}",

As:
puppet:///modules/ldapclient/files/RH6/ldapclient::config

The following will give detail about fileserving, but $name is probably not resolving to what you think it should:
http://docs.puppetlabs.com/guides/file_serving.html

How are you declaring this in your manliest. What do you think $name should be? Try putting in the source path without the variable substitution.

Den

Gary Larizza

unread,
Jan 27, 2012, 7:08:34 PM1/27/12
to puppet...@googlegroups.com
In the link Den provided, you'll want to check the puppet:/// syntax.  You don't want to include the 'files' directory in the puppet:/// reference.  You'll want to use puppet:///modules/ldapclient/RH6/config_file for a file located in  $modulepath/ldapclient/files/RH6/config_file.  By default, using puppet:///, it looks to the files directory, so you don't need to pass it.
 

This is maddening.  What do those errors even mean?  So vague :(

--
You received this message because you are subscribed to the Google Groups "Puppet Users" group.
To view this discussion on the web visit https://groups.google.com/d/msg/puppet-users/-/ZwWSDMnrqesJ.

To post to this group, send email to puppet...@googlegroups.com.
To unsubscribe from this group, send email to puppet-users...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/puppet-users?hl=en.



--

Gary Larizza
Professional Services Engineer
Puppet Labs

jblaine

unread,
Jan 27, 2012, 7:25:19 PM1/27/12
to puppet...@googlegroups.com
Den and Gary, thanks for the replies.

I am trying to re-use the title (as I understand it). Can I not do that?
Do I have to type the name of the file as the title and also at the
end of my source => "${ldapclient::params::fileroot}/.......", ?

Gary, I've removed '/files' as part of ${ldapclient::params::fileroot}

Setting the source to the explicit filename (typing it again) works,
but seems silly to me.

Felix Frank

unread,
Jan 30, 2012, 4:41:40 AM1/30/12
to puppet...@googlegroups.com
On 01/28/2012 12:17 AM, jblaine wrote:
> Trashing the entire defined resource idea 30 mins ago, and
> simply trying:

But why?

> class ldapclient::config {
> case $sys_sshortai {
> 'RH6': {
> file { '/etc/openldap/ldap.conf':
> mode => '444',
> source => "${ldapclient::params::fileroot}/${name}",

You're back to square one. $name is nothing sensible in this context.
It's the name of the class this appears inside of - 'ldapclient::config'.

For automatic URL composition by use of the file path, you definitely do
want to wrap the file resource in a defined type like you were trying
earlier!

HTH,
Felix

jblaine

unread,
Jan 30, 2012, 9:50:40 AM1/30/12
to puppet...@googlegroups.com
On Monday, January 30, 2012 4:41:40 AM UTC-5, Felix.Frank wrote:
On 01/28/2012 12:17 AM, jblaine wrote:
> Trashing the entire defined resource idea 30 mins ago, and
> simply trying:

But why?

Felix, thanks for the reply.

I was just trying stuff out while waiting to see what fleshed out here in
the group.
 

> class ldapclient::config {
>     case $sys_sshortai {
>         'RH6': {
>             file { '/etc/openldap/ldap.conf':
>                 mode => '444',
>                 source => "${ldapclient::params::fileroot}/${name}",

You're back to square one. $name is nothing sensible in this context.
It's the name of the class this appears inside of - 'ldapclient::config'.

So there's nothing I can refer to inside a basic file resource declaration
which refers to the file resource "title".  That's what I wanted to know
(assuming I understand everyone correctly).

Felix Frank

unread,
Jan 30, 2012, 10:31:43 AM1/30/12
to puppet...@googlegroups.com
On 01/30/2012 03:50 PM, jblaine wrote:
> So there's nothing I can refer to inside a basic file resource declaration
> which refers to the file resource "title". That's what I wanted to know
> (assuming I understand everyone correctly).

That's correct, yes.

Reply all
Reply to author
Forward
0 new messages