|
| 1 | +require 'puppet/type/file/owner' |
| 2 | +require 'puppet/type/file/group' |
| 3 | +require 'puppet/type/file/mode' |
| 4 | +require 'puppet/util/checksums' |
| 5 | + |
| 6 | +Puppet::Type.newtype(:concat_file) do |
| 7 | + @doc = "Gets all the file fragments and puts these into the target file. |
| 8 | + This will mostly be used with exported resources. |
| 9 | +
|
| 10 | + example: |
| 11 | + Concat_fragment <<| tag == 'unique_tag' |>> |
| 12 | +
|
| 13 | + concat_file { '/tmp/file: |
| 14 | + tag => 'unique_tag', # Mandatory |
| 15 | + path => '/tmp/file', # Optional. If given it overrides the resource name |
| 16 | + owner => 'root', # Optional. Default to undef |
| 17 | + group => 'root', # Optional. Default to undef |
| 18 | + mode => '0644' # Optional. Default to undef |
| 19 | + order => 'numeric' # Optional, Default to 'numeric' |
| 20 | + } |
| 21 | + " |
| 22 | + ensurable do |
| 23 | + defaultvalues |
| 24 | + |
| 25 | + defaultto { :present } |
| 26 | + end |
| 27 | + |
| 28 | + def exists? |
| 29 | + self[:ensure] == :present |
| 30 | + end |
| 31 | + |
| 32 | + newparam(:name, :namevar => true) do |
| 33 | + desc "Resource name" |
| 34 | + end |
| 35 | + |
| 36 | + newparam(:tag) do |
| 37 | + desc "Tag reference to collect all concat_fragment's with the same tag" |
| 38 | + end |
| 39 | + |
| 40 | + newparam(:path) do |
| 41 | + desc "The output file" |
| 42 | + defaultto do |
| 43 | + resource.value(:name) |
| 44 | + end |
| 45 | + end |
| 46 | + |
| 47 | + newparam(:owner, :parent => Puppet::Type::File::Owner) do |
| 48 | + desc "Desired file owner." |
| 49 | + end |
| 50 | + |
| 51 | + newparam(:group, :parent => Puppet::Type::File::Group) do |
| 52 | + desc "Desired file group." |
| 53 | + end |
| 54 | + |
| 55 | + newparam(:mode, :parent => Puppet::Type::File::Mode) do |
| 56 | + desc "Desired file mode." |
| 57 | + end |
| 58 | + |
| 59 | + newparam(:order) do |
| 60 | + desc "Controls the ordering of fragments. Can be set to alphabetical or numeric." |
| 61 | + defaultto 'numeric' |
| 62 | + end |
| 63 | + |
| 64 | + newparam(:backup) do |
| 65 | + desc "Controls the filebucketing behavior of the final file and see File type reference for its use." |
| 66 | + defaultto 'puppet' |
| 67 | + end |
| 68 | + |
| 69 | + newparam(:replace) do |
| 70 | + desc "Whether to replace a file that already exists on the local system." |
| 71 | + defaultto true |
| 72 | + end |
| 73 | + |
| 74 | + newparam(:validate_cmd) do |
| 75 | + desc "Validates file." |
| 76 | + end |
| 77 | + |
| 78 | + autorequire(:concat_fragment) do |
| 79 | + catalog.resources.collect do |r| |
| 80 | + if r.is_a?(Puppet::Type.type(:concat_fragment)) && r[:tag] == self[:tag] |
| 81 | + r.name |
| 82 | + end |
| 83 | + end.compact |
| 84 | + end |
| 85 | + |
| 86 | + def should_content |
| 87 | + return @generated_content if @generated_content |
| 88 | + @generated_content = "" |
| 89 | + content_fragments = [] |
| 90 | + |
| 91 | + resources = catalog.resources.select do |r| |
| 92 | + r.is_a?(Puppet::Type.type(:concat_fragment)) && r[:tag] == self[:tag] |
| 93 | + end |
| 94 | + |
| 95 | + resources.each do |r| |
| 96 | + content_fragments << ["#{r[:order]}___#{r[:name]}", fragment_content(r)] |
| 97 | + end |
| 98 | + |
| 99 | + if self[:order] == 'numeric' |
| 100 | + sorted = content_fragments.sort do |a, b| |
| 101 | + def decompound(d) |
| 102 | + d.split('___').map { |v| v =~ /^\d+$/ ? v.to_i : v } |
| 103 | + end |
| 104 | + |
| 105 | + decompound(a[0]) <=> decompound(b[0]) |
| 106 | + end |
| 107 | + else |
| 108 | + sorted = content_fragments.sort do |a, b| |
| 109 | + def decompound(d) |
| 110 | + d.split('___').first |
| 111 | + end |
| 112 | + |
| 113 | + decompound(a[0]) <=> decompound(b[0]) |
| 114 | + end |
| 115 | + end |
| 116 | + |
| 117 | + @generated_content = sorted.map { |cf| cf[1] }.join |
| 118 | + |
| 119 | + @generated_content |
| 120 | + end |
| 121 | + |
| 122 | + def fragment_content(r) |
| 123 | + if r[:content].nil? == false |
| 124 | + fragment_content = r[:content] |
| 125 | + elsif r[:source].nil? == false |
| 126 | + @source = nil |
| 127 | + Array(r[:source]).each do |source| |
| 128 | + if Puppet::FileServing::Metadata.indirection.find(source) |
| 129 | + @source = source |
| 130 | + break |
| 131 | + end |
| 132 | + end |
| 133 | + self.fail "Could not retrieve source(s) #{r[:source].join(", ")}" unless @source |
| 134 | + tmp = Puppet::FileServing::Content.indirection.find(@source, :environment => catalog.environment) |
| 135 | + fragment_content = tmp.content unless tmp.nil? |
| 136 | + end |
| 137 | + fragment_content |
| 138 | + end |
| 139 | + |
| 140 | + def eval_generate |
| 141 | + file_opts = { |
| 142 | + :ensure => self[:ensure] == :absent ? :absent : :file, |
| 143 | + :content => self.should_content, |
| 144 | + } |
| 145 | + |
| 146 | + [:path, :owner, :group, :mode, :replace, :backup].each do |param| |
| 147 | + unless self[param].nil? |
| 148 | + file_opts[param] = self[param] |
| 149 | + end |
| 150 | + end |
| 151 | + |
| 152 | + [Puppet::Type.type(:file).new(file_opts)] |
| 153 | + end |
| 154 | +end |
0 commit comments