2

I'm trying to get something like this to work in my Puppet manifest:

    if $hostname == 'host1' || $hostname == 'host2' {
        # Modified config.txt for portrait mode. 
        file { '/boot/config.txt' :
            ensure      => present,
            mode        => '0755',
            source      => 'puppet://puppet/files/boot/config.txt.portrait',
        }
    } else {
        # Normal config.txt for landscape mode.
        file { '/boot/config.txt' :
            ensure      => present,
            mode        => '0755',
            source      => 'puppet://puppet/files/boot/config.txt.landscape',
        }
    }

However, this fails. What is the best way to, depending on the hostname, to include different files?

3
  • 1
    Personally I would use a template so I wouldn't forget which file I had to edit for which host without searching.
    – user143703
    Mar 11, 2014 at 23:12
  • Rather then using hostname to determine this, can you tell which config file you need based on some attribute of the machine? For example, can you use a custom fact to detect the resolution, and go that way?
    – devicenull
    Mar 11, 2014 at 23:42
  • No, the devices are identical in every other way.
    – Tuinslak
    Mar 13, 2014 at 13:41

5 Answers 5

6

An alternative syntax would be to use a selector in your source parameter.

file { '/boot/config.txt' :
    ensure      => present,
    mode        => '0755',
    source      => $::hostname?{
                      'host1' => 'puppet://puppet/files/boot/config.txt.portrait',
                      'host2' => 'puppet://puppet/files/boot/config.txt.portrait',
                      default => 'puppet://puppet/files/boot/config.txt.landscape',
                    },
}
2
  • This seems like the cleanest option without using templates. Thanks all.
    – Tuinslak
    Mar 13, 2014 at 13:41
  • BTW, can an array of hostnames be used here ?
    – Tuinslak
    Mar 13, 2014 at 13:42
3

Building on what devicenull said, you can then shorten it further by using selective file source(s):

# Normal config.txt for landscape mode.
file { '/boot/config.txt' :
    ensure      => present,
    mode        => '0755',
    source      => [ 
         "puppet://puppet/files/boot/config.txt.$hostname", # down the individual hostname if required
         "puppet://puppet/files/boot/config.txt.$layouttype", # a layout dimension fact (portrait/landscape)
         "puppet://puppet/files/boot/config.txt" # default
    ],
}

I've got many examples like these in my manifests where relatively static files are needed for a host type (not often down to hostname level), but definitely $domain, and a custom fact $site_location (external, datacentre, office, etc) is used extensively.

2

For what you're asking I'd use Case Statements.

    case $hostname {
      'host1', 'host2': { # Modified config.txt for portrait mode. 
        file { '/boot/config.txt' :
            ensure      => present,
            mode        => '0755',
            source      => 'puppet://puppet/files/boot/config.txt.portrait',
        }  
      } 
      default:            { 
        file { '/boot/config.txt' :
            ensure      => present,
            mode        => '0755',
            source      => 'puppet://puppet/files/boot/config.txt.landscape',
        }
      } # apply the generic class
    }
1

Tuinslak!

We solved our problem like this:

       if $hostname =~ /^sv-dns./ {
               file { '/etc/chrony.conf':
                  ensure => file,
                  owner  => 'root',
                  group  => 'root',
                  mode   => '0644',
                  source => [ 'puppet:///modules/basico/conf/ntp_server/chrony.conf_server' ]
               }
    } else {
               file { '/etc/chrony.conf':
                  ensure => file,
                  owner  => 'root',
                  group  => 'root',
                  mode   => '0644',
                  source => [ 'puppet:///modules/basico/conf/ntp_server/chrony.conf_client' ]
               }
    }

We have two different types of chronyd configuration files: one for all the regular machines and one for all the DNS servers who act like a NTP server inside our network. We have a name convention here, that every DNS server has the hostname started with "sv-dns". So with the snippet above we can assure that every hostname, wich its name starts with "sv-dns" will receive the chrony.conf_server file and all other servers will receive the chrony.conf_client file.

If your hostname is fixed for example dnsmachine.some.domain you can use the example provided by @kwiksand:

file { '/boot/config.txt' :
ensure      => present,
mode        => '0755',
source      => $::hostname?{
                  'host1' => 'puppet://puppet/files/boot/config.txt.portrait',
                  'host2' => 'puppet://puppet/files/boot/config.txt.portrait',
                  default => 'puppet://puppet/files/boot/config.txt.landscape',
                },

Best regards,

Adail

0

I had to use "or" instead of ||:

    if $hostname == 'host1' or $hostname == 'host2' {

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .