puppet 3.2.3 → 3.2.4

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/Rakefile CHANGED
@@ -10,8 +10,6 @@ $LOAD_PATH << File.join(RAKE_ROOT, 'tasks')
10
10
  begin
11
11
  require 'rubygems'
12
12
  require 'rubygems/package_task'
13
- require 'rspec'
14
- require 'rspec/core/rake_task'
15
13
  rescue LoadError
16
14
  # Users of older versions of Rake (0.8.7 for example) will not necessarily
17
15
  # have rubygems installed, or the newer rubygems package_task for that
@@ -9,7 +9,7 @@ gpg_name: 'info@puppetlabs.com'
9
9
  gpg_key: '4BD6EC30'
10
10
  sign_tar: FALSE
11
11
  # a space separated list of mock configs
12
- final_mocks: 'pl-el-5-i386 pl-el-6-i386 pl-fedora-17-i386 pl-fedora-18-i386'
12
+ final_mocks: 'pl-el-5-i386 pl-el-6-i386 pl-fedora-17-i386 pl-fedora-18-i386 pl-fedora-19-i386'
13
13
  yum_host: 'burji.puppetlabs.com'
14
14
  yum_repo_path: '/opt/repository/yum/'
15
15
  build_gem: TRUE
@@ -37,9 +37,8 @@ BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
37
37
  BuildRequires: facter < 1:2.0
38
38
  # Puppet 3.x drops ruby 1.8.5 support and adds ruby 1.9 support
39
39
  BuildRequires: ruby >= 1.8.7
40
-
41
40
  BuildArch: noarch
42
- Requires: ruby(abi) >= 1.8
41
+ Requires: ruby >= 1.8
43
42
  Requires: ruby-shadow
44
43
 
45
44
  # Pull in ruby selinux bindings where available
@@ -67,6 +66,11 @@ Requires: shadow-utils
67
66
  %if 0%{?_with_systemd}
68
67
  # Required for %%post, %%preun, %%postun
69
68
  Requires: systemd
69
+ %if 0%{?fedora} >= 18
70
+ BuildRequires: systemd
71
+ %else
72
+ BuildRequires: systemd-units
73
+ %endif
70
74
  %else
71
75
  # Required for %%post and %%preun
72
76
  Requires: chkconfig
data/lib/puppet.rb CHANGED
@@ -27,6 +27,8 @@ require 'puppet/external/pson/pure'
27
27
  #
28
28
  # @api public
29
29
  module Puppet
30
+ require 'puppet/file_system'
31
+
30
32
  class << self
31
33
  include Puppet::Util
32
34
  attr_reader :features
@@ -0,0 +1,3 @@
1
+ module Puppet::FileSystem
2
+ require 'puppet/file_system/path_pattern'
3
+ end
@@ -0,0 +1,97 @@
1
+ require 'pathname'
2
+
3
+ module Puppet::FileSystem
4
+ class PathPattern
5
+ class InvalidPattern < Puppet::Error; end
6
+
7
+ TRAVERSAL = /^\.\.$/
8
+ ABSOLUTE_UNIX = /^\//
9
+ ABSOLUTE_WINDOWS = /^[a-z]:/i
10
+ #ABSOLUT_VODKA #notappearinginthisclass
11
+ CURRENT_DRIVE_RELATIVE_WINDOWS = /^\\/
12
+
13
+ def self.relative(pattern)
14
+ RelativePathPattern.new(pattern)
15
+ end
16
+
17
+ def self.absolute(pattern)
18
+ AbsolutePathPattern.new(pattern)
19
+ end
20
+
21
+ class << self
22
+ protected :new
23
+ end
24
+
25
+ # @param prefix [AbsolutePathPattern] An absolute path pattern instance
26
+ # @return [AbsolutePathPattern] A new AbsolutePathPattern prepended with
27
+ # the passed prefix's pattern.
28
+ def prefix_with(prefix)
29
+ new_pathname = prefix.pathname + pathname
30
+ self.class.absolute(new_pathname.to_s)
31
+ end
32
+
33
+ def glob
34
+ Dir.glob(pathname.to_s)
35
+ end
36
+
37
+ def to_s
38
+ pathname.to_s
39
+ end
40
+
41
+ protected
42
+
43
+ attr_reader :pathname
44
+
45
+ private
46
+
47
+ def validate
48
+ @pathname.each_filename do |e|
49
+ if e =~ TRAVERSAL
50
+ raise(InvalidPattern, "PathPatterns cannot be created with directory traversals.")
51
+ end
52
+ end
53
+ case @pathname.to_s
54
+ when CURRENT_DRIVE_RELATIVE_WINDOWS
55
+ raise(InvalidPattern, "A PathPattern cannot be a Windows current drive relative path.")
56
+ end
57
+ end
58
+
59
+ def initialize(pattern)
60
+ begin
61
+ @pathname = Pathname.new(pattern.strip)
62
+ rescue ArgumentError => error
63
+ raise InvalidPattern.new("PathPatterns cannot be created with a zero byte.", error)
64
+ end
65
+ validate
66
+ end
67
+ end
68
+
69
+ class RelativePathPattern < PathPattern
70
+ def absolute?
71
+ false
72
+ end
73
+
74
+ def validate
75
+ super
76
+ case @pathname.to_s
77
+ when ABSOLUTE_WINDOWS
78
+ raise(InvalidPattern, "A relative PathPattern cannot be prefixed with a drive.")
79
+ when ABSOLUTE_UNIX
80
+ raise(InvalidPattern, "A relative PathPattern cannot be an absolute path.")
81
+ end
82
+ end
83
+ end
84
+
85
+ class AbsolutePathPattern < PathPattern
86
+ def absolute?
87
+ true
88
+ end
89
+
90
+ def validate
91
+ super
92
+ if @pathname.to_s !~ ABSOLUTE_UNIX and @pathname.to_s !~ ABSOLUTE_WINDOWS
93
+ raise(InvalidPattern, "An absolute PathPattern cannot be a relative path.")
94
+ end
95
+ end
96
+ end
97
+ end
data/lib/puppet/module.rb CHANGED
@@ -11,6 +11,7 @@ class Puppet::Module
11
11
  class IncompatiblePlatform < Error; end
12
12
  class MissingMetadata < Error; end
13
13
  class InvalidName < Error; end
14
+ class InvalidFilePattern < Error; end
14
15
 
15
16
  include Puppet::Util::Logging
16
17
 
@@ -45,6 +46,8 @@ class Puppet::Module
45
46
  load_metadata if has_metadata?
46
47
 
47
48
  validate_puppet_version
49
+
50
+ @absolute_path_to_manifests = Puppet::FileSystem::PathPattern.absolute(manifests)
48
51
  end
49
52
 
50
53
  def has_metadata?
@@ -132,10 +135,16 @@ class Puppet::Module
132
135
  # Return the list of manifests matching the given glob pattern,
133
136
  # defaulting to 'init.{pp,rb}' for empty modules.
134
137
  def match_manifests(rest)
135
- pat = File.join(path, "manifests", rest || 'init')
136
- [manifest("init.pp"),manifest("init.rb")].compact + Dir.
137
- glob(pat + (File.extname(pat).empty? ? '.{pp,rb}' : '')).
138
- reject { |f| FileTest.directory?(f) }
138
+ if rest
139
+ wanted_manifests = wanted_manifests_from(rest)
140
+ searched_manifests = wanted_manifests.glob.reject { |f| FileTest.directory?(f) }
141
+ else
142
+ searched_manifests = []
143
+ end
144
+
145
+ # (#4220) Always ensure init.pp in case class is defined there.
146
+ init_manifests = [manifest("init.pp"), manifest("init.rb")].compact
147
+ init_manifests + searched_manifests
139
148
  end
140
149
 
141
150
  def metadata_file
@@ -275,6 +284,19 @@ class Puppet::Module
275
284
 
276
285
  private
277
286
 
287
+ def wanted_manifests_from(pattern)
288
+ begin
289
+ extended = File.extname(pattern).empty? ? "#{pattern}.{pp,rb}" : pattern
290
+ relative_pattern = Puppet::FileSystem::PathPattern.relative(extended)
291
+ rescue Puppet::FileSystem::PathPattern::InvalidPattern => error
292
+ raise Puppet::Module::InvalidFilePattern.new(
293
+ "The pattern \"#{pattern}\" to find manifests in the module \"#{name}\" " +
294
+ "is invalid and potentially unsafe.", error)
295
+ end
296
+
297
+ relative_pattern.prefix_with(@absolute_path_to_manifests)
298
+ end
299
+
278
300
  def subpath(type)
279
301
  File.join(path, type)
280
302
  end
@@ -10,7 +10,8 @@ module Puppet::ModuleTool
10
10
  parsed = parse_filename(filename)
11
11
  @module_name = parsed[:module_name]
12
12
  super(options)
13
- @module_dir = Pathname.new(options[:target_dir]) + parsed[:dir_name]
13
+ @module_path = Pathname(options[:target_dir])
14
+ @module_dir = @module_path + parsed[:dir_name]
14
15
  end
15
16
 
16
17
  def run
@@ -37,7 +38,7 @@ module Puppet::ModuleTool
37
38
  build_dir.mkpath
38
39
  begin
39
40
  begin
40
- Puppet::ModuleTool::Tar.instance(@module_name).unpack(@filename.to_s, build_dir.to_s)
41
+ Puppet::ModuleTool::Tar.instance(@module_name).unpack(@filename.to_s, build_dir.to_s, [@module_path.stat.uid, @module_path.stat.gid].join(':'))
41
42
  rescue Puppet::ExecutionFailure => e
42
43
  raise RuntimeError, "Could not extract contents of module archive: #{e.message}"
43
44
  end
@@ -1,6 +1,9 @@
1
1
  class Puppet::ModuleTool::Tar::Gnu
2
- def unpack(sourcefile, destdir)
3
- Puppet::Util::Execution.execute("tar xzf #{sourcefile} -C #{destdir}")
2
+ def unpack(sourcefile, destdir, owner)
3
+ Puppet::Util::Execution.execute("tar xzf #{sourcefile} --no-same-permissions --no-same-owner -C #{destdir}")
4
+ Puppet::Util::Execution.execute("find #{destdir} -type d -exec chmod 755 {} +")
5
+ Puppet::Util::Execution.execute("find #{destdir} -type f -exec chmod 644 {} +")
6
+ Puppet::Util::Execution.execute("chown -R #{owner} #{destdir}")
4
7
  end
5
8
 
6
9
  def pack(sourcedir, destfile)
@@ -3,7 +3,7 @@ class Puppet::ModuleTool::Tar::Mini
3
3
  @module_name = module_name
4
4
  end
5
5
 
6
- def unpack(sourcefile, destdir)
6
+ def unpack(sourcefile, destdir, _)
7
7
  Zlib::GzipReader.open(sourcefile) do |reader|
8
8
  Archive::Tar::Minitar.unpack(reader, destdir) do |action, name, stats|
9
9
  case action
@@ -1,5 +1,8 @@
1
1
  class Puppet::ModuleTool::Tar::Solaris < Puppet::ModuleTool::Tar::Gnu
2
- def unpack(sourcefile, destdir)
3
- Puppet::Util::Execution.execute("gtar xzf #{sourcefile} -C #{destdir}")
2
+ def unpack(sourcefile, destdir, owner)
3
+ Puppet::Util::Execution.execute("gtar xzf #{sourcefile} --no-same-permissions --no-same-owner -C #{destdir}")
4
+ Puppet::Util::Execution.execute("find #{destdir} -type d -exec chmod 755 {} +")
5
+ Puppet::Util::Execution.execute("find #{destdir} -type f -exec chmod 644 {} +")
6
+ Puppet::Util::Execution.execute("chown -R #{owner} #{destdir}")
4
7
  end
5
8
  end
@@ -6,26 +6,28 @@ require 'puppet/module'
6
6
  # doesn't really belong in the Puppet::Module class,
7
7
  # but it doesn't really belong anywhere else, either.
8
8
  module Puppet; module Parser; module Files
9
-
9
+
10
10
  module_function
11
11
 
12
- # Return a list of manifests (as absolute filenames) that match +pat+
13
- # with the current directory set to +cwd+. If the first component of
14
- # +pat+ does not contain any wildcards and is an existing module, return
15
- # a list of manifests in that module matching the rest of +pat+
16
- # Otherwise, try to find manifests matching +pat+ relative to +cwd+
17
- def find_manifests(start, options = {})
18
- cwd = options[:cwd] || Dir.getwd
19
- module_name, pattern = split_file_path(start)
12
+ # Return a list of manifests as absolute filenames matching the given
13
+ # pattern.
14
+ #
15
+ # @param pattern [String] A reference for a file in a module. It is the format "<modulename>/<file glob>"
16
+ # @param environment [Puppet::Node::Environment] the environment of modules
17
+ #
18
+ # @return [Array(String, Array<String>)] the module name and the list of files found
19
+ # @api private
20
+ def find_manifests_in_modules(pattern, environment)
21
+ module_name, file_pattern = split_file_path(pattern)
20
22
  begin
21
- if mod = Puppet::Module.find(module_name, options[:environment])
22
- return [mod.name, mod.match_manifests(pattern)]
23
+ if mod = Puppet::Module.find(module_name, environment)
24
+ return [mod.name, mod.match_manifests(file_pattern)]
23
25
  end
24
26
  rescue Puppet::Module::InvalidName
25
- # Than that would be a "no."
27
+ # one of the modules being loaded might have an invalid name and so
28
+ # looking for one might blow up since we load them lazily.
26
29
  end
27
- abspat = File::expand_path(start, cwd)
28
- [nil, Dir.glob(abspat + (File.extname(abspat).empty? ? '{.pp,.rb}' : '' )).uniq.reject { |f| FileTest.directory?(f) }]
30
+ [nil, []]
29
31
  end
30
32
 
31
33
  # Find the concrete file denoted by +file+. If +file+ is absolute,
@@ -81,9 +83,12 @@ module Puppet; module Parser; module Files
81
83
 
82
84
  # Split the path into the module and the rest of the path, or return
83
85
  # nil if the path is empty or absolute (starts with a /).
