new user: need Conditional statement example within a file resource type

3,410 views
Skip to first unread message

Kenneth Lo

unread,
Dec 13, 2011, 1:31:13 PM12/13/11
to Puppet Users
Searching old archive I find this topic:

http://groups.google.com/group/puppet-users/browse_thread/thread/187ee3897a26ae2a/32fea612e79dda80?hl=en&lnk=gst&q=puppet+case+statement+in+file+resource#32fea612e79dda80


I understand that "case statements must be outside of resource
statements" per that discussion and I understand the usage for the
selector in-statement solution, however that's just for assignment
though.

Consider this simple file resource, I just want to have a external
variable that control whether I need the file in the system:

file { "somefile" :

case ${hasfile} {
"true": { ensure => present }
default: { ensure => absent }
}
source => "puppet:///somefile",
owner => "root",
.
.
.
}


Obviously I had a syntax error here because case statement is not
happy within the resource.

So, what's a recommended puppet way to do something like this? thx in
advance.

--KL

Stefan Heijmans

unread,
Dec 13, 2011, 3:37:12 PM12/13/11
to puppet...@googlegroups.com
How about something like;


$hasfile = true
if $::hasfile {
   $fileensure = 'present'
}
else {
   $fileensure = 'absent'
}

file { "somefile" :

        ensure => $::fileensure,

Felix Frank

unread,
Dec 14, 2011, 7:34:01 AM12/14/11
to puppet...@googlegroups.com
This should also work:

file { "somefile": source => ..., owner => ... }

if $::hasfile {
File["somefile"] { ensure => present }
}
else {
File["somefile"] { ensure => absent }
}

It's up to you to decide which is more obscure.

Cheers,
Felix

Kenneth Lo

unread,
Dec 14, 2011, 10:05:22 AM12/14/11
to puppet...@googlegroups.com
This works. thx!

Another rookie question, what is the :: in front of the variable name
signify in general?

--KL

> --
> 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/-/CWF3DekKQwAJ.
>
> 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.

Kenneth Lo

unread,
Dec 14, 2011, 10:07:50 AM12/14/11
to puppet...@googlegroups.com
right, the reason I did not opt for this syntax is because my file
resource is actually quite large, and I think the other method Stefan
suggested has better readability.

> --
> You received this message because you are subscribed to the Google Groups "Puppet Users" group.

Stefan Heijmans

unread,
Dec 14, 2011, 10:53:38 AM12/14/11
to puppet...@googlegroups.com
It's to be future proof, you can read about @
 
Stefan
 

jcbollinger

unread,
Dec 14, 2011, 2:46:46 PM12/14/11
to Puppet Users

On Dec 13, 12:31 pm, Kenneth Lo <lo.kenn...@gmail.com> wrote:
> Searching old archive I find this topic:
>

> http://groups.google.com/group/puppet-users/browse_thread/thread/187e...


>
> I understand that  "case statements must be outside of resource
> statements" per that discussion and I understand the usage for the
> selector in-statement solution, however that's just for assignment
> though.


You seem to have a misapprehension here. See below.


> Consider this simple file resource, I just want to have a external
> variable that control whether I need the file in the system:
>
> file { "somefile" :
>
>         case ${hasfile} {
>            "true": { ensure => present }
>            default: { ensure => absent }
>         }
>         source => "puppet:///somefile",
>         owner => "root",
>         .
>         .
>         .
>
> }
>
> Obviously I had a syntax error here because case statement is not
> happy within the resource.


I would write it using a selector, like this:

file { "somefile" :
ensure => ${hasfile} ? {
'true' => present,
default => absent
},


source => "puppet:///somefile",
owner => "root",
}


Others' examples of using an 'if' statement outside the resource are
also fine, but where the desired conditional effect is so localized, I
prefer to localize the conditional itself.


John

Brice Figureau

unread,
Dec 16, 2011, 10:53:50 AM12/16/11
to puppet...@googlegroups.com

That's why the documentation says to use a selector.

> So, what's a recommended puppet way to do something like this? thx in
> advance.

file {
"somefile" :
ensure => $hasfile ? {


"true" => present,
default => absent
},

source => "puppet:///somefile",
owner => "root",
}

Please note that "true" is not strictly equivalent to the bareword true
in the puppet language :)
--
Brice Figureau
Follow the latest Puppet Community evolutions on www.planetpuppet.org!

Tim Mooney

unread,
Dec 16, 2011, 1:48:56 PM12/16/11
to puppet...@googlegroups.com
In regard to: Re: [Puppet Users] new user: need Conditional statement...:

