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?

  • 1
    Personally I would use a template so I wouldn't forget which file I had to edit for which host without searching. – yoonix Mar 11 '14 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 '14 at 23:42
  • No, the devices are identical in every other way. – Tuinslak Mar 13 '14 at 13:41
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',
                    },
}
  • This seems like the cleanest option without using templates. Thanks all. – Tuinslak Mar 13 '14 at 13:41
  • BTW, can an array of hostnames be used here ? – Tuinslak Mar 13 '14 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' {

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.