1
require 'puppet/util/checksums'
2
4
Puppet::Type.type(:file).newproperty(:content) do
3
5
include Puppet::Util::Diff
6
include Puppet::Util::Checksums
5
8
desc "Specify the contents of a file as a string. Newlines, tabs, and
6
9
spaces can be specified using the escaped syntax (e.g., \\n for a
22
25
This attribute is especially useful when used with
23
26
`PuppetTemplating templating`:trac:."
25
def string_as_checksum(string)
26
return "absent" if string == :absent
27
"{md5}" + Digest::MD5.hexdigest(string)
30
def should_to_s(should)
31
string_as_checksum(should)
35
string_as_checksum(is)
28
# Store a checksum as the value, rather than the actual content.
29
# Simplifies everything.
34
@actual_content = value
35
"{#{checksum_type}}" + send(self.checksum_type, value)
39
# Checksums need to invert how changes are printed.
40
def change_to_s(currentvalue, newvalue)
41
# Our "new" checksum value is provided by the source.
42
unless source = resource.parameter(:source) and newvalue = source.checksum
43
newvalue = "unknown checksum"
45
if currentvalue == :absent
46
return "defined content as '%s'" % [newvalue]
47
elsif newvalue == :absent
48
return "undefined content from '%s'" % [currentvalue]
50
return "content changed '%s' to '%s'" % [currentvalue, newvalue]
55
if source = resource.parameter(:source)
56
result = source.checksum
57
elsif checksum = resource.parameter(:checksum)
58
result = checksum.checktype
62
if result =~ /^\{(\w+)\}.+/
69
# If content was specified, return that; else try to return the source content;
72
if defined?(@actual_content) and @actual_content
73
return @actual_content
76
if s = resource.parameter(:source)
83
self.should || (s = resource.parameter(:source) and s.content)
38
86
# Override this method to provide diffs if asked for.
39
87
# Also, fix #872: when content is used, and replace is true, the file
40
88
# should be insync when it exists
42
if ! @resource.replace? and File.exists?(@resource[:path])
47
if ! result and Puppet[:show_diff] and File.exists?(@resource[:path])
48
string_file_diff(@resource[:path], self.should)
90
if resource.should_be_file?
91
return false if is == :absent
96
return true if ! @resource.replace?
100
elsif source = resource.parameter(:source)
101
fail "Got a remote source with no checksum" unless source.checksum
102
result = (is == source.checksum)
104
# We've got no content specified, and no source from which to
109
if ! result and Puppet[:show_diff]
110
string_file_diff(@resource[:path], actual_content)
54
116
return :absent unless stat = @resource.stat
56
return self.should if stat.ftype == "link" and @resource[:links] == :ignore
58
# Don't even try to manage the content on directories
118
# Don't even try to manage the content on directories or links
59
119
return nil if stat.ftype == "directory"
62
currentvalue = File.read(@resource[:path])
122
return "{#{checksum_type}}" + send(checksum_type.to_s + "_file", resource[:path]).to_s
65
raise Puppet::Error, "Could not read %s: %s" %
66
[@resource.title, detail]
124
raise Puppet::Error, "Could not read %s: %s" % [@resource.title, detail]
70
128
# Make sure we're also managing the checksum property.
71
129
def should=(value)
130
@resource.newattr(:checksum) unless @resource.parameter(:checksum)
73
@resource.newattr(:checksum) unless @resource.property(:checksum)
76
134
# Just write our content out to disk.
78
136
return_event = @resource.stat ? :file_changed : :file_created
80
@resource.write(self.should, :content)
138
# We're safe not testing for the 'source' if there's no 'should'
139
# because we wouldn't have gotten this far if there weren't at least
140
# one valid value somewhere.
141
@resource.write(actual_content, :content)
82
143
return return_event