84
- # This method can return nil & anyone calling it needs to handle that.
85
86
  def split_file_path(path)
86
- path.split(File::SEPARATOR, 2) unless path == "" or Puppet::Util.absolute_path?(path)
87
+ if path == "" or Puppet::Util.absolute_path?(path)
88
+ nil
89
+ else
90
+ path.split(File::SEPARATOR, 2)
91
+ end
87
92
  end
88
93
 
89
94
  end; end; end
@@ -98,7 +98,16 @@ class Puppet::Parser::Parser
98
98
  def_delegators :known_resource_types, :watch_file, :version
99
99
 
100
100
  def import(file)
101
- known_resource_types.loader.import(file, @lexer.file)
101
+ if @lexer.file
102
+ # use a path relative to the file doing the importing
103
+ dir = File.dirname(@lexer.file)
104
+ else
105
+ # otherwise assume that everything needs to be from where the user is
106
+ # executing this command. Normally, this would be in a "puppet apply -e"
107
+ dir = Dir.pwd
108
+ end
109
+
110
+ known_resource_types.loader.import(file, dir)
102
111
  end
103
112
 
104
113
  def initialize(env)
@@ -62,50 +62,48 @@ class Puppet::Parser::TypeLoader
62
62
  end
63
63
  end
64
64
 
65
- # Import our files.
66
- def import(file, current_file = nil)
65
+ # Import manifest files that match a given file glob pattern.
66
+ #
67
+ # @param pattern [String] the file glob to apply when determining which files
68
+ # to load
69
+ # @param dir [String] base directory to use when the file is not
70
+ # found in a module
71
+ # @api private
72
+ def import(pattern, dir)
67
73
  return if Puppet[:ignoreimport]
68
74
 
69
- # use a path relative to the file doing the importing
70
- if current_file
71
- dir = current_file.sub(%r{[^/]+$},'').sub(/\/$/, '')
72
- else
73
- dir = "."
74
- end
75
- if dir == ""
76
- dir = "."
77
- end
75
+ modname, files = Puppet::Parser::Files.find_manifests_in_modules(pattern, environment)
76
+ if files.empty?
77
+ abspat = File.expand_path(pattern, dir)
78
+ file_pattern = abspat + (File.extname(abspat).empty? ? '{.pp,.rb}' : '' )
78
79
 
79
- pat = file
80
- modname, files = Puppet::Parser::Files.find_manifests(pat, :cwd => dir, :environment => environment)
81
- if files.size == 0
82
- raise Puppet::ImportError.new("No file(s) found for import of '#{pat}'")
83
- end
80
+ files = Dir.glob(file_pattern).uniq.reject { |f| FileTest.directory?(f) }
81
+ modname = nil
84
82
 
85
- loaded_asts = []
86
- files.each do |file|
87
- unless Puppet::Util.absolute_path?(file)
88
- file = File.join(dir, file)
83
+ if files.empty?
84
+ raise_no_files_found(pattern)
89
85
  end
90
- @loading_helper.do_once(file) do
91
- loaded_asts << parse_file(file)
92
- end
93
- end
94
- loaded_asts.inject([]) do |loaded_types, ast|
95
- loaded_types + known_resource_types.import_ast(ast, modname)
96
86
  end
87
+
88
+ load_files(modname, files)
97
89
  end
98
90
 
91
+ # Load all of the manifest files in all known modules.
92
+ # @api private
99
93
  def import_all
100
94
  # And then load all files from each module, but (relying on system
101
95
  # behavior) only load files from the first module of a given name. E.g.,
102
96
  # given first/foo and second/foo, only files from first/foo will be loaded.
103
97
  environment.modules.each do |mod|
104
- Find.find(mod.manifests) do |path|
105
- if path =~ /\.pp$/ or path =~ /\.rb$/
106
- import(path)
98
+ manifest_files = []
99
+ if File.exists?(mod.manifests)
100
+ Find.find(mod.manifests) do |path|
101
+ if path.end_with?(".pp") || path.end_with?(".rb")
102
+ manifest_files << path
103
+ end
107
104
  end
108
105
  end
106
+ load_files(mod.name, manifest_files)
109
107
  end
110
108
  end
111
109
 
@@ -121,7 +119,7 @@ class Puppet::Parser::TypeLoader
121
119
  return nil if fqname == "" # special-case main.
122
120
  name2files(fqname).each do |filename|
123
121
  begin
124
- imported_types = import(filename)
122
+ imported_types = import_from_modules(filename)
125
123
  if result = imported_types.find { |t| t.type == type and t.name == fqname }
126
124
  Puppet.debug "Automatically imported #{fqname} from #{filename} into #{environment}"
127
125
  return result
@@ -138,7 +136,6 @@ class Puppet::Parser::TypeLoader
138
136
 
139
137
  def parse_file(file)
140
138
  Puppet.debug("importing '#{file}' in environment #{environment}")
141
- # parser = Puppet::Parser::Parser.new(environment)
142
139
  parser = Puppet::Parser::ParserFactory.parser(environment)
143
140
  parser.file = file
144
141
  return parser.parse
@@ -146,6 +143,32 @@ class Puppet::Parser::TypeLoader
146
143
 
147
144
  private
148
145
 
146
+ def import_from_modules(pattern)
147
+ modname, files = Puppet::Parser::Files.find_manifests_in_modules(pattern, environment)
148
+ if files.empty?
149
+ raise_no_files_found(pattern)
150
+ end
151
+
152
+ load_files(modname, files)
153
+ end
154
+
155
+ def raise_no_files_found(pattern)
156
+ raise Puppet::ImportError, "No file(s) found for import of '#{pattern}'"
157
+ end
158
+
159
+ def load_files(modname, files)
160
+ loaded_asts = []
161
+ files.each do |file|
162
+ @loading_helper.do_once(file) do
163
+ loaded_asts << parse_file(file)
164
+ end
165
+ end
166
+
167
+ loaded_asts.collect do |ast|
168
+ known_resource_types.import_ast(ast, modname)
169
+ end.flatten
170
+ end
171
+
149
172
  # Return a list of all file basenames that should be tried in order
150
173
  # to load the object with the given fully qualified name.
151
174
  def name2files(fqname)
@@ -7,7 +7,7 @@
7
7
 
8
8
 
9
9
  module Puppet
10
- PUPPETVERSION = '3.2.3'
10
+ PUPPETVERSION = '3.2.4'
11
11
 
12
12
  ##
13
13
  # version is a public API method intended to always provide a fast and