>> Obviously I had a syntax error here because case statement is not
>> happy within the resource.
>
> That's why the documentation says to use a selector.
>
>> So, what's a recommended puppet way to do something like this? thx in
>> advance.
>
> file {
> "somefile" :
> ensure => $hasfile ? {
> "true" => present,
> default => absent
> },
> source => "puppet:///somefile",
> owner => "root",
> }
>
> Please note that "true" is not strictly equivalent to the bareword true
> in the puppet language :)

Ah, perfect segue. I had been meaning to follow up to John Bollinger
when he earlier posted something similar that also had 'true' quoted.

I've been through the style guide and several other areas in the
documentation and I can't find any recommendations on whether it's better
to use bare

true
false

or whether it's better to quote them. This is specifically for use in
parameterized classes. For example:

foo.bar.edu.pp:

node 'foo.bar.edu' {

class {'rhel':
version => '5',
ipv6_enabled => true,
}
}

rhel/manifests/init.pp:

class rhel($version, $ipv6_enabled='default') {
include rhel::common

case $ipv6_enabled {
true: {
class {'network': ipv6 => true }
}
false: {
class {'network': ipv6 => false }
}
default: {
case $version {
'5': {
class {'network': ipv6 => false }
}
'6': {
class {'network': ipv6 => true }
}
default: { fail("only version 5 and 6 of rhel are currently supported")}
}
}
}
}


In other words, our default for RHEL 5 is ipv6 disabled, on RHEL 6 it's
ipv6 enabled, but the default can be overridden for either.

The problem is that we had to be very careful to make certain that we
didn't quote true or false in some places and leave them as barewords
elsewhere, or it just wouldn't work. Mixing quoted & nonquoted gave us
unreliable and unexpected results.

This brings me back to the questions: where in the docs is this covered,
and what are the recommendations for whether we should (or shouldn't) be
quoting true & false when passing them around into parameterized classes
and testing them in selectors?

Thanks much,

Tim
--
Tim Mooney Tim.M...@ndsu.edu
Enterprise Computing & Infrastructure 701-231-1076 (Voice)
Room 242-J6, IACC Building 701-231-8541 (Fax)
North Dakota State University, Fargo, ND 58105-5164

Brice Figureau

unread,
Dec 16, 2011, 2:16:25 PM12/16/11
to puppet...@googlegroups.com

Exactly. If you intend your options to be boolean use the barewords true
and false.

> This brings me back to the questions: where in the docs is this covered,
> and what are the recommendations for whether we should (or shouldn't) be
> quoting true & false when passing them around into parameterized classes
> and testing them in selectors?

I don't know if it's covered in the documentation.

Puppet has the notion of true/false (ie the boolean). Any puppet
conditional expression can evaluate to either true or false.

On the other hande "true" is a string containing the word true. "false"
is a string containing the word false. It is not a boolean.

But that's where things get difficult:

if "false" {
notice("false is true")
}

This will print "false is true".

The same for
$str = "false"
if $str {
notice("false is true")
}

But,
case $str {
true: { notice("true") }
false: { notice("false as bool") }
"false": { notice("false as str") }
}

will print "false as str". So "false" != false and is not == to true.

But when converted as a boolean any strings becomes true, and that's
what happen in our if example.

We track this issue in the following ticket:
http://projects.puppetlabs.com/issues/5648

--
Brice Figureau
My Blog: http://www.masterzen.fr/

Trevor Vaughan

unread,
Dec 16, 2011, 3:15:34 PM12/16/11
to puppet...@googlegroups.com
I tend to quote all used of 'false' and 'true' mainly because
sometimes the guts of puppet seem to give me back a string no matter
what I want and a bareword won't work.

I don't have examples offhand and it's possible that this was fixed
some time in the past.

Trevor

> --
> You received this message because you are subscribed to the Google Groups "Puppet Users" group.
> 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.
>

--
Trevor Vaughan
Vice President, Onyx Point, Inc
(410) 541-6699
tvau...@onyxpoint.com

-- This account not approved for unencrypted proprietary information --

Craig White

unread,
Dec 16, 2011, 3:34:20 PM12/16/11
to puppet...@googlegroups.com
perhaps not puppet but facter which I think always returns things as strings - definitely a point of confusion but understandable when you think about it.

Craig

--
Craig White ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ craig...@ttiltd.com
1.800.869.6908 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ www.ttiassessments.com

Need help communicating between generations at work to achieve your desired success? Let us help!

Trevor Vaughan

unread,
Dec 16, 2011, 3:49:00 PM12/16/11
to puppet...@googlegroups.com
It *may* have been using passed variables in templates.

I don't quite remember, but something was certainly interpolating strangely.

I tend to quote everything:

For undefined variable $::foo...

if $::foo != 'true' { ... } -> Explodes
if "$::foo" != 'true' { ... } -> Works

And makes sense. Of course Undefined is certainly not equal to "true"
but who's counting.

Trevor

Reply all
Reply to author
Forward
0 new messages