aboutsummaryrefslogtreecommitdiff
path: root/manifests/defines/concatenated_file.pp
blob: 5f1c2750faa3077fce7f06206fb7b23ae16d3ba3 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
# common/manifests/defines/concatenated_file.pp -- create a file from snippets
# stored in a directory
#
# Copyright (C) 2007 David Schmitt <david@schmitt.edv-bus.at>
# See LICENSE for the full license granted to you.

# TODO:
# * create the directory in _part too

# This resource collects file snippets from a directory ($dir) and concatenates
# them in lexical order of their names into a new file ($name). This can be
# used to collect information from disparate sources, when the target file
# format doesn't allow includes.
#
# concatenated_file_part can be used to easily configure content for this.
#
# If no $dir is specified, the target name with '.d' appended will be used.
#
# The $dir is purged by puppet and will only contain explicitely configured
# files. This can be overridden by defining the directory before the
# concatenated_file.
#
# Depend on File[$name] to change if and only if its contents change. Notify
# Exec["concat_${name}"] if you want to force an update.
#
# Usage:
#  concatenated_file { "/etc/some.conf":
#      dir => "/etc/some.conf.d",
#  }
define concatenated_file (
    $ensure = 'present',
    # where the snippets are located
    $dir = '',
    # a file with content to prepend
    $header = '',
    # a file with content to append
    $footer = '',
    # default permissions for the target file
    $mode = 0644, $owner = root, $group = 0
    )
{
    include common::moduledir::common::cf

    $dir_real = $dir ? { '' => "${name}.d", default => $dir }

    $tmp_file_name = regsubst($dir_real, '/', '_', 'G')
    $tmp_file = "${common::moduledir::module_dir_path}/${tmp_file_name}"

    if defined(File[$dir_real]) {
        debug("${dir_real} already defined")
    } else {
        file {
            $dir_real:
                ensure => $ensure ? {
                  'present' => directory,
                  default => $ensure
                },
                source => "puppet:///modules/common/empty",
                checksum => mtime,
                ignore => '.ignore',
                recurse => true, purge => true, force => true,
                mode => $mode, owner => $owner, group => $group,
                notify => Exec["concat_${name}"];
        }
    }

    file {
        $tmp_file:
            ensure => $ensure, checksum => md5,
            mode => $mode, owner => $owner, group => $group;
        # decouple the actual file from the generation process by using a
        # temporary file and puppet's source mechanism. This ensures that events
        # for notify/subscribe will only be generated when there is an actual
        # change.
        $name:
            ensure => $ensure, checksum => md5,
            source => $tmp_file,
            mode => $mode, owner => $owner, group => $group,
            require => File[$tmp_file];
    }

    if $ensure == 'present' {
      # if there is a header or footer file, add it
      $additional_cmd = $header ? {
        '' => $footer ? {
          '' => '',
          default => "| cat - '${footer}' "
        },
        default => $footer ? {
          '' => "| cat '${header}' - ",
          default => "| cat '${header}' - '${footer}' "
        }
      }

      # use >| to force clobbering the target file
      exec { "concat_${name}":
        command => "/usr/bin/find ${dir_real} -maxdepth 1 -type f ! -name '*puppettmp' -print0 | sort -z | xargs -0 cat ${additional_cmd} >| ${tmp_file}",
        subscribe => [ File[$dir_real] ],
        before => File[$tmp_file],
        alias => [ "concat_${dir_real}"],
        loglevel => info
      }
    }
}


# Add a snippet called $name to the concatenated_file at $dir.
# The file can be referenced as File["cf_part_${name}"]
define concatenated_file_part (
    $dir, $content = '', $ensure = present,
    $mode = 0644, $owner = root, $group = 0
    )
{

    file { "${dir}/${name}":
        ensure => $ensure, content => $content,
        mode => $mode, owner => $owner, group => $group,
        alias => "cf_part_${name}",
        notify => Exec["concat_${dir}"],
    }

}