@@ -0,0 +1,138 @@
1
+ require 'spec_helper'
2
+ require 'puppet_spec/files'
3
+ require 'puppet/file_system'
4
+
5
+ describe Puppet::FileSystem::PathPattern do
6
+ include PuppetSpec::Files
7
+ InvalidPattern = Puppet::FileSystem::PathPattern::InvalidPattern
8
+
9
+ describe 'relative' do
10
+ it "can not be created with a traversal up the directory tree" do
11
+ expect do
12
+ Puppet::FileSystem::PathPattern.relative("my/../other")
13
+ end.to raise_error(InvalidPattern, "PathPatterns cannot be created with directory traversals.")
14
+ end
15
+
16
+ it "can be created with a '..' prefixing a filename" do
17
+ expect(Puppet::FileSystem::PathPattern.relative("my/..other").to_s).to eq("my/..other")
18
+ end
19
+
20
+ it "can be created with a '..' suffixing a filename" do
21
+ expect(Puppet::FileSystem::PathPattern.relative("my/other..").to_s).to eq("my/other..")
22
+ end
23
+
24
+ it "can be created with a '..' embedded in a filename" do
25
+ expect(Puppet::FileSystem::PathPattern.relative("my/ot..her").to_s).to eq("my/ot..her")
26
+ end
27
+
28
+ it "can not be created with a \\0 byte embedded" do
29
+ expect do
30
+ Puppet::FileSystem::PathPattern.relative("my/\0/other")
31
+ end.to raise_error(InvalidPattern, "PathPatterns cannot be created with a zero byte.")
32
+ end
33
+
34
+ it "can not be created with a windows drive" do
35
+ expect do
36
+ Puppet::FileSystem::PathPattern.relative("c:\\relative\\path")
37
+ end.to raise_error(InvalidPattern, "A relative PathPattern cannot be prefixed with a drive.")
38
+ end
39
+
40
+ it "can not be created with a windows drive (with space)" do
41
+ expect do
42
+ Puppet::FileSystem::PathPattern.relative(" c:\\relative\\path")
43
+ end.to raise_error(InvalidPattern, "A relative PathPattern cannot be prefixed with a drive.")
44
+ end
45
+
46
+ it "can not create an absolute relative path" do
47
+ expect do
48
+ Puppet::FileSystem::PathPattern.relative("/no/absolutes")
49
+ end.to raise_error(InvalidPattern, "A relative PathPattern cannot be an absolute path.")
50
+ end
51
+
52
+ it "can not create an absolute relative path (with space)" do
53
+ expect do
54
+ Puppet::FileSystem::PathPattern.relative("\t/no/absolutes")
55
+ end.to raise_error(InvalidPattern, "A relative PathPattern cannot be an absolute path.")
56
+ end
57
+
58
+ it "can not create a relative path that is a windows path relative to the current drive" do
59
+ expect do
60
+ Puppet::FileSystem::PathPattern.relative("\\no\relatives")
61
+ end.to raise_error(InvalidPattern, "A PathPattern cannot be a Windows current drive relative path.")
62
+ end
63
+
64
+ it "creates a relative PathPattern from a valid relative path" do
65
+ expect(Puppet::FileSystem::PathPattern.relative("a/relative/path").to_s).to eq("a/relative/path")
66
+ end
67
+
68
+ it "is not absolute" do
69
+ expect(Puppet::FileSystem::PathPattern.relative("a/relative/path")).to_not be_absolute
70
+ end
71
+ end
72
+
73
+ describe 'absolute' do
74
+ it "can not create a relative absolute path" do
75
+ expect do
76
+ Puppet::FileSystem::PathPattern.absolute("no/relatives")
77
+ end.to raise_error(InvalidPattern, "An absolute PathPattern cannot be a relative path.")
78
+ end
79
+
80
+ it "can not create an absolute path that is a windows path relative to the current drive" do
81
+ expect do
82
+ Puppet::FileSystem::PathPattern.absolute("\\no\\relatives")
83
+ end.to raise_error(InvalidPattern, "A PathPattern cannot be a Windows current drive relative path.")
84
+ end
85
+
86
+ it "creates an absolute PathPattern from a valid absolute path" do
87
+ expect(Puppet::FileSystem::PathPattern.absolute("/an/absolute/path").to_s).to eq("/an/absolute/path")
88
+ end
89
+
90
+ it "creates an absolute PathPattern from a valid Windows absolute path" do
91
+ expect(Puppet::FileSystem::PathPattern.absolute("c:/absolute/windows/path").to_s).to eq("c:/absolute/windows/path")
92
+ end
93
+
94
+ it "can be created with a '..' embedded in a filename on windows", :if => Puppet.features.microsoft_windows? do
95
+ expect(Puppet::FileSystem::PathPattern.absolute(%q{c:\..my\ot..her\one..}).to_s).to eq(%q{c:\..my\ot..her\one..})
96
+ end
97
+
98
+ it "is absolute" do
99
+ expect(Puppet::FileSystem::PathPattern.absolute("c:/absolute/windows/path")).to be_absolute
100
+ end
101
+ end
102
+
103
+ it "prefixes the relative path pattern with another path" do
104
+ pattern = Puppet::FileSystem::PathPattern.relative("docs/*_thoughts.txt")
105
+ prefix = Puppet::FileSystem::PathPattern.absolute("/prefix")
106
+
107
+ absolute_pattern = pattern.prefix_with(prefix)
108
+
109
+ expect(absolute_pattern).to be_absolute
110
+ expect(absolute_pattern.to_s).to eq(File.join("/prefix", "docs/*_thoughts.txt"))
111
+ end
112
+
113
+ it "refuses to prefix with a relative pattern" do
114
+ pattern = Puppet::FileSystem::PathPattern.relative("docs/*_thoughts.txt")
115
+ prefix = Puppet::FileSystem::PathPattern.relative("prefix")
116
+
117
+ expect do
118
+ pattern.prefix_with(prefix)
119
+ end.to raise_error(InvalidPattern, "An absolute PathPattern cannot be a relative path.")
120
+ end
121
+
122
+ it "applies the pattern to the filesystem as a glob" do
123
+ dir = tmpdir('globtest')
124
+ create_file_in(dir, "found_one")
125
+ create_file_in(dir, "found_two")
126
+ create_file_in(dir, "third_not_found")
127
+
128
+ pattern = Puppet::FileSystem::PathPattern.relative("found_*").prefix_with(
129
+ Puppet::FileSystem::PathPattern.absolute(dir))
130
+
131
+ expect(pattern.glob).to match_array([File.join(dir, "found_one"),
132
+ File.join(dir, "found_two")])
133
+ end
134
+
135
+ def create_file_in(dir, name)
136
+ File.open(File.join(dir, name), "w") { |f| f.puts "data" }
137
+ end
138
+ end
@@ -8,7 +8,7 @@ describe Puppet::Module do
8
8
  include PuppetSpec::Files
9
9
 
10
10
  let(:env) { mock("environment") }
11
- let(:path) { "path" }
11
+ let(:path) { "/path" }
12
12
  let(:name) { "mymod" }
13
13
  let(:mod) { Puppet::Module.new(name, path, env) }
14
14
 
@@ -339,7 +339,7 @@ describe Puppet::Module do
339
339
  end
340
340
 
341
341
  it "should fail if its name is not alphanumeric" do
342
- lambda { Puppet::Module.new(".something", "path", env) }.should raise_error(Puppet::Module::InvalidName)
342
+ lambda { Puppet::Module.new(".something", "/path", env) }.should raise_error(Puppet::Module::InvalidName)
343
343
  end
344
344
 
345
345
  it "should require a name at initialization" do
@@ -347,7 +347,7 @@ describe Puppet::Module do
347
347
  end
348
348
 
349
349
  it "should accept an environment at initialization" do
350
- Puppet::Module.new("foo", "path", env).environment.should == env
350
+ Puppet::Module.new("foo", "/path", env).environment.should == env
351
351
  end
