puppet 0.24.1 → 0.24.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puppet might be problematic. Click here for more details.
- data/CHANGELOG +94 -0
- data/Rakefile +0 -4
- data/bin/puppet +18 -10
- data/bin/puppetd +1 -1
- data/bin/puppetdoc +14 -4
- data/bin/puppetmasterd +1 -1
- data/bin/puppetrun +3 -8
- data/bin/ralsh +12 -11
- data/conf/freebsd/puppetd +1 -1
- data/conf/freebsd/puppetmasterd +1 -1
- data/conf/gentoo/puppet/puppet.conf +29 -0
- data/conf/namespaceauth.conf +20 -0
- data/conf/redhat/puppet.spec +4 -1
- data/conf/solaris/smf/puppetd.xml +1 -1
- data/conf/solaris/smf/puppetmasterd.xml +1 -1
- data/conf/suse/puppet.spec +10 -8
- data/examples/root/etc/puppet/{puppetmasterd.conf → puppet.conf} +6 -3
- data/ext/logcheck/puppet +7 -0
- data/ext/puppet-test +28 -5
- data/lib/puppet.rb +2 -1
- data/lib/puppet/defaults.rb +12 -5
- data/lib/puppet/dsl.rb +43 -45
- data/lib/puppet/external/{gratr/rdot.rb → dot.rb} +0 -0
- data/lib/puppet/external/nagios.rb +50 -0
- data/lib/puppet/external/nagios/base.rb +421 -0
- data/lib/puppet/external/nagios/parser.rb +816 -0
- data/lib/puppet/file_serving/file_base.rb +16 -3
- data/lib/puppet/file_serving/metadata.rb +29 -11
- data/lib/puppet/indirector/terminus.rb +1 -0
- data/lib/puppet/metatype/closure.rb +4 -0
- data/lib/puppet/metatype/evaluation.rb +2 -17
- data/lib/puppet/metatype/metaparams.rb +1 -1
- data/lib/puppet/network.rb +3 -0
- data/lib/puppet/network/client.rb +4 -5
- data/lib/puppet/network/client/master.rb +10 -7
- data/lib/puppet/network/handler/fileserver.rb +22 -45
- data/lib/puppet/network/http_pool.rb +3 -0
- data/lib/puppet/network/http_server/mongrel.rb +7 -1
- data/lib/puppet/network/http_server/webrick.rb +4 -3
- data/lib/puppet/network/xmlrpc/client.rb +12 -1
- data/lib/puppet/node/catalog.rb +51 -40
- data/lib/puppet/parser/ast.rb +27 -49
- data/lib/puppet/parser/ast/astarray.rb +5 -24
- data/lib/puppet/parser/ast/caseopt.rb +4 -4
- data/lib/puppet/parser/ast/casestatement.rb +4 -5
- data/lib/puppet/parser/ast/collection.rb +3 -5
- data/lib/puppet/parser/ast/collexpr.rb +3 -5
- data/lib/puppet/parser/ast/definition.rb +148 -159
- data/lib/puppet/parser/ast/else.rb +2 -3
- data/lib/puppet/parser/ast/function.rb +3 -10
- data/lib/puppet/parser/ast/hostclass.rb +66 -59
- data/lib/puppet/parser/ast/ifstatement.rb +4 -5
- data/lib/puppet/parser/ast/leaf.rb +6 -6
- data/lib/puppet/parser/ast/node.rb +26 -58
- data/lib/puppet/parser/ast/resource.rb +5 -7
- data/lib/puppet/parser/ast/resource_defaults.rb +2 -4
- data/lib/puppet/parser/ast/resource_override.rb +4 -6
- data/lib/puppet/parser/ast/resource_reference.rb +2 -4
- data/lib/puppet/parser/ast/resourceparam.rb +2 -4
- data/lib/puppet/parser/ast/selector.rb +5 -6
- data/lib/puppet/parser/ast/tag.rb +2 -4
- data/lib/puppet/parser/ast/vardef.rb +3 -4
- data/lib/puppet/parser/collector.rb +5 -5
- data/lib/puppet/parser/{compile.rb → compiler.rb} +69 -107
- data/lib/puppet/parser/functions.rb +3 -3
- data/lib/puppet/parser/interpreter.rb +32 -23
- data/lib/puppet/parser/lexer.rb +391 -282
- data/lib/puppet/parser/parser.rb +5 -4
- data/lib/puppet/parser/parser_support.rb +3 -6
- data/lib/puppet/parser/resource.rb +24 -36
- data/lib/puppet/parser/resource/param.rb +1 -1
- data/lib/puppet/parser/resource/reference.rb +7 -3
- data/lib/puppet/parser/scope.rb +12 -7
- data/lib/puppet/parser/templatewrapper.rb +1 -1
- data/lib/puppet/pgraph.rb +9 -98
- data/lib/puppet/provider/interface/redhat.rb +65 -65
- data/lib/puppet/provider/mount/parsed.rb +1 -1
- data/lib/puppet/provider/naginator.rb +55 -0
- data/lib/puppet/provider/nameservice/directoryservice.rb +6 -7
- data/lib/puppet/provider/package/fink.rb +0 -2
- data/lib/puppet/provider/package/gem.rb +9 -5
- data/lib/puppet/provider/package/openbsd.rb +1 -1
- data/lib/puppet/provider/package/pkgdmg.rb +3 -8
- data/lib/puppet/provider/package/portage.rb +4 -4
- data/lib/puppet/provider/package/yumhelper.py +8 -6
- data/lib/puppet/provider/parsedfile.rb +7 -1
- data/lib/puppet/provider/service/debian.rb +2 -0
- data/lib/puppet/provider/service/gentoo.rb +4 -0
- data/lib/puppet/provider/service/init.rb +1 -1
- data/lib/puppet/provider/sshkey/parsed.rb +2 -0
- data/lib/puppet/provider/user/useradd.rb +1 -1
- data/lib/puppet/rails.rb +4 -0
- data/lib/puppet/rails/database/001_add_created_at_to_all_tables.rb +17 -0
- data/lib/puppet/rails/fact_value.rb +4 -0
- data/lib/puppet/rails/host.rb +1 -2
- data/lib/puppet/rails/param_value.rb +4 -0
- data/lib/puppet/rails/resource_tag.rb +4 -0
- data/lib/puppet/rails/source_file.rb +4 -1
- data/lib/puppet/relationship.rb +5 -1
- data/lib/puppet/reports/tagmail.rb +12 -1
- data/lib/puppet/resource_reference.rb +1 -1
- data/lib/puppet/simple_graph.rb +78 -11
- data/lib/puppet/sslcertificates.rb +1 -1
- data/lib/puppet/sslcertificates/ca.rb +3 -3
- data/lib/puppet/transaction.rb +7 -4
- data/lib/puppet/transportable.rb +1 -1
- data/lib/puppet/type.rb +3 -10
- data/lib/puppet/type/cron.rb +18 -0
- data/lib/puppet/type/exec.rb +18 -12
- data/lib/puppet/type/{pfile.rb → file.rb} +66 -84
- data/lib/puppet/type/file/checksum.rb +271 -0
- data/lib/puppet/type/{pfile → file}/content.rb +10 -15
- data/lib/puppet/type/{pfile → file}/ensure.rb +15 -8
- data/lib/puppet/type/{pfile → file}/group.rb +0 -0
- data/lib/puppet/type/{pfile → file}/mode.rb +0 -0
- data/lib/puppet/type/{pfile → file}/owner.rb +0 -0
- data/lib/puppet/type/{pfile → file}/source.rb +34 -48
- data/lib/puppet/type/{pfile → file}/target.rb +0 -0
- data/lib/puppet/type/{pfile → file}/type.rb +0 -0
- data/lib/puppet/type/{pfilebucket.rb → filebucket.rb} +0 -0
- data/lib/puppet/type/host.rb +13 -0
- data/lib/puppet/type/mailalias.rb +1 -1
- data/lib/puppet/type/nagios_command.rb +3 -0
- data/lib/puppet/type/nagios_contact.rb +3 -0
- data/lib/puppet/type/nagios_contactgroup.rb +3 -0
- data/lib/puppet/type/nagios_host.rb +3 -0
- data/lib/puppet/type/nagios_hostextinfo.rb +3 -0
- data/lib/puppet/type/nagios_hostgroup.rb +3 -0
- data/lib/puppet/type/nagios_hostgroupescalation.rb +3 -0
- data/lib/puppet/type/nagios_service.rb +3 -0
- data/lib/puppet/type/nagios_servicedependency.rb +3 -0
- data/lib/puppet/type/nagios_serviceescalation.rb +3 -0
- data/lib/puppet/type/nagios_serviceextinfo.rb +3 -0
- data/lib/puppet/type/nagios_timeperiod.rb +3 -0
- data/lib/puppet/type/package.rb +4 -12
- data/lib/puppet/type/service.rb +9 -0
- data/lib/puppet/type/sshkey.rb +3 -3
- data/lib/puppet/util/autoload.rb +5 -5
- data/lib/puppet/util/checksums.rb +51 -13
- data/lib/puppet/util/constant_inflector.rb +14 -0
- data/lib/puppet/util/filetype.rb +1 -1
- data/lib/puppet/util/graph.rb +3 -9
- data/lib/puppet/util/nagios_maker.rb +57 -0
- data/lib/puppet/util/settings.rb +19 -16
- data/lib/puppet/util/tagging.rb +39 -0
- data/test/executables/puppetbin.rb +17 -0
- data/test/language/ast.rb +8 -58
- data/test/language/ast/casestatement.rb +3 -3
- data/test/language/ast/resource.rb +6 -7
- data/test/language/ast/resource_reference.rb +12 -12
- data/test/language/ast/selector.rb +2 -2
- data/test/language/ast/variable.rb +2 -2
- data/test/language/functions.rb +24 -24
- data/test/language/parser.rb +20 -8
- data/test/language/resource.rb +5 -42
- data/test/language/scope.rb +21 -37
- data/test/language/snippets.rb +7 -0
- data/test/lib/puppettest.rb +28 -14
- data/test/lib/puppettest/parsertesting.rb +10 -10
- data/test/lib/puppettest/support/resources.rb +1 -1
- data/test/network/client/master.rb +10 -0
- data/test/network/handler/fileserver.rb +51 -49
- data/test/network/server/webrick.rb +1 -1
- data/test/other/dsl.rb +3 -4
- data/test/other/transactions.rb +6 -4
- data/test/rails/ast.rb +2 -2
- data/test/rails/configuration.rb +1 -1
- data/test/rails/railsparameter.rb +2 -0
- data/test/rails/railsresource.rb +1 -0
- data/test/ral/manager/type.rb +4 -4
- data/test/ral/providers/cron/crontab.rb +3 -1
- data/test/ral/providers/package.rb +1 -1
- data/test/ral/{types → type}/basic.rb +2 -2
- data/test/ral/{types → type}/cron.rb +0 -0
- data/test/ral/{types → type}/exec.rb +42 -2
- data/test/ral/{types → type}/file.rb +34 -79
- data/test/ral/{types → type}/file/target.rb +0 -0
- data/test/ral/{types → type}/filebucket.rb +0 -0
- data/test/ral/{types → type}/fileignoresource.rb +0 -0
- data/test/ral/{types → type}/filesources.rb +8 -27
- data/test/ral/{types → type}/group.rb +0 -0
- data/test/ral/{types → type}/host.rb +16 -0
- data/test/ral/{types → type}/mailalias.rb +0 -0
- data/test/ral/{types → type}/parameter.rb +0 -0
- data/test/ral/{types → type}/port.rb +0 -0
- data/test/ral/{types → type}/property.rb +0 -0
- data/test/ral/{types → type}/resources.rb +0 -0
- data/test/ral/{types → type}/service.rb +0 -0
- data/test/ral/{types → type}/sshkey.rb +0 -0
- data/test/ral/{types → type}/tidy.rb +1 -0
- data/test/ral/{types → type}/user.rb +0 -0
- data/test/ral/{types → type}/yumrepo.rb +0 -0
- data/test/ral/{types → type}/zone.rb +0 -0
- data/test/util/autoload.rb +24 -5
- metadata +60 -107
- data/conf/gentoo/puppet/puppetca.conf +0 -29
- data/conf/gentoo/puppet/puppetd.conf +0 -29
- data/conf/gentoo/puppet/puppetmasterd.conf +0 -29
- data/examples/root/etc/puppet/puppetd.conf +0 -4
- data/lib/puppet/external/gratr.rb +0 -33
- data/lib/puppet/external/gratr/adjacency_graph.rb +0 -257
- data/lib/puppet/external/gratr/base.rb +0 -34
- data/lib/puppet/external/gratr/biconnected.rb +0 -116
- data/lib/puppet/external/gratr/chinese_postman.rb +0 -123
- data/lib/puppet/external/gratr/common.rb +0 -73
- data/lib/puppet/external/gratr/comparability.rb +0 -92
- data/lib/puppet/external/gratr/digraph.rb +0 -116
- data/lib/puppet/external/gratr/digraph_distance.rb +0 -185
- data/lib/puppet/external/gratr/dot.rb +0 -90
- data/lib/puppet/external/gratr/edge.rb +0 -145
- data/lib/puppet/external/gratr/graph.rb +0 -303
- data/lib/puppet/external/gratr/graph_api.rb +0 -83
- data/lib/puppet/external/gratr/import.rb +0 -44
- data/lib/puppet/external/gratr/labels.rb +0 -90
- data/lib/puppet/external/gratr/maximum_flow.rb +0 -64
- data/lib/puppet/external/gratr/search.rb +0 -409
- data/lib/puppet/external/gratr/strong_components.rb +0 -127
- data/lib/puppet/external/gratr/undirected_graph.rb +0 -153
- data/lib/puppet/rails/external/tagging/acts_as_taggable.rb +0 -62
- data/lib/puppet/rails/external/tagging/init.rb +0 -5
- data/lib/puppet/rails/external/tagging/tag.rb +0 -50
- data/lib/puppet/rails/external/tagging/tagging.rb +0 -12
- data/lib/puppet/rails/puppet_class.rb +0 -6
- data/lib/puppet/reference/node_source.rb +0 -9
- data/lib/puppet/reference/report.rb +0 -21
- data/lib/puppet/type/pfile/checksum.rb +0 -326
- data/test/language/ast/definition.rb +0 -166
- data/test/language/ast/hostclass.rb +0 -184
- data/test/language/compile.rb +0 -569
- data/test/language/lexer.rb +0 -276
- data/test/lib/mocha.rb +0 -19
- data/test/lib/mocha/any_instance_method.rb +0 -35
- data/test/lib/mocha/auto_verify.rb +0 -113
- data/test/lib/mocha/central.rb +0 -35
- data/test/lib/mocha/class_method.rb +0 -62
- data/test/lib/mocha/deprecation.rb +0 -22
- data/test/lib/mocha/exception_raiser.rb +0 -17
- data/test/lib/mocha/expectation.rb +0 -378
- data/test/lib/mocha/expectation_error.rb +0 -6
- data/test/lib/mocha/infinite_range.rb +0 -25
- data/test/lib/mocha/inspect.rb +0 -39
- data/test/lib/mocha/instance_method.rb +0 -8
- data/test/lib/mocha/is_a.rb +0 -9
- data/test/lib/mocha/metaclass.rb +0 -7
- data/test/lib/mocha/missing_expectation.rb +0 -27
- data/test/lib/mocha/mock.rb +0 -207
- data/test/lib/mocha/multiple_yields.rb +0 -20
- data/test/lib/mocha/no_yields.rb +0 -11
- data/test/lib/mocha/object.rb +0 -110
- data/test/lib/mocha/parameter_matchers.rb +0 -9
- data/test/lib/mocha/parameter_matchers/all_of.rb +0 -39
- data/test/lib/mocha/parameter_matchers/any_of.rb +0 -44
- data/test/lib/mocha/parameter_matchers/anything.rb +0 -30
- data/test/lib/mocha/parameter_matchers/has_entry.rb +0 -39
- data/test/lib/mocha/parameter_matchers/has_key.rb +0 -39
- data/test/lib/mocha/parameter_matchers/has_value.rb +0 -39
- data/test/lib/mocha/parameter_matchers/includes.rb +0 -37
- data/test/lib/mocha/pretty_parameters.rb +0 -28
- data/test/lib/mocha/return_values.rb +0 -31
- data/test/lib/mocha/setup_and_teardown.rb +0 -23
- data/test/lib/mocha/single_return_value.rb +0 -24
- data/test/lib/mocha/single_yield.rb +0 -18
- data/test/lib/mocha/standalone.rb +0 -32
- data/test/lib/mocha/stub.rb +0 -18
- data/test/lib/mocha/test_case_adapter.rb +0 -49
- data/test/lib/mocha/yield_parameters.rb +0 -31
data/lib/puppet/type/exec.rb
CHANGED
@@ -211,10 +211,7 @@ module Puppet
|
|
211
211
|
log the output when the command reports an error. Values are
|
212
212
|
**true**, *false*, *on_failure*, and any legal log level."
|
213
213
|
|
214
|
-
|
215
|
-
# And all of the log levels
|
216
|
-
Puppet::Util::Log.eachlevel { |level| values << level }
|
217
|
-
newvalues(*values)
|
214
|
+
newvalues(:true, :false, :on_failure)
|
218
215
|
end
|
219
216
|
|
220
217
|
newparam(:refresh) do
|
@@ -229,6 +226,15 @@ module Puppet
|
|
229
226
|
end
|
230
227
|
|
231
228
|
newparam(:env) do
|
229
|
+
desc "This parameter is deprecated. Use 'environment' instead."
|
230
|
+
|
231
|
+
munge do |value|
|
232
|
+
warning "'env' is deprecated on exec; use 'environment' instead."
|
233
|
+
resource[:environment] = value
|
234
|
+
end
|
235
|
+
end
|
236
|
+
|
237
|
+
newparam(:environment) do
|
232
238
|
desc "Any additional environment variables you want to set for a
|
233
239
|
command. Note that if you use this to set PATH, it will override
|
234
240
|
the ``path`` attribute. Multiple environment variables should be
|
@@ -279,7 +285,7 @@ module Puppet
|
|
279
285
|
# Rebuild the database, but only when the file changes
|
280
286
|
exec { newaliases:
|
281
287
|
path => [\"/usr/bin\", \"/usr/sbin\"],
|
282
|
-
subscribe =>
|
288
|
+
subscribe => File[\"/etc/aliases\"],
|
283
289
|
refreshonly => true
|
284
290
|
}
|
285
291
|
|
@@ -554,32 +560,32 @@ module Puppet
|
|
554
560
|
begin
|
555
561
|
# Do our chdir
|
556
562
|
Dir.chdir(dir) do
|
557
|
-
|
563
|
+
environment = {}
|
558
564
|
|
559
565
|
if self[:path]
|
560
|
-
|
566
|
+
environment[:PATH] = self[:path].join(":")
|
561
567
|
end
|
562
568
|
|
563
|
-
if envlist = self[:
|
569
|
+
if envlist = self[:environment]
|
564
570
|
envlist = [envlist] unless envlist.is_a? Array
|
565
571
|
envlist.each do |setting|
|
566
572
|
if setting =~ /^(\w+)=((.|\n)+)$/
|
567
573
|
name = $1
|
568
574
|
value = $2
|
569
|
-
if
|
575
|
+
if environment.include? name
|
570
576
|
warning(
|
571
577
|
"Overriding environment setting '%s' with '%s'" %
|
572
578
|
[name, value]
|
573
579
|
)
|
574
580
|
end
|
575
|
-
|
581
|
+
environment[name] = value
|
576
582
|
else
|
577
|
-
warning "Cannot understand
|
583
|
+
warning "Cannot understand environment setting %s" % setting.inspect
|
578
584
|
end
|
579
585
|
end
|
580
586
|
end
|
581
587
|
|
582
|
-
withenv
|
588
|
+
withenv environment do
|
583
589
|
Timeout::timeout(self[:timeout]) do
|
584
590
|
output, status = Puppet::Util::SUIDManager.run_and_capture(
|
585
591
|
[command], self[:user], self[:group]
|
@@ -5,10 +5,12 @@ require 'uri'
|
|
5
5
|
require 'fileutils'
|
6
6
|
require 'puppet/network/handler'
|
7
7
|
require 'puppet/util/diff'
|
8
|
+
require 'puppet/util/checksums'
|
8
9
|
|
9
10
|
module Puppet
|
10
11
|
newtype(:file) do
|
11
12
|
include Puppet::Util::MethodHelper
|
13
|
+
include Puppet::Util::Checksums
|
12
14
|
@doc = "Manages local files, including setting ownership and
|
13
15
|
permissions, creation of both files and directories, and
|
14
16
|
retrieving entire files from remote servers. As Puppet matures, it
|
@@ -173,11 +175,9 @@ module Puppet
|
|
173
175
|
recursion), and ``follow`` will manage the file to which the
|
174
176
|
link points."
|
175
177
|
|
176
|
-
newvalues(:follow, :manage
|
178
|
+
newvalues(:follow, :manage)
|
177
179
|
|
178
|
-
|
179
|
-
# but don't copy remote links
|
180
|
-
defaultto :ignore
|
180
|
+
defaultto :manage
|
181
181
|
end
|
182
182
|
|
183
183
|
newparam(:purge, :boolean => true) do
|
@@ -460,7 +460,9 @@ module Puppet
|
|
460
460
|
super
|
461
461
|
|
462
462
|
# Get rid of any duplicate slashes, and remove any trailing slashes.
|
463
|
-
@title = @title.gsub(/\/+/, "/")
|
463
|
+
@title = @title.gsub(/\/+/, "/")
|
464
|
+
|
465
|
+
@title.sub!(/\/$/, "") unless @title == "/"
|
464
466
|
|
465
467
|
# Clean out as many references to any file paths as possible.
|
466
468
|
# This was the source of many, many bugs.
|
@@ -640,7 +642,6 @@ module Puppet
|
|
640
642
|
# :file.
|
641
643
|
return nil unless child = catalog.create_implicit_resource(self.class.name, args)
|
642
644
|
rescue => detail
|
643
|
-
puts detail.backtrace
|
644
645
|
self.notice "Cannot manage: %s" % [detail]
|
645
646
|
return nil
|
646
647
|
end
|
@@ -648,7 +649,7 @@ module Puppet
|
|
648
649
|
|
649
650
|
# LAK:FIXME This shouldn't be necessary, but as long as we're
|
650
651
|
# modeling the relationship graph specifically, it is.
|
651
|
-
catalog.relationship_graph.add_edge
|
652
|
+
catalog.relationship_graph.add_edge self, child
|
652
653
|
|
653
654
|
return child
|
654
655
|
end
|
@@ -767,11 +768,8 @@ module Puppet
|
|
767
768
|
begin
|
768
769
|
File.unlink(newfile)
|
769
770
|
rescue => detail
|
770
|
-
if Puppet[:trace]
|
771
|
-
|
772
|
-
end
|
773
|
-
self.err "Could not remove old backup: %s" %
|
774
|
-
detail
|
771
|
+
puts detail.backtrace if Puppet[:trace]
|
772
|
+
self.err "Could not remove old backup: %s" % detail
|
775
773
|
return false
|
776
774
|
end
|
777
775
|
end
|
@@ -781,9 +779,7 @@ module Puppet
|
|
781
779
|
def remove_existing(should)
|
782
780
|
return unless s = stat(true)
|
783
781
|
|
784
|
-
unless handlebackup
|
785
|
-
self.fail "Could not back up; will not replace"
|
786
|
-
end
|
782
|
+
self.fail "Could not back up; will not replace" unless handlebackup
|
787
783
|
|
788
784
|
unless should.to_s == "link"
|
789
785
|
return if s.ftype.to_s == should.to_s
|
@@ -792,8 +788,7 @@ module Puppet
|
|
792
788
|
case s.ftype
|
793
789
|
when "directory":
|
794
790
|
if self[:force] == :true
|
795
|
-
debug "Removing existing directory for replacement with %s" %
|
796
|
-
should
|
791
|
+
debug "Removing existing directory for replacement with %s" % should
|
797
792
|
FileUtils.rmtree(self[:path])
|
798
793
|
else
|
799
794
|
notice "Not removing directory; use 'force' to override"
|
@@ -977,7 +972,7 @@ module Puppet
|
|
977
972
|
end
|
978
973
|
|
979
974
|
def uri2obj(source)
|
980
|
-
sourceobj = FileSource.new
|
975
|
+
sourceobj = Puppet::Type::File::FileSource.new
|
981
976
|
path = nil
|
982
977
|
unless source
|
983
978
|
devfail "Got a nil source"
|
@@ -1033,54 +1028,38 @@ module Puppet
|
|
1033
1028
|
return [sourceobj, path.sub(/\/\//, '/')]
|
1034
1029
|
end
|
1035
1030
|
|
1036
|
-
# Write out the file.
|
1037
|
-
#
|
1038
|
-
|
1039
|
-
|
1040
|
-
|
1031
|
+
# Write out the file. Requires the content to be written,
|
1032
|
+
# the property name for logging, and the checksum for validation.
|
1033
|
+
def write(content, property, checksum = nil)
|
1034
|
+
if validate = validate_checksum?
|
1035
|
+
# Use the appropriate checksum type -- md5, md5lite, etc.
|
1036
|
+
sumtype = property(:checksum).checktype
|
1037
|
+
checksum ||= "{#{sumtype}}" + property(:checksum).send(sumtype, content)
|
1038
|
+
end
|
1041
1039
|
|
1042
1040
|
remove_existing(:file)
|
1043
1041
|
|
1044
|
-
|
1045
|
-
path =
|
1046
|
-
if
|
1047
|
-
path = self[:path] + ".puppettmp"
|
1048
|
-
else
|
1049
|
-
path = self[:path]
|
1050
|
-
end
|
1051
|
-
|
1052
|
-
# As the correct user and group
|
1053
|
-
write_if_writable(File.dirname(path)) do
|
1054
|
-
f = nil
|
1055
|
-
# Open our file with the correct modes
|
1056
|
-
if mode
|
1057
|
-
Puppet::Util.withumask(000) do
|
1058
|
-
f = File.open(path,
|
1059
|
-
File::CREAT|File::WRONLY|File::TRUNC, mode)
|
1060
|
-
end
|
1061
|
-
else
|
1062
|
-
f = File.open(path, File::CREAT|File::WRONLY|File::TRUNC)
|
1063
|
-
end
|
1042
|
+
use_temporary_file = (content.length != 0)
|
1043
|
+
path = self[:path]
|
1044
|
+
path += ".puppettmp" if use_temporary_file
|
1064
1045
|
|
1065
|
-
|
1066
|
-
|
1046
|
+
mode = self.should(:mode) # might be nil
|
1047
|
+
umask = mode ? 000 : 022
|
1067
1048
|
|
1068
|
-
|
1069
|
-
f.
|
1049
|
+
Puppet::Util.withumask(umask) do
|
1050
|
+
File.open(path, File::CREAT|File::WRONLY|File::TRUNC, mode) { |f| f.print content }
|
1070
1051
|
end
|
1071
1052
|
|
1072
1053
|
# And put our new file in place
|
1073
|
-
if
|
1054
|
+
if use_temporary_file # This is only not true when our file is empty.
|
1074
1055
|
begin
|
1056
|
+
fail_if_checksum_is_wrong(path, checksum) if validate
|
1075
1057
|
File.rename(path, self[:path])
|
1076
1058
|
rescue => detail
|
1077
|
-
self.err "Could not rename tmp %s for replacing: %s" %
|
1078
|
-
[self[:path], detail]
|
1059
|
+
self.err "Could not rename tmp %s for replacing: %s" % [self[:path], detail]
|
1079
1060
|
ensure
|
1080
1061
|
# Make sure the created file gets removed
|
1081
|
-
if FileTest.exists?(path)
|
1082
|
-
File.unlink(path)
|
1083
|
-
end
|
1062
|
+
File.unlink(path) if FileTest.exists?(path)
|
1084
1063
|
end
|
1085
1064
|
end
|
1086
1065
|
|
@@ -1088,32 +1067,35 @@ module Puppet
|
|
1088
1067
|
property_fix
|
1089
1068
|
|
1090
1069
|
# And then update our checksum, so the next run doesn't find it.
|
1091
|
-
|
1092
|
-
# file back in again.
|
1093
|
-
self.setchecksum
|
1094
|
-
|
1070
|
+
self.setchecksum(checksum)
|
1095
1071
|
end
|
1096
|
-
|
1097
|
-
#
|
1098
|
-
|
1099
|
-
|
1100
|
-
|
1101
|
-
|
1102
|
-
|
1103
|
-
|
1104
|
-
# if FileTest.writable?(dir)
|
1105
|
-
# asroot = false
|
1106
|
-
# yield
|
1107
|
-
# end
|
1108
|
-
# end
|
1109
|
-
#
|
1110
|
-
# if asroot
|
1111
|
-
# yield
|
1112
|
-
# end
|
1072
|
+
|
1073
|
+
# Should we validate the checksum of the file we're writing?
|
1074
|
+
def validate_checksum?
|
1075
|
+
if sumparam = @parameters[:checksum]
|
1076
|
+
return sumparam.checktype.to_s !~ /time/
|
1077
|
+
else
|
1078
|
+
return false
|
1079
|
+
end
|
1113
1080
|
end
|
1114
1081
|
|
1115
1082
|
private
|
1116
1083
|
|
1084
|
+
# Make sure the file we wrote out is what we think it is.
|
1085
|
+
def fail_if_checksum_is_wrong(path, checksum)
|
1086
|
+
if checksum =~ /^\{(\w+)\}.+/
|
1087
|
+
sumtype = $1
|
1088
|
+
else
|
1089
|
+
# This shouldn't happen, but if it happens to, it's nicer
|
1090
|
+
# to just use a default sumtype than fail.
|
1091
|
+
sumtype = "md5"
|
1092
|
+
end
|
1093
|
+
newsum = property(:checksum).getsum(sumtype, path)
|
1094
|
+
return if newsum == checksum
|
1095
|
+
|
1096
|
+
self.fail "File written to disk did not match checksum; discarding changes (%s vs %s)" % [checksum, newsum]
|
1097
|
+
end
|
1098
|
+
|
1117
1099
|
# Override the parent method, because we don't want to generate changes
|
1118
1100
|
# when the file is missing and there is no 'ensure' state.
|
1119
1101
|
def propertychanges(currentvalues)
|
@@ -1150,20 +1132,20 @@ module Puppet
|
|
1150
1132
|
|
1151
1133
|
# the filesource class can't include the path, because the path
|
1152
1134
|
# changes for every file instance
|
1153
|
-
class FileSource
|
1135
|
+
class ::Puppet::Type::File::FileSource
|
1154
1136
|
attr_accessor :mount, :root, :server, :local
|
1155
1137
|
end
|
1156
1138
|
|
1157
1139
|
# We put all of the properties in separate files, because there are so many
|
1158
1140
|
# of them. The order these are loaded is important, because it determines
|
1159
1141
|
# the order they are in the property lit.
|
1160
|
-
require 'puppet/type/
|
1161
|
-
require 'puppet/type/
|
1162
|
-
require 'puppet/type/
|
1163
|
-
require 'puppet/type/
|
1164
|
-
require 'puppet/type/
|
1165
|
-
require 'puppet/type/
|
1166
|
-
require 'puppet/type/
|
1167
|
-
require 'puppet/type/
|
1168
|
-
require 'puppet/type/
|
1142
|
+
require 'puppet/type/file/checksum'
|
1143
|
+
require 'puppet/type/file/content' # can create the file
|
1144
|
+
require 'puppet/type/file/source' # can create the file
|
1145
|
+
require 'puppet/type/file/target' # creates a different type of file
|
1146
|
+
require 'puppet/type/file/ensure' # can create the file
|
1147
|
+
require 'puppet/type/file/owner'
|
1148
|
+
require 'puppet/type/file/group'
|
1149
|
+
require 'puppet/type/file/mode'
|
1150
|
+
require 'puppet/type/file/type'
|
1169
1151
|
end
|
@@ -0,0 +1,271 @@
|
|
1
|
+
require 'puppet/util/checksums'
|
2
|
+
|
3
|
+
# Keep a copy of the file checksums, and notify when they change. This
|
4
|
+
# property never actually modifies the system, it only notices when the system
|
5
|
+
# changes on its own.
|
6
|
+
Puppet::Type.type(:file).newproperty(:checksum) do
|
7
|
+
include Puppet::Util::Checksums
|
8
|
+
|
9
|
+
desc "How to check whether a file has changed. This state is used internally
|
10
|
+
for file copying, but it can also be used to monitor files somewhat
|
11
|
+
like Tripwire without managing the file contents in any way. You can
|
12
|
+
specify that a file's checksum should be monitored and then subscribe to
|
13
|
+
the file from another object and receive events to signify
|
14
|
+
checksum changes, for instance."
|
15
|
+
|
16
|
+
@event = :file_changed
|
17
|
+
|
18
|
+
@unmanaged = true
|
19
|
+
|
20
|
+
@validtypes = %w{md5 md5lite timestamp mtime time}
|
21
|
+
|
22
|
+
def self.validtype?(type)
|
23
|
+
@validtypes.include?(type)
|
24
|
+
end
|
25
|
+
|
26
|
+
@validtypes.each do |ctype|
|
27
|
+
newvalue(ctype) do
|
28
|
+
handlesum()
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
str = @validtypes.join("|")
|
33
|
+
|
34
|
+
# This is here because Puppet sets this internally, using
|
35
|
+
# {md5}......
|
36
|
+
newvalue(/^\{#{str}\}/) do
|
37
|
+
handlesum()
|
38
|
+
end
|
39
|
+
|
40
|
+
newvalue(:nosum) do
|
41
|
+
# nothing
|
42
|
+
:nochange
|
43
|
+
end
|
44
|
+
|
45
|
+
# If they pass us a sum type, behave normally, but if they pass
|
46
|
+
# us a sum type + sum, stick the sum in the cache.
|
47
|
+
munge do |value|
|
48
|
+
if value =~ /^\{(\w+)\}(.+)$/
|
49
|
+
type = symbolize($1)
|
50
|
+
sum = $2
|
51
|
+
cache(type, sum)
|
52
|
+
return type
|
53
|
+
else
|
54
|
+
if FileTest.directory?(@resource[:path])
|
55
|
+
return :time
|
56
|
+
else
|
57
|
+
return symbolize(value)
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
62
|
+
# Store the checksum in the data cache, or retrieve it if only the
|
63
|
+
# sum type is provided.
|
64
|
+
def cache(type, sum = nil)
|
65
|
+
unless type
|
66
|
+
raise ArgumentError, "A type must be specified to cache a checksum"
|
67
|
+
end
|
68
|
+
type = symbolize(type)
|
69
|
+
unless state = @resource.cached(:checksums)
|
70
|
+
self.debug "Initializing checksum hash"
|
71
|
+
state = {}
|
72
|
+
@resource.cache(:checksums, state)
|
73
|
+
end
|
74
|
+
|
75
|
+
if sum
|
76
|
+
unless sum =~ /\{\w+\}/
|
77
|
+
sum = "{%s}%s" % [type, sum]
|
78
|
+
end
|
79
|
+
state[type] = sum
|
80
|
+
else
|
81
|
+
return state[type]
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
# Because source and content and whomever else need to set the checksum
|
86
|
+
# and do the updating, we provide a simple mechanism for doing so.
|
87
|
+
def checksum=(value)
|
88
|
+
munge(@should)
|
89
|
+
self.updatesum(value)
|
90
|
+
end
|
91
|
+
|
92
|
+
def checktype
|
93
|
+
self.should || :md5
|
94
|
+
end
|
95
|
+
|
96
|
+
# Checksums need to invert how changes are printed.
|
97
|
+
def change_to_s(currentvalue, newvalue)
|
98
|
+
begin
|
99
|
+
if currentvalue == :absent
|
100
|
+
return "defined '%s' as '%s'" %
|
101
|
+
[self.name, self.currentsum]
|
102
|
+
elsif newvalue == :absent
|
103
|
+
return "undefined %s from '%s'" %
|
104
|
+
[self.name, self.is_to_s(currentvalue)]
|
105
|
+
else
|
106
|
+
if defined? @cached and @cached
|
107
|
+
return "%s changed '%s' to '%s'" %
|
108
|
+
[self.name, @cached, self.is_to_s(currentvalue)]
|
109
|
+
else
|
110
|
+
return "%s changed '%s' to '%s'" %
|
111
|
+
[self.name, self.currentsum, self.is_to_s(currentvalue)]
|
112
|
+
end
|
113
|
+
end
|
114
|
+
rescue Puppet::Error, Puppet::DevError
|
115
|
+
raise
|
116
|
+
rescue => detail
|
117
|
+
raise Puppet::DevError, "Could not convert change %s to string: %s" %
|
118
|
+
[self.name, detail]
|
119
|
+
end
|
120
|
+
end
|
121
|
+
|
122
|
+
def currentsum
|
123
|
+
cache(checktype())
|
124
|
+
end
|
125
|
+
|
126
|
+
# Retrieve the cached sum
|
127
|
+
def getcachedsum
|
128
|
+
hash = nil
|
129
|
+
unless hash = @resource.cached(:checksums)
|
130
|
+
hash = {}
|
131
|
+
@resource.cache(:checksums, hash)
|
132
|
+
end
|
133
|
+
|
134
|
+
sumtype = self.should
|
135
|
+
|
136
|
+
if hash.include?(sumtype)
|
137
|
+
#self.notice "Found checksum %s for %s" %
|
138
|
+
# [hash[sumtype] ,@resource[:path]]
|
139
|
+
sum = hash[sumtype]
|
140
|
+
|
141
|
+
unless sum =~ /^\{\w+\}/
|
142
|
+
sum = "{%s}%s" % [sumtype, sum]
|
143
|
+
end
|
144
|
+
return sum
|
145
|
+
elsif hash.empty?
|
146
|
+
#self.notice "Could not find sum of type %s" % sumtype
|
147
|
+
return :nosum
|
148
|
+
else
|
149
|
+
#self.notice "Found checksum for %s but not of type %s" %
|
150
|
+
# [@resource[:path],sumtype]
|
151
|
+
return :nosum
|
152
|
+
end
|
153
|
+
end
|
154
|
+
|
155
|
+
# Calculate the sum from disk.
|
156
|
+
def getsum(checktype, file = nil)
|
157
|
+
sum = ""
|
158
|
+
|
159
|
+
checktype = :mtime if checktype == :timestamp
|
160
|
+
checktype = :ctime if checktype == :time
|
161
|
+
|
162
|
+
file ||= @resource[:path]
|
163
|
+
|
164
|
+
return nil unless FileTest.exist?(file)
|
165
|
+
|
166
|
+
if ! FileTest.file?(file)
|
167
|
+
checktype = :mtime
|
168
|
+
end
|
169
|
+
method = checktype.to_s + "_file"
|
170
|
+
|
171
|
+
self.fail("Invalid checksum type %s" % checktype) unless respond_to?(method)
|
172
|
+
|
173
|
+
return "{%s}%s" % [checktype, send(method, file)]
|
174
|
+
end
|
175
|
+
|
176
|
+
# At this point, we don't actually modify the system, we modify
|
177
|
+
# the stored state to reflect the current state, and then kick
|
178
|
+
# off an event to mark any changes.
|
179
|
+
def handlesum
|
180
|
+
currentvalue = self.retrieve
|
181
|
+
if currentvalue.nil?
|
182
|
+
raise Puppet::Error, "Checksum state for %s is somehow nil" %
|
183
|
+
@resource.title
|
184
|
+
end
|
185
|
+
|
186
|
+
if self.insync?(currentvalue)
|
187
|
+
self.debug "Checksum is already in sync"
|
188
|
+
return nil
|
189
|
+
end
|
190
|
+
# If we still can't retrieve a checksum, it means that
|
191
|
+
# the file still doesn't exist
|
192
|
+
if currentvalue == :absent
|
193
|
+
# if they're copying, then we won't worry about the file
|
194
|
+
# not existing yet
|
195
|
+
unless @resource.property(:source)
|
196
|
+
self.warning("File %s does not exist -- cannot checksum" % @resource[:path])
|
197
|
+
end
|
198
|
+
return nil
|
199
|
+
end
|
200
|
+
|
201
|
+
# If the sums are different, then return an event.
|
202
|
+
if self.updatesum(currentvalue)
|
203
|
+
return :file_changed
|
204
|
+
else
|
205
|
+
return nil
|
206
|
+
end
|
207
|
+
end
|
208
|
+
|
209
|
+
def insync?(currentvalue)
|
210
|
+
@should = [checktype()]
|
211
|
+
if cache(checktype())
|
212
|
+
return currentvalue == currentsum()
|
213
|
+
else
|
214
|
+
# If there's no cached sum, then we don't want to generate
|
215
|
+
# an event.
|
216
|
+
return true
|
217
|
+
end
|
218
|
+
end
|
219
|
+
|
220
|
+
# Even though they can specify multiple checksums, the insync?
|
221
|
+
# mechanism can really only test against one, so we'll just retrieve
|
222
|
+
# the first specified sum type.
|
223
|
+
def retrieve(usecache = false)
|
224
|
+
# When the 'source' is retrieving, it passes "true" here so
|
225
|
+
# that we aren't reading the file twice in quick succession, yo.
|
226
|
+
currentvalue = currentsum()
|
227
|
+
return currentvalue if usecache and currentvalue
|
228
|
+
|
229
|
+
stat = nil
|
230
|
+
return :absent unless stat = @resource.stat
|
231
|
+
|
232
|
+
if stat.ftype == "link" and @resource[:links] != :follow
|
233
|
+
self.debug "Not checksumming symlink"
|
234
|
+
# @resource.delete(:checksum)
|
235
|
+
return currentvalue
|
236
|
+
end
|
237
|
+
|
238
|
+
# Just use the first allowed check type
|
239
|
+
currentvalue = getsum(checktype())
|
240
|
+
|
241
|
+
# If there is no sum defined, then store the current value
|
242
|
+
# into the cache, so that we're not marked as being
|
243
|
+
# out of sync. We don't want to generate an event the first
|
244
|
+
# time we get a sum.
|
245
|
+
self.updatesum(currentvalue) unless cache(checktype())
|
246
|
+
|
247
|
+
# @resource.debug "checksum state is %s" % self.is
|
248
|
+
return currentvalue
|
249
|
+
end
|
250
|
+
|
251
|
+
# Store the new sum to the state db.
|
252
|
+
def updatesum(newvalue)
|
253
|
+
result = false
|
254
|
+
|
255
|
+
# if we're replacing, vs. updating
|
256
|
+
if sum = cache(checktype())
|
257
|
+
return false if newvalue == sum
|
258
|
+
|
259
|
+
self.debug "Replacing %s checksum %s with %s" % [@resource.title, sum, newvalue]
|
260
|
+
result = true
|
261
|
+
else
|
262
|
+
@resource.debug "Creating checksum %s" % newvalue
|
263
|
+
result = false
|
264
|
+
end
|
265
|
+
|
266
|
+
# Cache the sum so the log message can be right if possible.
|
267
|
+
@cached = sum
|
268
|
+
cache(checktype(), newvalue)
|
269
|
+
return result
|
270
|
+
end
|
271
|
+
end
|