Basic syntax and learning problems

398 views
Skip to first unread message

Edward Ned Harvey (puppet)

unread,
Jun 17, 2016, 3:48:44 PM6/17/16
to puppet...@googlegroups.com
Running puppet 3.7.4

I am new to puppet, and learning the syntax. For learning, I open up two terminals, where I "vi foo.pp" in one terminal, and I "puppet apply foo.pp" on the other terminal.

Using this:
node default {
notify{"syntax1":
message => $facts['osfamily']
}
}

I got this result:
Error: facts is not a hash or array when accessing it with osfamily at /root/foo.pp:3 on node...

So then, using this:
node default {
notify{"syntax1":
message => $facts
}
}

I get this result:
Notice: /Stage[main]/Main/Node[default]/Notify[syntax1]/message: defined 'message' as 'syntax1'

Question 1: Why can't I access $facts?

So I wondered if maybe facts weren't available because I'm running "puppet apply" instead of "puppet agent -t" but when I look here:
https://docs.puppet.com/puppet/3.7/reference/lang_facts_and_builtin_vars.html

They say "Before requesting a catalog (or compiling one with puppet apply), Puppet will collect system information with Facter. Puppet receives this information as facts..."

So I would expect $facts to be available.

Using this:
node default {
notify{"syntax1":
message => $os
}
}

I get this result:
Notice: /Stage[main]/Main/Node[default]/Notify[syntax1]/message: defined 'message' as '{"name"=>"RedHat", "family"=>"RedHat", "release"=>{"major"=>"7", "minor"=>"2", "full"=>"7.2"}}'

So it seems, yes, at least *some* facts are available.

Using this:
node default {
notify{"syntax1":
message => $os['name']
}
}

I get this:
Error: os is not a hash or array when accessing it with name at /root/foo.pp:3 on node ...

Question #2: What's wrong with my syntax to access the OS name? I would expect to be able to access $os['release']['major'] to get the result "7"

Peter Bukowinski

unread,
Jun 17, 2016, 4:12:48 PM6/17/16
to puppet...@googlegroups.com
Hi Edward,

With puppet 3.7, all facts are "stringified" by default, meaning hashes are flattened to strings. If you've got facter 2.0 or greater, you can change this behavior do you can access hash keys individually.

https://docs.puppet.com/puppet/3.7/reference/lang_facts_and_builtin_vars.html#data-types

Be sure to also read the next section below the one I linked for some gotchas. Also, if you want to access $facts as a hash, make sure to set he option notes here:

https://docs.puppet.com/puppet/3.7/reference/lang_facts_and_builtin_vars.html#the-factsfactname-hash

-- Peter (from phone)
> --
> 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/BY1PR0401MB1255B576DD0E2274E7825A2EDC570%40BY1PR0401MB1255.namprd04.prod.outlook.com.
> For more options, visit https://groups.google.com/d/optout.

Edward Ned Harvey (puppet)

unread,
Jun 17, 2016, 4:50:31 PM6/17/16
to puppet...@googlegroups.com
> From: puppet...@googlegroups.com [mailto:puppet-
> us...@googlegroups.com] On Behalf Of Peter Bukowinski
>
> Hi Edward,
>
> With puppet 3.7, all facts are "stringified" by default, meaning hashes are
> flattened to strings. If you've got facter 2.0 or greater, you can change this
> behavior do you can access hash keys individually.

Thanks very much for the help. Unfortunately, I'm learning, and working, in an environment with several hundred machines in production using puppet. I can't really expect to upgrade or reconfigure the environment. All I'm trying to do is ensure some ssh files exist in a particular user's home directory, so I thought I would use $facts to determine if the user exists, and get their home directory path, and create the files in there.

Is there a way to parse the $os string into a hash, so I can access its members? (Besides wanting to access users' home directories, it would also be useful to just get the OS major number, for a different purpose.) I tried parsejson(), but it doesn't like the => instead of :, and it didn't seem right to substitute : for =>. I figured there *should* be a way to parse the string the right way.

If not via $facts, how else would puppet put some files into a user's home directory?

Peter Bukowinski

unread,
Jun 17, 2016, 5:47:32 PM6/17/16
to puppet...@googlegroups.com
Fortunately, facter has separate facts for most items in the os fact hash. Keep in mind you can see all the facts available to your client by running ‘sudo facter -p’. Here are the facts you can use to directly access some of the facts in the os hash.

# facter os
{"name"=>"Ubuntu", "family"=>"Debian", "release"=>{"major"=>"13.10", "full"=>"13.10"}, "lsb"=>{"distcodename"=>"saucy", "distid"=>"Ubuntu", "distdescription"=>"Ubuntu 13.10", "distrelease"=>"13.10", "majdistrelease"=>"13.10”}}

# facter osfamily
Debian

# facter lsbmajdistrelease
13.10

# facter lsbdistcodename
saucy


The easiest way to install files into a particular user’s home directory (if the path to that directory is consistent across all your machines) is to create a package that does it for you. Then you can use puppet to ensure that the package is installed without it having to worry about the particulars.

Edward Ned Harvey (puppet)

unread,
Jun 17, 2016, 6:52:14 PM6/17/16
to puppet...@googlegroups.com
> From: puppet...@googlegroups.com [mailto:puppet-
> us...@googlegroups.com] On Behalf Of Peter Bukowinski
>
> Fortunately, facter has separate facts for most items in the os fact hash.
> Keep in mind you can see all the facts available to your client by running
> ‘sudo facter -p’

Thanks. That was very helpful. :-)


> The easiest way to install files into a particular user’s home directory (if the
> path to that directory is consistent across all your machines) is to create a
> package that does it for you. Then you can use puppet to ensure that the
> package is installed without it having to worry about the particulars.

Hmmm... If the directory is consistent across all the machines, I can just hard-code the path into puppet. For now, that's what I've done, but I look forward to learning a better way (or look forward to upgrading our environment, so I can hopefully use $facts in the future. But I'm not entirely sure $facts would contain the info I want anyway).

Thanks for your help.
Reply all
Reply to author
Forward
0 new messages