352
352
 
353
353
  describe '#modulepath' do
@@ -418,7 +418,8 @@ describe Puppet::Module, "when finding matching manifests" do
418
418
  end
419
419
 
420
420
  it "should default to the 'init' file if no glob pattern is specified" do
421
- Dir.expects(:glob).with("/a/manifests/init.{pp,rb}").returns(%w{/a/manifests/init.pp})
421
+ FileTest.expects(:exist?).with("/a/manifests/init.pp").returns(true)
422
+ FileTest.expects(:exist?).with("/a/manifests/init.rb").returns(false)
422
423
 
423
424
  @mod.match_manifests(nil).should == %w{/a/manifests/init.pp}
424
425
  end
@@ -440,6 +441,12 @@ describe Puppet::Module, "when finding matching manifests" do
440
441
 
441
442
  @mod.match_manifests(@pq_glob_with_extension).should == []
442
443
  end
444
+
445
+ it "should raise an error if the pattern tries to leave the manifest directory" do
446
+ expect do
447
+ @mod.match_manifests("something/../../*")
448
+ end.to raise_error(Puppet::Module::InvalidFilePattern, 'The pattern "something/../../*" to find manifests in the module "mymod" is invalid and potentially unsafe.')
449
+ end
443
450
  end
444
451
 
445
452
  describe Puppet::Module do
@@ -509,13 +516,13 @@ describe Puppet::Module do
509
516
  Puppet::Module.any_instance.expects(:has_metadata?).returns true
510
517
  Puppet::Module.any_instance.expects(:load_metadata)
511
518
 
512
- Puppet::Module.new("yay", "path", mock("env"))
519
+ Puppet::Module.new("yay", "/path", mock("env"))
513
520
  end
514
521
 
515
522
  def a_module_with_metadata(data)
516
523
  text = data.to_pson
517
524
 
518
- mod = Puppet::Module.new("foo", "path", mock("env"))
525
+ mod = Puppet::Module.new("foo", "/path", mock("env"))
519
526
  mod.stubs(:metadata_file).returns "/my/file"
520
527
  File.stubs(:read).with("/my/file").returns text
521
528
  mod
@@ -8,8 +8,11 @@ describe Puppet::ModuleTool::Tar::Gnu do
8
8
  let(:destfile) { '/the/dest/file.tar.gz' }
9
9
 
10
10
  it "unpacks a tar file" do
11
- Puppet::Util::Execution.expects(:execute).with("tar xzf #{sourcefile} -C #{destdir}")
12
- subject.unpack(sourcefile, destdir)
11
+ Puppet::Util::Execution.expects(:execute).with("tar xzf #{sourcefile} --no-same-permissions --no-same-owner -C #{destdir}")
12
+ Puppet::Util::Execution.expects(:execute).with("find #{destdir} -type d -exec chmod 755 {} +")
13
+ Puppet::Util::Execution.expects(:execute).with("find #{destdir} -type f -exec chmod 644 {} +")
14
+ Puppet::Util::Execution.expects(:execute).with("chown -R <owner:group> #{destdir}")
15
+ subject.unpack(sourcefile, destdir, '<owner:group>')
13
16
  end
14
17
 
15
18
  it "packs a tar file" do
