puppet 2.6.7 → 2.6.8
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 +49 -0
- data/install.rb +6 -2
- data/lib/puppet.rb +1 -1
- data/lib/puppet/application.rb +16 -8
- data/lib/puppet/application/agent.rb +2 -0
- data/lib/puppet/application/apply.rb +3 -0
- data/lib/puppet/application/master.rb +1 -1
- data/lib/puppet/configurer.rb +10 -1
- data/lib/puppet/defaults.rb +9 -0
- data/lib/puppet/file_serving/fileset.rb +1 -0
- data/lib/puppet/indirector/exec.rb +1 -2
- data/lib/puppet/indirector/report/yaml.rb +11 -0
- data/lib/puppet/node/environment.rb +1 -1
- data/lib/puppet/parameter.rb +2 -0
- data/lib/puppet/parameter/path.rb +42 -0
- data/lib/puppet/parser/compiler.rb +1 -1
- data/lib/puppet/parser/lexer.rb +3 -2
- data/lib/puppet/parser/parser_support.rb +0 -1
- data/lib/puppet/provider/exec/posix.rb +112 -0
- data/lib/puppet/provider/exec/shell.rb +17 -0
- data/lib/puppet/provider/group/groupadd.rb +3 -0
- data/lib/puppet/provider/nameservice/#directoryservice.rb# +519 -0
- data/lib/puppet/provider/package/gem.rb +2 -2
- data/lib/puppet/provider/package/macports.rb +106 -0
- data/lib/puppet/provider/service/debian.rb +6 -2
- data/lib/puppet/rails/inventory_node.rb +5 -0
- data/lib/puppet/reference/#providers.rb# +123 -0
- data/lib/puppet/resource/type_collection.rb +6 -1
- data/lib/puppet/simple_graph.rb +1 -1
- data/lib/puppet/transaction.rb +1 -1
- data/lib/puppet/transaction/report.rb +28 -10
- data/lib/puppet/type/cron.rb +3 -1
- data/lib/puppet/type/exec.rb +30 -167
- data/lib/puppet/type/file.rb +12 -1
- data/lib/puppet/type/file/source.rb +1 -0
- data/lib/puppet/type/group.rb +11 -1
- data/lib/puppet/type/service.rb +19 -11
- data/lib/puppet/util/command_line.rb +15 -12
- data/lib/puppet/util/command_line/puppetrun +0 -1
- data/lib/puppet/util/loadedfile.rb +1 -5
- data/lib/puppet/util/metric.rb +3 -5
- data/lib/puppet/util/plugins.rb +82 -0
- data/spec/integration/configurer_spec.rb +38 -5
- data/spec/integration/transaction_spec.rb +43 -42
- data/spec/lib/puppet_spec/verbose.rb +9 -0
- data/spec/shared_behaviours/path_parameters.rb +185 -0
- data/spec/spec_helper.rb +6 -0
- data/spec/unit/application/agent_spec.rb +7 -0
- data/spec/unit/application/apply_spec.rb +6 -0
- data/spec/unit/application/master_spec.rb +2 -2
- data/spec/unit/configurer_spec.rb +48 -0
- data/spec/unit/file_serving/fileset_spec.rb +8 -0
- data/spec/unit/indirector/certificate_status/#file_spec.rb# +188 -0
- data/spec/unit/indirector/exec_spec.rb +2 -3
- data/spec/unit/indirector/facts/inventory_active_record_spec.rb +5 -1
- data/spec/unit/indirector/report/yaml_spec.rb +38 -0
- data/spec/unit/node/environment_spec.rb +15 -14
- data/spec/unit/parameter/path_spec.rb +24 -0
- data/spec/unit/parser/compiler_spec.rb +1 -2
- data/spec/unit/parser/lexer_spec.rb +12 -0
- data/spec/unit/provider/exec/posix_spec.rb +120 -0
- data/spec/unit/provider/exec/shell_spec.rb +50 -0
- data/spec/unit/provider/group/groupadd_spec.rb +11 -1
- data/spec/unit/provider/package/gem_spec.rb +11 -1
- data/spec/unit/provider/package/macports_spec.rb +122 -0
- data/spec/unit/provider/service/debian_spec.rb +14 -2
- data/spec/unit/resource/#type_collection_spec.rb# +463 -0
- data/spec/unit/resource/type_collection_spec.rb +21 -17
- data/spec/unit/transaction/report_spec.rb +13 -2
- data/spec/unit/type/cron_spec.rb +466 -18
- data/spec/unit/type/exec_spec.rb +633 -106
- data/spec/unit/type/file/source_spec.rb +1 -0
- data/spec/unit/type/group_spec.rb +8 -1
- data/spec/unit/type_spec.rb +1 -1
- data/spec/unit/util/loadedfile_spec.rb +7 -0
- data/spec/unit/util/rdoc/parser_spec.rb +2 -1
- data/tasks/rake/git_workflow.rake +3 -1
- data/test/ral/type/exec.rb +87 -176
- metadata +21 -5
- data/lib/puppet/provider/package/darwinport.rb +0 -86
data/lib/puppet/type/file.rb
CHANGED
@@ -122,7 +122,18 @@ Puppet::Type.newtype(:file) do
|
|
122
122
|
|
123
123
|
newparam(:recurse) do
|
124
124
|
desc "Whether and how deeply to do recursive
|
125
|
-
management.
|
125
|
+
management. Options are:
|
126
|
+
|
127
|
+
* `inf,true` --- Regular style recursion on both remote and local
|
128
|
+
directory structure.
|
129
|
+
* `remote` --- Descends recursively into the remote directory
|
130
|
+
but not the local directory. Allows copying of
|
131
|
+
a few files into a directory containing many
|
132
|
+
unmanaged files without scanning all the local files.
|
133
|
+
* `false` --- Default of no recursion.
|
134
|
+
* `[0-9]+` --- Same as true, but limit recursion. Warning: this syntax
|
135
|
+
has been deprecated in favor of the `recurselimit` attribute.
|
136
|
+
"
|
126
137
|
|
127
138
|
newvalues(:true, :false, :inf, :remote, /^[0-9]+$/)
|
128
139
|
|
@@ -114,6 +114,7 @@ module Puppet
|
|
114
114
|
param_name = (metadata_method == :checksum) ? :content : metadata_method
|
115
115
|
next if metadata_method == :owner and !Puppet.features.root?
|
116
116
|
next if metadata_method == :checksum and metadata.ftype == "directory"
|
117
|
+
next if metadata_method == :checksum and metadata.ftype == "link" and metadata.links == :manage
|
117
118
|
|
118
119
|
if resource[param_name].nil? or resource[param_name] == :absent
|
119
120
|
resource[param_name] = metadata.send(metadata_method)
|
data/lib/puppet/type/group.rb
CHANGED
@@ -1,4 +1,3 @@
|
|
1
|
-
|
2
1
|
require 'etc'
|
3
2
|
require 'facter'
|
4
3
|
|
@@ -15,6 +14,9 @@ module Puppet
|
|
15
14
|
feature :manages_members,
|
16
15
|
"For directories where membership is an attribute of groups not users."
|
17
16
|
|
17
|
+
feature :system_groups,
|
18
|
+
"The provider allows you to create system groups with lower GIDs."
|
19
|
+
|
18
20
|
ensurable do
|
19
21
|
desc "Create or remove the group."
|
20
22
|
|
@@ -95,5 +97,13 @@ module Puppet
|
|
95
97
|
|
96
98
|
defaultto false
|
97
99
|
end
|
100
|
+
|
101
|
+
newparam(:system, :boolean => true) do
|
102
|
+
desc "Whether the group is a system group with lower GID."
|
103
|
+
|
104
|
+
newvalues(:true, :false)
|
105
|
+
|
106
|
+
defaultto false
|
107
|
+
end
|
98
108
|
end
|
99
109
|
end
|
data/lib/puppet/type/service.rb
CHANGED
@@ -8,19 +8,24 @@ module Puppet
|
|
8
8
|
|
9
9
|
newtype(:service) do
|
10
10
|
@doc = "Manage running services. Service support unfortunately varies
|
11
|
-
widely by platform
|
11
|
+
widely by platform --- some platforms have very little if any
|
12
12
|
concept of a running service, and some have a very codified and
|
13
13
|
powerful concept. Puppet's service support will generally be able
|
14
|
-
to
|
14
|
+
to do the right thing regardless (e.g., if there is no
|
15
15
|
'status' command, then Puppet will look in the process table for a
|
16
16
|
command matching the service name), but the more information you
|
17
|
-
can provide the better behaviour you will get.
|
18
|
-
|
17
|
+
can provide, the better behaviour you will get. In particular, any
|
18
|
+
virtual services that don't have a predictable entry in the process table
|
19
|
+
(for example, `network` on Red Hat/CentOS systems) will manifest odd
|
20
|
+
behavior on restarts if you don't specify `hasstatus` or a `status`
|
21
|
+
command.
|
19
22
|
|
20
23
|
Note that if a `service` receives an event from another resource,
|
21
24
|
the service will get restarted. The actual command to restart the
|
22
|
-
service depends on the platform. You can provide
|
23
|
-
for restarting with the `restart` attribute
|
25
|
+
service depends on the platform. You can provide an explicit command
|
26
|
+
for restarting with the `restart` attribute, or use the init script's
|
27
|
+
restart command with the `hasrestart` attribute; if you do neither,
|
28
|
+
the service's stop and start commands will be used."
|
24
29
|
|
25
30
|
feature :refreshable, "The provider can restart the service.",
|
26
31
|
:methods => [:restart]
|
@@ -93,11 +98,14 @@ module Puppet
|
|
93
98
|
that a large number of init scripts on different platforms do
|
94
99
|
not support any kind of status command; thus, you must specify
|
95
100
|
manually whether the service you are running has such a
|
96
|
-
command
|
97
|
-
`status`
|
98
|
-
|
99
|
-
If you
|
100
|
-
|
101
|
+
command. Alternately, you can provide a specific command using the
|
102
|
+
`status` attribute.
|
103
|
+
|
104
|
+
If you specify neither of these, then Puppet will look for the
|
105
|
+
service name in the process table. Be aware that 'virtual' init
|
106
|
+
scripts such as networking will respond poorly to refresh events
|
107
|
+
(via notify and subscribe relationships) if you don't override
|
108
|
+
this default behavior."
|
101
109
|
|
102
110
|
newvalues(:true, :false)
|
103
111
|
end
|
@@ -1,9 +1,10 @@
|
|
1
|
+
require "puppet/util/plugins"
|
2
|
+
|
1
3
|
module Puppet
|
2
4
|
module Util
|
3
5
|
class CommandLine
|
4
6
|
|
5
|
-
|
6
|
-
{
|
7
|
+
LegacyName = Hash.new{|h,k| k}.update(
|
7
8
|
'agent' => 'puppetd',
|
8
9
|
'cert' => 'puppetca',
|
9
10
|
'doc' => 'puppetdoc',
|
@@ -13,9 +14,8 @@ module Puppet
|
|
13
14
|
'queue' => 'puppetqd',
|
14
15
|
'resource' => 'ralsh',
|
15
16
|
'kick' => 'puppetrun',
|
16
|
-
'master' => 'puppetmasterd'
|
17
|
-
|
18
|
-
})
|
17
|
+
'master' => 'puppetmasterd'
|
18
|
+
)
|
19
19
|
|
20
20
|
def initialize( zero = $0, argv = ARGV, stdin = STDIN )
|
21
21
|
@zero = zero
|
@@ -23,6 +23,7 @@ module Puppet
|
|
23
23
|
@stdin = stdin
|
24
24
|
|
25
25
|
@subcommand_name, @args = subcommand_and_args( @zero, @argv, @stdin )
|
26
|
+
Puppet::Plugins.on_commandline_initialization(:command_line_object => self)
|
26
27
|
end
|
27
28
|
|
28
29
|
attr :subcommand_name
|
@@ -56,21 +57,23 @@ module Puppet
|
|
56
57
|
puts usage_message
|
57
58
|
elsif available_subcommands.include?(subcommand_name) #subcommand
|
58
59
|
require_application subcommand_name
|
59
|
-
Puppet::Application.find(subcommand_name).new(self)
|
60
|
+
app = Puppet::Application.find(subcommand_name).new(self)
|
61
|
+
Puppet::Plugins.on_application_initialization(:appliation_object => self)
|
62
|
+
app.run
|
60
63
|
else
|
61
64
|
abort "Error: Unknown command #{subcommand_name}.\n#{usage_message}" unless execute_external_subcommand
|
62
65
|
end
|
63
66
|
end
|
64
67
|
|
65
68
|
def execute_external_subcommand
|
66
|
-
|
69
|
+
external_command = "puppet-#{subcommand_name}"
|
67
70
|
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
+
require 'puppet/util'
|
72
|
+
path_to_subcommand = Puppet::Util.which( external_command )
|
73
|
+
return false unless path_to_subcommand
|
71
74
|
|
72
|
-
|
73
|
-
|
75
|
+
system( path_to_subcommand, *args )
|
76
|
+
true
|
74
77
|
end
|
75
78
|
|
76
79
|
def legacy_executable_name
|
@@ -34,10 +34,6 @@ module Puppet
|
|
34
34
|
# Create the file. Must be passed the file path.
|
35
35
|
def initialize(file)
|
36
36
|
@file = file
|
37
|
-
unless FileTest.exists?(@file)
|
38
|
-
raise Puppet::NoSuchFile,
|
39
|
-
"Can not use a non-existent file for parsing"
|
40
|
-
end
|
41
37
|
@statted = 0
|
42
38
|
@stamp = nil
|
43
39
|
@tstamp = stamp
|
@@ -50,7 +46,7 @@ module Puppet
|
|
50
46
|
@statted = Time.now.to_i
|
51
47
|
begin
|
52
48
|
@stamp = File.stat(@file).ctime
|
53
|
-
rescue Errno::ENOENT
|
49
|
+
rescue Errno::ENOENT, Errno::ENOTDIR
|
54
50
|
@stamp = Time.now
|
55
51
|
end
|
56
52
|
end
|
data/lib/puppet/util/metric.rb
CHANGED
@@ -122,7 +122,7 @@ class Puppet::Util::Metric
|
|
122
122
|
def initialize(name,label = nil)
|
123
123
|
@name = name.to_s
|
124
124
|
|
125
|
-
@label = label || labelize(name)
|
125
|
+
@label = label || self.class.labelize(name)
|
126
126
|
|
127
127
|
@values = []
|
128
128
|
end
|
@@ -133,7 +133,7 @@ class Puppet::Util::Metric
|
|
133
133
|
|
134
134
|
def newvalue(name,value,label = nil)
|
135
135
|
raise ArgumentError.new("metric name #{name.inspect} is not a string") unless name.is_a? String
|
136
|
-
label ||= labelize(name)
|
136
|
+
label ||= self.class.labelize(name)
|
137
137
|
@values.push [name,label,value]
|
138
138
|
end
|
139
139
|
|
@@ -174,10 +174,8 @@ class Puppet::Util::Metric
|
|
174
174
|
@values.sort { |a, b| a[1] <=> b[1] }
|
175
175
|
end
|
176
176
|
|
177
|
-
private
|
178
|
-
|
179
177
|
# Convert a name into a label.
|
180
|
-
def labelize(name)
|
178
|
+
def self.labelize(name)
|
181
179
|
name.to_s.capitalize.gsub("_", " ")
|
182
180
|
end
|
183
181
|
end
|
@@ -0,0 +1,82 @@
|
|
1
|
+
#
|
2
|
+
# This system manages an extensible set of metadata about plugins which it
|
3
|
+
# collects by searching for files named "plugin_init.rb" in a series of
|
4
|
+
# directories. Initially, these are simply the $LOAD_PATH.
|
5
|
+
#
|
6
|
+
# The contents of each file found is executed in the context of a Puppet::Plugins
|
7
|
+
# object (and thus scoped). An example file might contain:
|
8
|
+
#
|
9
|
+
# -------------------------------------------------------
|
10
|
+
# @name = "Greet the CA"
|
11
|
+
#
|
12
|
+
# @description = %q{
|
13
|
+
# This plugin causes a friendly greeting to print out on a master
|
14
|
+
# that is operating as the CA, after it has been set up but before
|
15
|
+
# it does anything.
|
16
|
+
# }
|
17
|
+
#
|
18
|
+
# def after_application_setup(options)
|
19
|
+
# if options[:application_object].is_a?(Puppet::Application::Master) && Puppet::SSL::CertificateAuthority.ca?
|
20
|
+
# puts "Hey, this is the CA!"
|
21
|
+
# end
|
22
|
+
# end
|
23
|
+
# -------------------------------------------------------
|
24
|
+
#
|
25
|
+
# Note that the instance variables are local to this Puppet::Plugin (and so may be used
|
26
|
+
# for maintaining state, etc.) but the plugin system does not provide any thread safety
|
27
|
+
# assurances, so they may not be adequate for some complex use cases.
|
28
|
+
#
|
29
|
+
#
|
30
|
+
module Puppet
|
31
|
+
class Plugins
|
32
|
+
Paths = [] # Where we might find plugin initialization code
|
33
|
+
Loaded = [] # Code we have found (one-to-one with paths once searched)
|
34
|
+
#
|
35
|
+
# Return all the Puppet::Plugins we know about, searching any new paths
|
36
|
+
#
|
37
|
+
def self.known
|
38
|
+
Paths[Loaded.length...Paths.length].each { |path|
|
39
|
+
file = File.join(path,'plugin_init.rb')
|
40
|
+
Loaded << (File.exist?(file) && new(file))
|
41
|
+
}
|
42
|
+
Loaded.compact
|
43
|
+
end
|
44
|
+
#
|
45
|
+
# Add more places to look for plugins without adding duplicates or changing the
|
46
|
+
# order of ones we've already found.
|
47
|
+
#
|
48
|
+
def self.look_in(*paths)
|
49
|
+
Paths.replace Paths | paths.flatten.collect { |path| File.expand_path(path) }
|
50
|
+
end
|
51
|
+
#
|
52
|
+
# Initially just look in $LOAD_PATH
|
53
|
+
#
|
54
|
+
look_in $LOAD_PATH
|
55
|
+
#
|
56
|
+
# Calling methods (hooks) on the class calls the method of the same name on
|
57
|
+
# all plugins that use that hook, passing in the same arguments to each
|
58
|
+
# and returning an array containing the results returned by each plugin as
|
59
|
+
# an array of [plugin_name,result] pairs.
|
60
|
+
#
|
61
|
+
def self.method_missing(hook,*args,&block)
|
62
|
+
known.
|
63
|
+
select { |p| p.respond_to? hook }.
|
64
|
+
collect { |p| [p.name,p.send(hook,*args,&block)] }
|
65
|
+
end
|
66
|
+
#
|
67
|
+
#
|
68
|
+
#
|
69
|
+
attr_reader :path,:name
|
70
|
+
def initialize(path)
|
71
|
+
@name = @path = path
|
72
|
+
class << self
|
73
|
+
private
|
74
|
+
def define_hooks
|
75
|
+
eval File.read(path),nil,path,1
|
76
|
+
end
|
77
|
+
end
|
78
|
+
define_hooks
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
@@ -5,6 +5,8 @@ require File.dirname(__FILE__) + '/../spec_helper'
|
|
5
5
|
require 'puppet/configurer'
|
6
6
|
|
7
7
|
describe Puppet::Configurer do
|
8
|
+
include PuppetSpec::Files
|
9
|
+
|
8
10
|
describe "when downloading plugins" do
|
9
11
|
it "should use the :pluginsignore setting, split on whitespace, for ignoring remote files" do
|
10
12
|
resource = Puppet::Type.type(:notify).new :name => "yay"
|
@@ -17,19 +19,50 @@ describe Puppet::Configurer do
|
|
17
19
|
end
|
18
20
|
|
19
21
|
describe "when running" do
|
20
|
-
|
21
|
-
catalog = Puppet::Resource::Catalog.new
|
22
|
-
catalog.add_resource(Puppet::Type.type(:notify).new(:title => "testing"))
|
22
|
+
before(:each) do
|
23
|
+
@catalog = Puppet::Resource::Catalog.new
|
24
|
+
@catalog.add_resource(Puppet::Type.type(:notify).new(:title => "testing"))
|
23
25
|
|
24
|
-
|
26
|
+
# Make sure we don't try to persist the local state after the transaction ran,
|
27
|
+
# because it will fail during test (the state file is in an not existing directory)
|
28
|
+
# and we need the transaction to be successful to be able to produce a summary report
|
29
|
+
@catalog.host_config = false
|
30
|
+
|
31
|
+
@configurer = Puppet::Configurer.new
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should send a transaction report with valid data" do
|
25
35
|
|
36
|
+
@configurer.stubs(:save_last_run_summary)
|
26
37
|
Puppet::Transaction::Report.indirection.expects(:save).with do |x, report|
|
27
38
|
report.time.class == Time and report.logs.length > 0
|
28
39
|
end
|
29
40
|
|
30
41
|
Puppet[:report] = true
|
31
42
|
|
32
|
-
configurer.run :catalog => catalog
|
43
|
+
@configurer.run :catalog => @catalog
|
44
|
+
end
|
45
|
+
|
46
|
+
it "should save a correct last run summary" do
|
47
|
+
report = Puppet::Transaction::Report.new("apply")
|
48
|
+
report.stubs(:save)
|
49
|
+
|
50
|
+
Puppet[:lastrunfile] = tmpfile("lastrunfile")
|
51
|
+
Puppet[:report] = true
|
52
|
+
|
53
|
+
@configurer.run :catalog => @catalog, :report => report
|
54
|
+
|
55
|
+
summary = nil
|
56
|
+
File.open(Puppet[:lastrunfile], "r") do |fd|
|
57
|
+
summary = YAML.load(fd.read)
|
58
|
+
end
|
59
|
+
|
60
|
+
summary.should be_a(Hash)
|
61
|
+
%w{time changes events resources}.each do |key|
|
62
|
+
summary.should be_key(key)
|
63
|
+
end
|
64
|
+
summary["time"].should be_key("notify")
|
65
|
+
summary["time"]["last_run"].should >= Time.now.tv_sec
|
33
66
|
end
|
34
67
|
end
|
35
68
|
end
|
@@ -107,29 +107,23 @@ describe Puppet::Transaction do
|
|
107
107
|
file1 = tmpfile("file1")
|
108
108
|
file2 = tmpfile("file2")
|
109
109
|
|
110
|
-
|
111
|
-
|
112
|
-
:path => path,
|
113
|
-
|
110
|
+
file = Puppet::Type.type(:file).new(
|
111
|
+
:path => path,
|
114
112
|
:ensure => "file"
|
115
113
|
)
|
116
114
|
|
117
|
-
|
118
|
-
|
119
|
-
:path => ENV["PATH"],
|
115
|
+
exec1 = Puppet::Type.type(:exec).new(
|
116
|
+
:path => ENV["PATH"],
|
120
117
|
:command => "touch #{file1}",
|
121
118
|
:refreshonly => true,
|
122
|
-
|
123
|
-
:subscribe => Puppet::Resource.new(:file, path)
|
119
|
+
:subscribe => Puppet::Resource.new(:file, path)
|
124
120
|
)
|
125
121
|
|
126
|
-
|
127
|
-
|
128
|
-
:
|
129
|
-
:command => "touch #{file2}",
|
122
|
+
exec2 = Puppet::Type.type(:exec).new(
|
123
|
+
:path => ENV["PATH"],
|
124
|
+
:command => "touch #{file2}",
|
130
125
|
:refreshonly => true,
|
131
|
-
|
132
|
-
:subscribe => Puppet::Resource.new(:file, path)
|
126
|
+
:subscribe => Puppet::Resource.new(:file, path)
|
133
127
|
)
|
134
128
|
|
135
129
|
catalog = mk_catalog(file, exec1, exec2)
|
@@ -141,33 +135,26 @@ describe Puppet::Transaction do
|
|
141
135
|
it "should not let one failed refresh result in other refreshes failing" do
|
142
136
|
path = tmpfile("path")
|
143
137
|
newfile = tmpfile("file")
|
144
|
-
|
145
|
-
file = Puppet::Type.type(:file).new(
|
146
|
-
|
138
|
+
file = Puppet::Type.type(:file).new(
|
147
139
|
:path => path,
|
148
|
-
|
149
140
|
:ensure => "file"
|
150
141
|
)
|
151
142
|
|
152
|
-
|
153
|
-
|
143
|
+
exec1 = Puppet::Type.type(:exec).new(
|
154
144
|
:path => ENV["PATH"],
|
155
145
|
:command => "touch /this/cannot/possibly/exist",
|
156
146
|
:logoutput => true,
|
157
147
|
:refreshonly => true,
|
158
148
|
:subscribe => file,
|
159
|
-
|
160
149
|
:title => "one"
|
161
150
|
)
|
162
151
|
|
163
|
-
|
164
|
-
|
152
|
+
exec2 = Puppet::Type.type(:exec).new(
|
165
153
|
:path => ENV["PATH"],
|
166
154
|
:command => "touch #{newfile}",
|
167
155
|
:logoutput => true,
|
168
156
|
:refreshonly => true,
|
169
157
|
:subscribe => [file, exec1],
|
170
|
-
|
171
158
|
:title => "two"
|
172
159
|
)
|
173
160
|
|
@@ -184,22 +171,18 @@ describe Puppet::Transaction do
|
|
184
171
|
|
185
172
|
Puppet[:ignoreschedules] = false
|
186
173
|
|
187
|
-
|
188
|
-
|
174
|
+
file = Puppet::Type.type(:file).new(
|
189
175
|
:name => tmpfile("file"),
|
190
|
-
|
191
176
|
:ensure => "file",
|
192
177
|
:backup => false
|
193
178
|
)
|
194
179
|
|
195
180
|
fname = tmpfile("exec")
|
196
181
|
|
197
|
-
|
198
|
-
|
182
|
+
exec = Puppet::Type.type(:exec).new(
|
199
183
|
:name => "touch #{fname}",
|
200
184
|
:path => "/usr/bin:/bin",
|
201
185
|
:schedule => "monthly",
|
202
|
-
|
203
186
|
:subscribe => Puppet::Resource.new("file", file.name)
|
204
187
|
)
|
205
188
|
|
@@ -236,29 +219,21 @@ describe Puppet::Transaction do
|
|
236
219
|
|
237
220
|
it "should not attempt to evaluate resources with failed dependencies" do
|
238
221
|
|
239
|
-
|
240
|
-
|
222
|
+
exec = Puppet::Type.type(:exec).new(
|
241
223
|
:command => "/bin/mkdir /this/path/cannot/possibly/exit",
|
242
|
-
|
243
224
|
:title => "mkdir"
|
244
225
|
)
|
245
226
|
|
246
|
-
|
247
|
-
file1 = Puppet::Type.type(:file).new(
|
248
|
-
|
227
|
+
file1 = Puppet::Type.type(:file).new(
|
249
228
|
:title => "file1",
|
250
229
|
:path => tmpfile("file1"),
|
251
|
-
|
252
230
|
:require => exec,
|
253
231
|
:ensure => :file
|
254
232
|
)
|
255
233
|
|
256
|
-
|
257
|
-
file2 = Puppet::Type.type(:file).new(
|
258
|
-
|
234
|
+
file2 = Puppet::Type.type(:file).new(
|
259
235
|
:title => "file2",
|
260
236
|
:path => tmpfile("file2"),
|
261
|
-
|
262
237
|
:require => file1,
|
263
238
|
:ensure => :file
|
264
239
|
)
|
@@ -270,6 +245,32 @@ describe Puppet::Transaction do
|
|
270
245
|
FileTest.should_not be_exists(file2[:path])
|
271
246
|
end
|
272
247
|
|
248
|
+
it "should not trigger subscribing resources on failure" do
|
249
|
+
file1 = tmpfile("file1")
|
250
|
+
file2 = tmpfile("file2")
|
251
|
+
|
252
|
+
create_file1 = Puppet::Type.type(:exec).new(
|
253
|
+
:command => "/usr/bin/touch #{file1}"
|
254
|
+
)
|
255
|
+
|
256
|
+
exec = Puppet::Type.type(:exec).new(
|
257
|
+
:command => "/bin/mkdir /this/path/cannot/possibly/exit",
|
258
|
+
:title => "mkdir",
|
259
|
+
:notify => create_file1
|
260
|
+
)
|
261
|
+
|
262
|
+
create_file2 = Puppet::Type.type(:exec).new(
|
263
|
+
:command => "/usr/bin/touch #{file2}",
|
264
|
+
:subscribe => exec
|
265
|
+
)
|
266
|
+
|
267
|
+
catalog = mk_catalog(exec, create_file1, create_file2)
|
268
|
+
catalog.apply
|
269
|
+
|
270
|
+
FileTest.should_not be_exists(file1)
|
271
|
+
FileTest.should_not be_exists(file2)
|
272
|
+
end
|
273
|
+
|
273
274
|
# #801 -- resources only checked in noop should be rescheduled immediately.
|
274
275
|
it "should immediately reschedule noop resources" do
|
275
276
|
Puppet::Type.type(:schedule).mkdefaultschedules
|