puppet 3.2.0.rc1 → 3.2.0.rc2

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/Gemfile CHANGED
@@ -4,7 +4,7 @@ def location_for(place, fake_version = nil)
4
4
  if place =~ /^(git:[^#]*)#(.*)/
5
5
  [fake_version, { :git => $1, :branch => $2, :require => false }].compact
6
6
  elsif place =~ /^file:\/\/(.*)/
7
- [fake_version, { :path => File.expand_path($1), :require => false }].compact
7
+ ['>= 0', { :path => File.expand_path($1), :require => false }]
8
8
  else
9
9
  [place, { :require => false }]
10
10
  end
@@ -18,13 +18,13 @@ platforms :ruby do
18
18
  gem "racc", "~> 1.4", :group => :development
19
19
  end
20
20
 
21
- gem "puppet", *location_for("file://#{File.dirname(__FILE__)}", '99.0.0')
21
+ gem "puppet", :path => File.dirname(__FILE__), :require => false
22
22
  gem "facter", *location_for(ENV['FACTER_LOCATION'] || '~> 1.6')
23
- gem "hiera", *location_for(ENV['HIERA_LOCATION'] || '~> 1.0', '99.0.0')
23
+ gem "hiera", *location_for(ENV['HIERA_LOCATION'] || '~> 1.0')
24
24
  gem "rake", :require => false
25
25
  gem "rspec", "~> 2.11.0", :require => false
26
26
  gem "mocha", "~> 0.10.5", :require => false
27
- gem "rgen", "0.6.1", :require => false
27
+ gem "rgen", "0.6.2", :require => false
28
28
 
29
29
  gem "yarjuf", "~> 1.0"
30
30
 
@@ -27,7 +27,7 @@ class Puppet::Application::Apply < Puppet::Application
27
27
  end
28
28
  end
29
29
 
30
- option("--parseonly") do
30
+ option("--parseonly") do |args|
31
31
  puts "--parseonly has been removed. Please use 'puppet parser validate <manifest>'"
32
32
  exit 1
33
33
  end
@@ -23,7 +23,7 @@ class Puppet::Application::Master < Puppet::Application
23
23
  end
24
24
  end
25
25
 
26
- option("--parseonly") do
26
+ option("--parseonly") do |args|
27
27
  puts "--parseonly has been removed. Please use 'puppet parser validate <manifest>'"
28
28
  exit 1
29
29
  end
@@ -144,6 +144,8 @@ class Puppet::Daemon
144
144
 
145
145
  # Finally, loop forever running events - or, at least, until we exit.
146
146
  run_event_loop
147
+
148
+ server.wait_for_shutdown if server
147
149
  end
148
150
 
149
151
  def run_event_loop
@@ -1095,6 +1095,13 @@ EOT
1095
1095
  on every run. Puppet can be run with this enabled by default and then selectively
1096
1096
  disabled when a recompile is desired.",
1097
1097
  },
1098
+ :ignoremissingtypes => {
1099
+ :default => false,
1100
+ :type => :boolean,
1101
+ :desc => "Skip searching for classes and definitions that were missing during a
1102
+ prior compilation. The list of missing objects is maintained per-environment and
1103
+ persists until the environment is cleared or the master is restarted.",
1104
+ },
1098
1105
  :ignorecache => {
1099
1106
  :default => false,
1100
1107
  :type => :boolean,
@@ -24,36 +24,6 @@ class Puppet::FileServing::Fileset
24
24
  result
25
25
  end
26
26
 
27
- # Return a list of all files in our fileset. This is different from the
28
- # normal definition of find in that we support specific levels
29
- # of recursion, which means we need to know when we're going another
30
- # level deep, which Find doesn't do.
31
- def files
32
- files = perform_recursion
33
-
34
- # Now strip off the leading path, so each file becomes relative, and remove
35
- # any slashes that might end up at the beginning of the path.
36
- result = files.collect { |file| file.sub(%r{^#{Regexp.escape(@path)}/*}, '') }
37
-
38
- # And add the path itself.
39
- result.unshift(".")
40
-
41
- result
42
- end
43
-
44
- # Should we ignore this path?
45
- def ignore?(path)
46
- return false if @ignore == [nil]
47
-
48
- # 'detect' normally returns the found result, whereas we just want true/false.
49
- ! @ignore.detect { |pattern| File.fnmatch?(pattern, path) }.nil?
50
- end
51
-
52
- def ignore=(values)
53
- values = [values] unless values.is_a?(Array)
54
- @ignore = values
55
- end
56
-
57
27
  def initialize(path, options = {})
58
28
  if Puppet.features.microsoft_windows?
59
29
  # REMIND: UNC path
@@ -66,8 +36,8 @@ class Puppet::FileServing::Fileset
66
36
  @path = path
67
37
 
68
38
  # Set our defaults.
69
- @ignore = []
70
- @links = :manage
39
+ self.ignore = []
40
+ self.links = :manage
71
41
  @recurse = false
72
42
  @recurselimit = :infinite
73
43
 
@@ -77,23 +47,40 @@ class Puppet::FileServing::Fileset
77
47
  initialize_from_hash(options)
78
48
  end
79
49
 
80
- raise ArgumentError.new("Fileset paths must exist") unless stat = stat(path)
50
+ raise ArgumentError.new("Fileset paths must exist") unless valid?(path)
81
51
  raise ArgumentError.new("Fileset recurse parameter must not be a number anymore, please use recurselimit") if @recurse.is_a?(Integer)
82
52
  end
83
53
 
54
+ # Return a list of all files in our fileset. This is different from the
55
+ # normal definition of find in that we support specific levels
56
+ # of recursion, which means we need to know when we're going another
57
+ # level deep, which Find doesn't do.
58
+ def files
59
+ files = perform_recursion
60
+
61
+ # Now strip off the leading path, so each file becomes relative, and remove
62
+ # any slashes that might end up at the beginning of the path.
63
+ result = files.collect { |file| file.sub(%r{^#{Regexp.escape(@path)}/*}, '') }
64
+
65
+ # And add the path itself.
66
+ result.unshift(".")
67
+
68
+ result
69
+ end
70
+
71
+ def ignore=(values)
72
+ values = [values] unless values.is_a?(Array)
73
+ @ignore = values
74
+ end
75
+
84
76
  def links=(links)
85
77
  links = links.to_sym
86
78
  raise(ArgumentError, "Invalid :links value '#{links}'") unless [:manage, :follow].include?(links)
87
79
  @links = links
88
- @stat_method = links == :manage ? :lstat : :stat
80
+ @stat_method = File.method(@links == :manage ? :lstat : :stat)
89
81
  end
90
82
 
91
- # Should we recurse further? This is basically a single
92
- # place for all of the logic around recursion.
93
- def recurse?(depth)
94
- # recurse if told to, and infinite recursion or current depth not at the limit
95
- self.recurse and (self.recurselimit == :infinite or depth <= self.recurselimit)
96
- end
83
+ private
97
84
 
98
85
  def initialize_from_hash(options)
99
86
  options.each do |option, value|
@@ -121,61 +108,65 @@ class Puppet::FileServing::Fileset
121
108
  end
122
109
  end
123
110
 
124
- private
125
-
126
- # Pull the recursion logic into one place. It's moderately hairy, and this
127
- # allows us to keep the hairiness apart from what we do with the files.
128
- def perform_recursion
129
- # Start out with just our base directory.
130
- current_dirs = [@path]
111
+ FileSetEntry = Struct.new(:depth, :path, :ignored, :stat_method) do
112
+ def down_level(to)
113
+ FileSetEntry.new(depth + 1, File.join(path, to), ignored, stat_method)
114
+ end
131
115
 
132
- next_dirs = []
116
+ def basename
117
+ File.basename(path)
118
+ end
133
119
 
134
- depth = 1
120
+ def children
121
+ return [] unless directory?
135
122
 
136
- result = []
137
- return result unless recurse?(depth)
123
+ Dir.entries(path).
124
+ reject { |child| ignore?(child) }.
125
+ collect { |child| down_level(child) }
126
+ end
138
127
 
139
- while dir_path = current_dirs.shift
140
- next unless stat = stat(dir_path)
141
- next unless stat.directory?
128
+ def ignore?(child)
129
+ return true if child == "." || child == ".."
130
+ return false if ignored == [nil]
142
131
 
143
- Dir.entries(dir_path).each do |file_path|
144
- next if [".", ".."].include?(file_path)
132
+ ignored.any? { |pattern| File.fnmatch?(pattern, child) }
133
+ end
145
134
 
146
- # Note that this also causes matching directories not
147
- # to be recursed into.
148
- next if ignore?(file_path)
135
+ def directory?
136
+ stat_method.call(path).directory?
137
+ rescue Errno::ENOENT, Errno::EACCES
138
+ false
139
+ end
140
+ end
149
141
 
150
- # Add it to our list of files to return
151
- result << File.join(dir_path, file_path)
142
+ # Pull the recursion logic into one place. It's moderately hairy, and this
143
+ # allows us to keep the hairiness apart from what we do with the files.
144
+ def perform_recursion
145
+ current_dirs = [FileSetEntry.new(0, @path, @ignore, @stat_method)]
152
146
 
153
- # And to our list of files/directories to iterate over.
154
- next_dirs << File.join(dir_path, file_path)
155
- end
147
+ result = []
156
148
 
157
- # Move to the next recusion level
158
- if current_dirs.empty?
159
- depth += 1
160
- break unless recurse?(depth)
161
- current_dirs = next_dirs
162
- next_dirs = []
149
+ while entry = current_dirs.shift
150
+ if continue_recursion_at?(entry.depth + 1)
151
+ entry.children.each do |child|
152
+ result << child.path
153
+ current_dirs << child
154
+ end
163
155
  end
164
156
  end
165
157
 
166
158
  result
167
159
  end
168
- public
169
- # Stat a given file, using the links-appropriate method.
170
- def stat(path)
171
- @stat_method ||= self.links == :manage ? :lstat : :stat
172
-
173
- begin
174
- return File.send(@stat_method, path)
175
- rescue
176
- # If this happens, it is almost surely because we're
177
- # trying to manage a link to a file that does not exist.
178
- return nil
179
- end
160
+
161
+ def valid?(path)
162
+ @stat_method.call(path)
163
+ true
164
+ rescue Errno::ENOENT, Errno::EACCES
165
+ false
166
+ end
167
+
168
+ def continue_recursion_at?(depth)
169
+ # recurse if told to, and infinite recursion or current depth not at the limit
170
+ self.recurse && (self.recurselimit == :infinite || depth <= self.recurselimit)
180
171
  end
181
172
  end
@@ -113,7 +113,7 @@ class Puppet::Resource::Catalog::StaticCompiler < Puppet::Indirector::Code
113
113
  result.each { |data| data.source = "#{source}/#{data.relative_path}" }
114
114
  break result if result and ! result.empty? and sourceselect == :first
115
115
  result
116
- end.flatten
116
+ end.flatten.compact
117
117
 
118
118
  # This only happens if we have sourceselect == :all
119
119
  unless sourceselect == :first
@@ -58,7 +58,7 @@ module Puppet::Network::HTTP
58
58
  msg = error.message
59
59
  msg << ": [" + ssl_validator.verify_errors.join('; ') + "]"
60
60
  raise Puppet::Error, msg
61
- elsif error.message =~ /hostname (was )?not match/
61
+ elsif error.message =~ /hostname (\w+ )?not match/
62
62
  leaf_ssl_cert = ssl_validator.peer_certs.last
63
63
 
64
64
  valid_certnames = [leaf_ssl_cert.name, *leaf_ssl_cert.subject_alt_names].uniq
@@ -43,7 +43,7 @@ class Puppet::Network::HTTP::WEBrick
43
43
  @mutex.synchronize do
44
44
  raise "WEBrick server is not listening" unless @listening
45
45
  @server.shutdown
46
- @thread.join
46
+ wait_for_shutdown
47
47
  @server = nil
48
48
  @listening = false
49
49
  end
@@ -55,6 +55,10 @@ class Puppet::Network::HTTP::WEBrick
55
55
  end
56
56
  end
57
57
 
58
+ def wait_for_shutdown
59
+ @thread.join
60
+ end
61
+
58
62
  # Configure our http log file.
59
63
  def setup_logger
60
64
  # Make sure the settings are all ready for us.
@@ -108,4 +108,8 @@ class Puppet::Network::Server
108
108
  unlisten
109
109
  remove_pidfile
110
110
  end
111
+
112
+ def wait_for_shutdown
113
+ @http_server.wait_for_shutdown
114
+ end
111
115
  end
@@ -41,7 +41,8 @@ Puppet::Type.type(:service).provide :init, :parent => :base do
41
41
  # it should remain excluded. When that bug is adddressed this should be
42
42
  # reexamined.
43
43
  excludes += %w{wait-for-state portmap-wait}
44
- excludes
44
+ # these excludes were found with grep -r -L start /etc/init.d
45
+ excludes += %w{rcS module-init-tools}
45
46
  end
46
47
 
47
48
  # List all services of this type.
@@ -6,6 +6,7 @@ Puppet::Type.type(:service).provide :systemd, :parent => :base do
6
6
  commands :systemctl => "systemctl"
7
7
 
8
8
  #defaultfor :osfamily => [:redhat, :suse]
9
+ defaultfor :osfamily => [:archlinux]
9
10
 
10
11
  def self.instances
11
12
  i = []
@@ -1,3 +1,4 @@
1
+ require 'active_record'
1
2
  require 'puppet/rails'
2
3
  require 'puppet/rails/fact_value'
3
4
 
@@ -1,3 +1,5 @@
1
+ require 'active_record'
2
+
1
3
  class Puppet::Rails::FactValue < ActiveRecord::Base
2
4
  belongs_to :fact_name
3
5
  belongs_to :host
@@ -199,9 +199,11 @@ class Puppet::Resource::TypeCollection
199
199
  searchspace.each do |fqname|
200
200
  result = send(type, fqname)
201
201
  unless result
202
- # do not try to autoload if we already tried and it wasn't conclusive
203
- # as this is a time consuming operation.
204
- unless @notfound[fqname]
202
+ if @notfound[fqname] and Puppet[:ignoremissingtypes]
203
+ # do not try to autoload if we already tried and it wasn't conclusive
204
+ # as this is a time consuming operation. Warn the user.
205
+ Puppet.warning "Not attempting to load #{type} #{fqname} as this object was missing during a prior compilation"
206
+ else
205
207
  result = loader.try_load_fqname(type, fqname)
206
208
  @notfound[fqname] = result.nil?
207
209
  end
@@ -109,7 +109,7 @@ class Puppet::Settings::FileSetting < Puppet::Settings::StringSetting
109
109
  end
110
110
 
111
111
  def munge(value)
112
- if value.is_a?(String)
112
+ if value.is_a?(String) and value != ':memory:' # for sqlite3 in-memory tests
113
113
  value = File.expand_path(value)
114
114
  end
115
115
  value
@@ -117,11 +117,17 @@ class Puppet::Transaction::ResourceHarness
117
117
  end
118
118
  event
119
119
  rescue => detail
120
+ # Execution will continue on StandardErrors, just store the event
120
121
  Puppet.log_exception(detail)
121
122
  event.status = "failure"
122
123
 
123
124
  event.message = "change from #{property.is_to_s(current_value)} to #{property.should_to_s(property.should)} failed: #{detail}"
124
125
  event
126
+ rescue Exception => detail
127
+ # Execution will halt on Exceptions, they get raised to the application
128
+ event.status = "failure"
129
+ event.message = "change from #{property.is_to_s(current_value)} to #{property.should_to_s(property.should)} failed: #{detail}"
130
+ raise
125
131
  ensure
126
132
  event.send_log
127
133
  end
@@ -28,7 +28,7 @@ module Puppet::Util::ADSI
28
28
  unless @computer_name
29
29
  buf = " " * 128
30
30
  Win32API.new('kernel32', 'GetComputerName', ['P','P'], 'I').call(buf, buf.length.to_s)
31
- @computer_name = buf.unpack("A*")
31
+ @computer_name = buf.unpack("A*")[0]
32
32
  end
33
33
  @computer_name
34
34
  end
@@ -126,25 +126,6 @@ class Array
126
126
 
127
127
  slice(n, length - n) or []
128
128
  end unless method_defined? :drop
129
-
130
- # Array does not have a to_hash method and Hash uses this instead of checking with "respond_to?" if an
131
- # array can convert itself or not. (This is a bad thing in Hash). When Array is extended with a method_missing,
132
- # (like when using the RGen package 0.6.1 where meta methods are available on arrays), this trips up the
133
- # Hash implementation.
134
- # This patch simply does what the regular to_hash does, and it is accompanied by a respond_to? method that
135
- # returns false for :to_hash.
136
- # This is really ugly, and should be removed when the implementation in lib/rgen/array_extension.rb is
137
- # fixed to handle to_hash correctly.
138
- def to_hash
139
- raise NoMethodError.new
140
- end
141
-
142
- # @see #to_hash
143
- def respond_to? m, include_private=false
144
- return false if m == :to_hash
145
- super
146
- end
147
-
148
129
  end
149
130
 
150
131
 
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
  module Puppet
10
- PUPPETVERSION = '3.2.0-rc1'
10
+ PUPPETVERSION = '3.2.0-rc2'
11
11
 
12
12
  ##
13
13
  # version is a public API method intended to always provide a fast and
@@ -23,7 +23,7 @@ end
23
23
  # automatically for you. Nothing to do there.
24
24
  def setup_scratch_database
25
25
  Puppet[:dbadapter] = 'sqlite3'
26
- Puppet[:dblocation] = ':memory'
26
+ Puppet[:dblocation] = ':memory:'
27
27
  Puppet[:railslog] = PuppetSpec::Files.tmpfile('storeconfigs.log')
28
28
  Puppet::Rails.init
29
29
  end