@@ -11,14 +11,14 @@ describe Puppet::ModuleTool::Tar::Mini, :if => (Puppet.features.minitar? and Pup
11
11
  it "unpacks a tar file" do
12
12
  unpacks_the_entry(:file_start, 'thefile')
13
13
 
14
- minitar.unpack(sourcefile, destdir)
14
+ minitar.unpack(sourcefile, destdir, 'uid')
15
15
  end
16
16
 
17
17
  it "does not allow an absolute path" do
18
18
  unpacks_the_entry(:file_start, '/thefile')
19
19
 
20
20
  expect {
21
- minitar.unpack(sourcefile, destdir)
21
+ minitar.unpack(sourcefile, destdir, 'uid')
22
22
  }.to raise_error(Puppet::ModuleTool::Errors::InvalidPathInPackageError,
23
23
  "Attempt to install file into \"/thefile\" under \"#{destdir}\"")
24
24
  end
@@ -27,7 +27,7 @@ describe Puppet::ModuleTool::Tar::Mini, :if => (Puppet.features.minitar? and Pup
27
27
  unpacks_the_entry(:file_start, '../../thefile')
28
28
 
29
29
  expect {
30
- minitar.unpack(sourcefile, destdir)
30
+ minitar.unpack(sourcefile, destdir, 'uid')
31
31
  }.to raise_error(Puppet::ModuleTool::Errors::InvalidPathInPackageError,
32
32
  "Attempt to install file into \"#{File.expand_path('/the/thefile')}\" under \"#{destdir}\"")
33
33
  end
@@ -36,7 +36,7 @@ describe Puppet::ModuleTool::Tar::Mini, :if => (Puppet.features.minitar? and Pup
36
36
  unpacks_the_entry(:dir, '../../thedir')
37
37
 
38
38
  expect {
39
- minitar.unpack(sourcefile, destdir)
39
+ minitar.unpack(sourcefile, destdir, 'uid')
40
40
  }.to raise_error(Puppet::ModuleTool::Errors::InvalidPathInPackageError,
41
41
  "Attempt to install file into \"#{File.expand_path('/the/thedir')}\" under \"#{destdir}\"")
42
42
  end
@@ -8,8 +8,11 @@ describe Puppet::ModuleTool::Tar::Solaris do
8
8
  let(:destfile) { '/the/dest/file.tar.gz' }
9
9
 
10
10
  it "unpacks a tar file" do
11
- Puppet::Util::Execution.expects(:execute).with("gtar xzf #{sourcefile} -C #{destdir}")
12
- subject.unpack(sourcefile, destdir)
11
+ Puppet::Util::Execution.expects(:execute).with("gtar xzf #{sourcefile} --no-same-permissions --no-same-owner -C #{destdir}")
12
+ Puppet::Util::Execution.expects(:execute).with("find #{destdir} -type d -exec chmod 755 {} +")
13
+ Puppet::Util::Execution.expects(:execute).with("find #{destdir} -type f -exec chmod 644 {} +")
14
+ Puppet::Util::Execution.expects(:execute).with("chown -R <owner:group> #{destdir}")
15
+ subject.unpack(sourcefile, destdir, '<owner:group>')
13
16
  end
14
17
 
15
18
  it "packs a tar file" do
@@ -10,14 +10,6 @@ describe Puppet::Parser::Files do
10
10
  @basepath = make_absolute("/somepath")
11
11
  end
12
12
 
13
- it "should have a method for finding a template" do
14
- Puppet::Parser::Files.should respond_to(:find_template)
15
- end
16
-
17
- it "should have a method for finding manifests" do
18
- Puppet::Parser::Files.should respond_to(:find_manifests)
19
- end
20
-
21
13
  describe "when searching for templates" do
22
14
  it "should return fully-qualified templates directly" do
23
15
  Puppet::Parser::Files.expects(:modulepath).never
@@ -127,90 +119,42 @@ describe Puppet::Parser::Files do
127
119
  describe "when searching for manifests" do
128
120
  it "should ignore invalid modules" do
129
121
  mod = mock 'module'
130
- Puppet::Node::Environment.new.expects(:module).with("mymod").raises(Puppet::Module::InvalidName, "name is invalid")
122
+ env = Puppet::Node::Environment.new
123
+ env.expects(:module).with("mymod").raises(Puppet::Module::InvalidName, "name is invalid")
131
124
  Puppet.expects(:value).with(:modulepath).never
132
125
  Dir.stubs(:glob).returns %w{foo}
133
126
 
134
- Puppet::Parser::Files.find_manifests("mymod/init.pp")
127
+ Puppet::Parser::Files.find_manifests_in_modules("mymod/init.pp", env)
135
128
  end
136
129
  end
137
130
 
138
- describe "when searching for manifests when no module is found" do
139
- before do
140
- File.stubs(:find).returns(nil)
141
- end
142
-
143
- it "should not look for modules when paths are fully qualified" do
144
- Puppet.expects(:value).with(:modulepath).never
145
- file = @basepath + "/fully/qualified/file.pp"
146
- Dir.stubs(:glob).with(file).returns([file])
147
- Puppet::Parser::Files.find_manifests(file)
148
- end
149
-
150
- it "should return nil and an array of fully qualified files" do
151
- file = @basepath + "/fully/qualified/file.pp"
152
- Dir.stubs(:glob).with(file).returns([file])
153
- Puppet::Parser::Files.find_manifests(file).should == [nil, [file]]
154
- end
155
-
156
- it "should match against provided fully qualified patterns" do
157
- pattern = @basepath + "/fully/qualified/pattern/*"
158
- Dir.expects(:glob).with(pattern+'{.pp,.rb}').returns(%w{my file list})
159
- ['my', 'file','list'].each do |w|
160
- FileTest.expects(:'directory?').with(w).returns false
161
- end
162
- Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{my file list}
163
- end
164
-
165
- it "should look for files relative to the current directory" do
166
- # We expand_path to normalize backslashes and slashes on Windows
167
- cwd = File.expand_path(Dir.getwd)
168
- Dir.expects(:glob).with("#{cwd}/foobar/init.pp").returns(["#{cwd}/foobar/init.pp"])
169
- Puppet::Parser::Files.find_manifests("foobar/init.pp")[1].should == ["#{cwd}/foobar/init.pp"]
170
- end
171
-
172
- it "should only return files, not directories" do
173
- pattern = @basepath + "/fully/qualified/pattern/*"
174
- file = @basepath + "/my/file"
175
- dir = @basepath + "/my/directory"
176
- Dir.expects(:glob).with(pattern+'{.pp,.rb}').returns([file, dir])
177
- FileTest.expects(:directory?).with(file).returns(false)
178
- FileTest.expects(:directory?).with(dir).returns(true)
179
- Puppet::Parser::Files.find_manifests(pattern)[1].should == [file]
180
- end
181
-
182
- it "should return files once only" do
183
- pattern = @basepath + "/fully/qualified/pattern/*"
184
- Dir.expects(:glob).with(pattern+'{.pp,.rb}').returns(%w{one two one})
185
- Puppet::Parser::Files.find_manifests(pattern)[1].should == %w{one two}
186
- end
187
- end
188
-
189
- describe "when searching for manifests in a found module" do
131
+ describe "when searching for manifests in a module" do
190
132
  def a_module_in_environment(env, name)
191
133
  mod = Puppet::Module.new(name, "/one/#{name}", env)
192
134
  env.stubs(:module).with(name).returns mod
193
135
  mod.stubs(:match_manifests).with("init.pp").returns(["/one/#{name}/manifests/init.pp"])
194
136
  end
195
137
 
196
- it "should return the name of the module and the manifests from the first found module" do
197
- a_module_in_environment(Puppet::Node::Environment.new, "mymod")
138
+ let(:environment) { Puppet::Node::Environment.new }
198
139
 
199
- Puppet::Parser::Files.find_manifests("mymod/init.pp").should ==
200
- ["mymod", ["/one/mymod/manifests/init.pp"]]
140
+ it "returns no files when no module is found" do
141
+ module_name, files = Puppet::Parser::Files.find_manifests_in_modules("not_here_module/foo", environment)
142
+ expect(files).to be_empty
143
+ expect(module_name).to be_nil
201
144
  end
202
145
 
203
- it "should use the node environment if specified" do
204
- a_module_in_environment(Puppet::Node::Environment.new("myenv"), "mymod")
146
+ it "should return the name of the module and the manifests from the first found module" do
147
+ a_module_in_environment(environment, "mymod")
205
148
 
206
- Puppet::Parser::Files.find_manifests("mymod/init.pp", :environment => "myenv").should ==
149
+ Puppet::Parser::Files.find_manifests_in_modules("mymod/init.pp", environment).should ==
207
150
  ["mymod", ["/one/mymod/manifests/init.pp"]]
208
151
  end
209
152
 
210
153
  it "does not find the module when it is a different environment" do
211
- a_module_in_environment(Puppet::Node::Environment.new("myenv"), "mymod")
154
+ different_env = Puppet::Node::Environment.new("different")
155
+ a_module_in_environment(environment, "mymod")
212
156
 
213
- Puppet::Parser::Files.find_manifests("mymod/init.pp", :environment => "different").should_not include("mymod")
157
+ Puppet::Parser::Files.find_manifests_in_modules("mymod/init.pp", different_env).should_not include("mymod")
214
158
  end
215
159
  end
216
160
  end
@@ -35,16 +35,18 @@ describe Puppet::Parser do
35
35
  end
36
36
 
37
37
  context "when importing" do
38
- it "should delegate importing to the known resource type loader" do
39
- parser = Puppet::Parser::Parser.new "development"
40
- parser.known_resource_types.loader.expects(:import).with("newfile", "current_file")
41
- parser.lexer.expects(:file).returns "current_file"
42
- parser.import("newfile")
38
+ it "uses the directory of the currently parsed file" do
39
+ @parser.lexer.stubs(:file).returns "/tmp/current_file"
40
+
41
+ @parser.known_resource_types.loader.expects(:import).with("newfile", "/tmp")
42
+
43
+ @parser.import("newfile")
43
44
  end
44
45
 
45
- it "should import multiple files on one line" do
46
- @parser.known_resource_types.loader.expects(:import).with('one', nil)
47
- @parser.known_resource_types.loader.expects(:import).with('two', nil)
46
+ it "uses the current working directory, when there is no file being parsed" do
47
+ @parser.known_resource_types.loader.expects(:import).with('one', Dir.pwd)
48
+ @parser.known_resource_types.loader.expects(:import).with('two', Dir.pwd)
49
+
48
50
  @parser.parse("import 'one', 'two'")
49
51
  end
50
52
  end
@@ -37,67 +37,56 @@ describe Puppet::Parser::TypeLoader do
37
37
  end
38
38
 
39
39
  it "should attempt to import each generated name" do
40
- @loader.expects(:import).with("foo/bar",nil).returns([])
41
- @loader.expects(:import).with("foo",nil).returns([])
40
+ @loader.expects(:import_from_modules).with("foo/bar").returns([])
41
+ @loader.expects(:import_from_modules).with("foo").returns([])
42
42
  @loader.try_load_fqname(:hostclass, "foo::bar") { |f| false }
43
43
  end
44
44
  end
45
45
 
46
46
  describe "when importing" do
47
47
  before do
48
- Puppet::Parser::Files.stubs(:find_manifests).returns ["modname", %w{file}]
48
+ Puppet::Parser::Files.stubs(:find_manifests_in_modules).returns ["modname", %w{file}]
49
49
  parser_class.any_instance.stubs(:parse).returns(Puppet::Parser::AST::Hostclass.new(''))
50
50
  parser_class.any_instance.stubs(:file=)
51
51
  end
52
52
 
53
53
  it "should return immediately when imports are being ignored" do
54
- Puppet::Parser::Files.expects(:find_manifests).never
54
+ Puppet::Parser::Files.expects(:find_manifests_in_modules).never
55
55
  Puppet[:ignoreimport] = true
56
- @loader.import("foo").should be_nil
56
+ @loader.import("foo", "/path").should be_nil
57
57
  end
58
58
 
59
59
  it "should find all manifests matching the file or pattern" do
60
- Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| pat == "myfile" }.returns ["modname", %w{one}]
61
- @loader.import("myfile")
62
- end
63
-
64
- it "should use the directory of the current file if one is set" do
65
- Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:cwd] == make_absolute("/current") }.returns ["modname", %w{one}]
66
- @loader.import("myfile", make_absolute("/current/file"))
60
+ Puppet::Parser::Files.expects(:find_manifests_in_modules).with("myfile", anything).returns ["modname", %w{one}]
61
+ @loader.import("myfile", "/path")
67
62
  end
68
63
 
69
64
  it "should pass the environment when looking for files" do
70
- Puppet::Parser::Files.expects(:find_manifests).with { |pat, opts| opts[:environment] == @loader.environment }.returns ["modname", %w{one}]
71
- @loader.import("myfile")
65
+ Puppet::Parser::Files.expects(:find_manifests_in_modules).with(anything, @loader.environment).returns ["modname", %w{one}]
66
+ @loader.import("myfile", "/path")
72
67
  end
73
68
 
74
69
  it "should fail if no files are found" do
75
- Puppet::Parser::Files.expects(:find_manifests).returns [nil, []]
76
- lambda { @loader.import("myfile") }.should raise_error(Puppet::ImportError)
70
+ Puppet::Parser::Files.expects(:find_manifests_in_modules).returns [nil, []]
71
+ lambda { @loader.import("myfile", "/path") }.should raise_error(Puppet::ImportError)
77
72
  end
78
73
 
79
74
  it "should parse each found file" do
80
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", [make_absolute("/one")]]
75
+ Puppet::Parser::Files.expects(:find_manifests_in_modules).returns ["modname", [make_absolute("/one")]]
81
76
  @loader.expects(:parse_file).with(make_absolute("/one")).returns(Puppet::Parser::AST::Hostclass.new(''))
82
- @loader.import("myfile")
83
- end
84
-
85
- it "should make each file qualified before attempting to parse it" do
86
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{one}]
87
- @loader.expects(:parse_file).with(make_absolute("/current/one")).returns(Puppet::Parser::AST::Hostclass.new(''))
88
- @loader.import("myfile", make_absolute("/current/file"))
77
+ @loader.import("myfile", "/path")
89
78
  end
90
79
 
91
80
  it "should not attempt to import files that have already been imported" do
92
81
  @loader = Puppet::Parser::TypeLoader.new(:myenv)
93
82
 
94
- Puppet::Parser::Files.expects(:find_manifests).returns ["modname", %w{/one}]
83
+ Puppet::Parser::Files.expects(:find_manifests_in_modules).returns ["modname", %w{/one}]
95
84
  parser_class.any_instance.expects(:parse).once.returns(Puppet::Parser::AST::Hostclass.new(''))
96
85
  other_parser_class.any_instance.expects(:parse).never.returns(Puppet::Parser::AST::Hostclass.new(''))
97
- @loader.import("myfile")
86
+ @loader.import("myfile", "/path")
98
87
 
99
88
  # This will fail if it tries to reimport the file.
100
- @loader.import("myfile")
89
+ @loader.import("myfile", "/path")
101
90
  end
102
91
  end
103
92
 
@@ -219,7 +208,7 @@ describe Puppet::Parser::TypeLoader do
219
208
  it "should be able to add classes to the current resource type collection" do
220
209
  file = tmpfile("simple_file.pp")
221
210
  File.open(file, "w") { |f| f.puts "class foo {}" }
222
- @loader.import(file)
211
+ @loader.import(File.basename(file), File.dirname(file))
223
212
 
224
213
  @loader.known_resource_types.hostclass("foo").should be_instance_of(Puppet::Resource::Type)
225
214
  end
@@ -55,6 +55,14 @@ describe Puppet::Resource::TypeCollection do
55
55
  @code.node("foo").should equal(node)
56
56
  end
57
57
 
58
+ it "should fail if a duplicate node is added" do
59
+ @code.add(Puppet::Resource::Type.new(:node, "foo"))
60
+
61
+ expect do
62
+ @code.add(Puppet::Resource::Type.new(:node, "foo"))
63
+ end.to raise_error(Puppet::ParseError, /cannot redefine/)
64
+ end
65
+
58
66
  it "should store hostclasses as hostclasses" do
59
67
  klass = Puppet::Resource::Type.new(:hostclass, "foo")
60
68
 
@@ -62,6 +70,16 @@ describe Puppet::Resource::TypeCollection do
62
70
  @code.hostclass("foo").should equal(klass)
63
71
  end
64
72
 
73
+ it "merge together hostclasses of the same name" do
74
+ klass1 = Puppet::Resource::Type.new(:hostclass, "foo", :doc => "first")
75
+ klass2 = Puppet::Resource::Type.new(:hostclass, "foo", :doc => "second")
76
+
77
+ @code.add(klass1)
78
+ @code.add(klass2)
79
+
80
+ @code.hostclass("foo").doc.should == "firstsecond"
81
+ end
82
+
65
83
  it "should store definitions as definitions" do
66
84
  define = Puppet::Resource::Type.new(:definition, "foo")
67
85
 
@@ -69,13 +87,12 @@ describe Puppet::Resource::TypeCollection do
69
87
  @code.definition("foo").should equal(define)
70
88
  end
71
89
 
72
- it "should merge new classes with existing classes of the same name" do
73
- loader = Puppet::Resource::TypeCollection.new("env")
74
- first = Puppet::Resource::Type.new(:hostclass, "foo")
75
- second = Puppet::Resource::Type.new(:hostclass, "foo")
76
- loader.add first
77
- first.expects(:merge).with(second)
78
- loader.add(second)
90
+ it "should fail if a duplicate definition is added" do
91
+ @code.add(Puppet::Resource::Type.new(:definition, "foo"))
92
+
93
+ expect do
94
+ @code.add(Puppet::Resource::Type.new(:definition, "foo"))
95
+ end.to raise_error(Puppet::ParseError, /cannot be redefined/)
79
96
  end
80
97
 
81
98
  it "should remove all nodes, classes, and definitions when cleared" do
@@ -180,58 +197,27 @@ describe Puppet::Resource::TypeCollection do
180
197
  end
181
198
 
182
199
  %w{hostclass node definition}.each do |data|
183
- before do
184
- @instance = Puppet::Resource::Type.new(data, "foo")
185
- end
200
+ describe "behavior of add for #{data}" do
186
201
 
187
- it "should have a method for adding a #{data}" do
188
- Puppet::Resource::TypeCollection.new("env").should respond_to("add_#{data}")
189
- end
190
-
191
- it "should use the name of the instance to add it" do
192
- loader = Puppet::Resource::TypeCollection.new("env")
193
- loader.send("add_#{data}", @instance)
194
- loader.send(data, @instance.name).should equal(@instance)
195
- end
196
-
197
- unless data == "hostclass"
198
- it "should fail to add a #{data} when one already exists" do
202
+ it "should return the added #{data}" do
199
203
  loader = Puppet::Resource::TypeCollection.new("env")
200
- loader.add @instance
201
- lambda { loader.add(@instance) }.should raise_error(Puppet::ParseError)
202
- end
203
- end
204
-
205
- it "should return the added #{data}" do
206
- loader = Puppet::Resource::TypeCollection.new("env")
204
+ instance = Puppet::Resource::Type.new(data, "foo")
207
205
 
208
- loader.add(@instance).should equal(@instance)
209
- end
206
+ loader.add(instance).should equal(instance)
207
+ end
210
208
 
211
- it "should be able to retrieve #{data} by name" do
212
- loader = Puppet::Resource::TypeCollection.new("env")
213
- instance = Puppet::Resource::Type.new(data, "bar")
214
- loader.add instance
215
- loader.send(data, "bar").should equal(instance)
216
- end
209
+ it "should retrieve #{data} insensitive to case" do
210
+ loader = Puppet::Resource::TypeCollection.new("env")
211
+ instance = Puppet::Resource::Type.new(data, "Bar")
217
212
 
218
- it "should retrieve #{data} insensitive to case" do
219
- loader = Puppet::Resource::TypeCollection.new("env")
220
- instance = Puppet::Resource::Type.new(data, "Bar")
221
- loader.add instance
222
- loader.send(data, "bAr").should equal(instance)
223
- end
213
+ loader.add instance
224
214
 
225
- it "should return nil when asked for a #{data} that has not been added" do
226
- Puppet::Resource::TypeCollection.new("env").send(data, "foo").should be_nil
227
- end
215
+ loader.send(data, "bAr").should equal(instance)
216
+ end
228
217
 
229
- it "should be able to retrieve all #{data}s" do
230
- plurals = { "hostclass" => "hostclasses", "node" => "nodes", "definition" => "definitions" }
231
- loader = Puppet::Resource::TypeCollection.new("env")
232
- instance = Puppet::Resource::Type.new(data, "foo")
233
- loader.add instance
234
- loader.send(plurals[data]).should == { "foo" => instance }
218
+ it "should return nil when asked for a #{data} that has not been added" do
219
+ Puppet::Resource::TypeCollection.new("env").send(data, "foo").should be_nil
220
+ end
235
221
  end
236
222
  end
237
223
 
@@ -319,12 +305,12 @@ describe Puppet::Resource::TypeCollection do
319
305
  it "should only look in the topclass, if the name is qualified" do
320
306
  @loader.find_hostclass("foo", "::bar").name.should == 'bar'
321
307
  end
322
-
308
+
323
309
  it "should only look in the topclass, if we assume the name is fully qualified" do
324
310
  @loader.find_hostclass("foo", "bar", :assume_fqname => true).name.should == 'bar'
325
311
  end
326
312
  end
327
-
313
+
328
314
  it "should not look in the local scope for classes when the name is qualified" do
329
315
  @loader = Puppet::Resource::TypeCollection.new("env")
330
316
  @loader.add Puppet::Resource::Type.new(:hostclass, "foo::bar")
@@ -341,18 +327,6 @@ describe Puppet::Resource::TypeCollection do
341
327
  loader.find_node(stub("ignored"), "bar").should == node
342
328
  end
343
329
 
344
- it "should use the 'find_or_load' method to find hostclasses" do
345
- loader = Puppet::Resource::TypeCollection.new("env")
346
- loader.expects(:find_or_load).with("foo", "bar", :hostclass, {})
347
- loader.find_hostclass("foo", "bar")
348
- end
349
-
350
- it "should use the 'find_or_load' method to find definitions" do
351
- loader = Puppet::Resource::TypeCollection.new("env")
352
- loader.expects(:find_or_load).with("foo", "bar", :definition)
353
- loader.find_definition("foo", "bar")
354
- end
355
-
356
330
  it "should indicate whether any nodes are defined" do
357
331
  loader = Puppet::Resource::TypeCollection.new("env")
358
332
  loader.add_node(Puppet::Resource::Type.new(:node, "foo"))
@@ -458,7 +432,5 @@ describe Puppet::Resource::TypeCollection do
458
432
 
459
433
  lambda { @code.version }.should raise_error(Puppet::ParseError)
460
434
  end
461
-
462
435
  end
463
-
464
436
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: puppet
3
3
  version: !ruby/object:Gem::Version
4
- version: 3.2.3
4
+ version: 3.2.4
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2013-07-12 00:00:00.000000000 Z
12
+ date: 2013-08-14 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: facter
@@ -878,6 +878,7 @@ files:
878
878
  - lib/puppet/forge/repository.rb
879
879
  - lib/puppet/forge/cache.rb
880
880
  - lib/puppet/file_serving.rb
881
+ - lib/puppet/file_system/path_pattern.rb
881
882
  - lib/puppet/network/authentication.rb
882
883
  - lib/puppet/network/rights.rb
883
884
  - lib/puppet/network/rest_controller.rb
@@ -919,6 +920,7 @@ files:
919
920
  - lib/puppet/forge.rb
920
921
  - lib/puppet/data_binding.rb
921
922
  - lib/puppet/simple_graph.rb
923
+ - lib/puppet/file_system.rb
922
924
  - lib/puppet/daemon.rb
923
925
  - lib/puppet/network.rb
924
926
  - lib/puppet/parameter/value.rb
@@ -1969,6 +1971,7 @@ files:
1969
1971
  - spec/unit/forge/repository_spec.rb
1970
1972
  - spec/unit/forge/errors_spec.rb
1971
1973
  - spec/unit/daemon_spec.rb
1974
+ - spec/unit/file_system/path_pattern_spec.rb
1972
1975
  - spec/unit/status_spec.rb
1973
1976
  - spec/unit/network/authentication_spec.rb
1974
1977
  - spec/unit/network/rights_spec.rb
@@ -2878,6 +2881,7 @@ test_files:
2878
2881
  - spec/unit/forge/repository_spec.rb
2879
2882
  - spec/unit/forge/errors_spec.rb
2880
2883
  - spec/unit/daemon_spec.rb
2884
+ - spec/unit/file_system/path_pattern_spec.rb
2881
2885
  - spec/unit/status_spec.rb
2882
2886
  - spec/unit/network/authentication_spec.rb
2883
2887
  - spec/unit/network/rights_spec.rb