puppet 2.7.13 → 2.7.14

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.

Files changed (215) hide show
  1. data/CHANGELOG +144 -1
  2. data/conf/osx/preflight +1 -1
  3. data/conf/redhat/puppet.spec +9 -5
  4. data/conf/suse/puppet.spec +4 -1
  5. data/conf/windows/eventlog/Rakefile +32 -0
  6. data/conf/windows/eventlog/puppetres.dll +0 -0
  7. data/conf/windows/eventlog/puppetres.mc +18 -0
  8. data/ext/rack/files/apache2.conf +3 -0
  9. data/install.rb +23 -1
  10. data/lib/puppet.rb +1 -1
  11. data/lib/puppet/agent.rb +1 -14
  12. data/lib/puppet/application/kick.rb +1 -1
  13. data/lib/puppet/application/module.rb +11 -0
  14. data/lib/puppet/daemon.rb +74 -3
  15. data/lib/puppet/defaults.rb +1 -1
  16. data/lib/puppet/face/certificate.rb +1 -1
  17. data/lib/puppet/face/help/man.erb +1 -1
  18. data/lib/puppet/face/module.rb +17 -0
  19. data/lib/puppet/face/module/build.rb +10 -4
  20. data/lib/puppet/face/module/changes.rb +5 -5
  21. data/lib/puppet/face/module/generate.rb +6 -4
  22. data/lib/puppet/face/module/install.rb +122 -32
  23. data/lib/puppet/face/module/list.rb +234 -33
  24. data/lib/puppet/face/module/search.rb +56 -23
  25. data/lib/puppet/face/module/uninstall.rb +33 -38
  26. data/lib/puppet/face/module/upgrade.rb +84 -0
  27. data/lib/puppet/feature/eventlog.rb +6 -0
  28. data/lib/puppet/forge.rb +67 -122
  29. data/lib/puppet/forge/cache.rb +1 -1
  30. data/lib/puppet/forge/repository.rb +6 -25
  31. data/lib/puppet/indirector/facts/network_device.rb +1 -1
  32. data/lib/puppet/interface/action.rb +1 -1
  33. data/lib/puppet/module.rb +79 -28
  34. data/lib/puppet/module_tool.rb +72 -34
  35. data/lib/puppet/module_tool/applications.rb +12 -14
  36. data/lib/puppet/module_tool/applications/application.rb +21 -19
  37. data/lib/puppet/module_tool/applications/builder.rb +4 -4
  38. data/lib/puppet/module_tool/applications/checksummer.rb +12 -3
  39. data/lib/puppet/module_tool/applications/generator.rb +1 -1
  40. data/lib/puppet/module_tool/applications/installer.rb +163 -34
  41. data/lib/puppet/module_tool/applications/searcher.rb +2 -3
  42. data/lib/puppet/module_tool/applications/uninstaller.rb +84 -36
  43. data/lib/puppet/module_tool/applications/unpacker.rb +4 -26
  44. data/lib/puppet/module_tool/applications/upgrader.rb +109 -0
  45. data/lib/puppet/module_tool/checksums.rb +2 -2
  46. data/lib/puppet/module_tool/contents_description.rb +1 -1
  47. data/lib/puppet/module_tool/dependency.rb +2 -2
  48. data/lib/puppet/module_tool/errors.rb +9 -0
  49. data/lib/puppet/module_tool/errors/base.rb +15 -0
  50. data/lib/puppet/module_tool/errors/installer.rb +90 -0
  51. data/lib/puppet/module_tool/errors/shared.rb +115 -0
  52. data/lib/puppet/module_tool/errors/uninstaller.rb +45 -0
  53. data/lib/puppet/module_tool/errors/upgrader.rb +72 -0
  54. data/lib/puppet/module_tool/metadata.rb +2 -2
  55. data/lib/puppet/module_tool/modulefile.rb +7 -7
  56. data/lib/puppet/module_tool/shared_behaviors.rb +161 -0
  57. data/lib/puppet/module_tool/skeleton.rb +1 -1
  58. data/lib/puppet/node/environment.rb +4 -2
  59. data/lib/puppet/parser/ast/leaf.rb +1 -1
  60. data/lib/puppet/parser/functions/create_resources.rb +3 -2
  61. data/lib/puppet/parser/scope.rb +44 -9
  62. data/lib/puppet/provider/augeas/augeas.rb +2 -2
  63. data/lib/puppet/provider/exec.rb +8 -3
  64. data/lib/puppet/provider/exec/shell.rb +1 -2
  65. data/lib/puppet/provider/nameservice/directoryservice.rb +10 -4
  66. data/lib/puppet/provider/package/gem.rb +1 -1
  67. data/lib/puppet/provider/package/pkg.rb +10 -21
  68. data/lib/puppet/provider/selmodule/semodule.rb +1 -2
  69. data/lib/puppet/provider/service/upstart.rb +33 -17
  70. data/lib/puppet/provider/ssh_authorized_key/parsed.rb +1 -1
  71. data/lib/puppet/rails/inventory_node.rb +7 -7
  72. data/lib/puppet/reports/http.rb +4 -1
  73. data/lib/puppet/reports/tagmail.rb +8 -1
  74. data/lib/puppet/resource/type.rb +1 -1
  75. data/lib/puppet/test/test_helper.rb +138 -0
  76. data/lib/puppet/type.rb +9 -1
  77. data/lib/puppet/type/file.rb +18 -10
  78. data/lib/puppet/type/package.rb +13 -9
  79. data/lib/puppet/type/resources.rb +1 -1
  80. data/lib/puppet/type/ssh_authorized_key.rb +3 -4
  81. data/lib/puppet/type/sshkey.rb +4 -4
  82. data/lib/puppet/type/user.rb +1 -0
  83. data/lib/puppet/type/vlan.rb +1 -1
  84. data/lib/puppet/util.rb +31 -14
  85. data/lib/puppet/util/autoload.rb +1 -1
  86. data/lib/puppet/util/command_line.rb +2 -6
  87. data/lib/puppet/util/instrumentation/indirection_probe.rb +1 -1
  88. data/lib/puppet/util/instrumentation/instrumentable.rb +1 -1
  89. data/lib/puppet/util/instrumentation/listeners/log.rb +1 -1
  90. data/lib/puppet/util/instrumentation/listeners/performance.rb +1 -1
  91. data/lib/puppet/util/log.rb +3 -1
  92. data/lib/puppet/util/log/destinations.rb +38 -0
  93. data/lib/puppet/util/monkey_patches.rb +45 -0
  94. data/lib/puppet/util/network_device/base.rb +1 -1
  95. data/lib/puppet/util/network_device/cisco.rb +1 -1
  96. data/lib/puppet/util/network_device/cisco/facts.rb +1 -1
  97. data/lib/puppet/util/network_device/cisco/interface.rb +1 -1
  98. data/lib/puppet/util/network_device/config.rb +1 -1
  99. data/lib/puppet/util/network_device/ipcalc.rb +1 -1
  100. data/lib/puppet/util/network_device/transport.rb +1 -1
  101. data/lib/puppet/util/network_device/transport/base.rb +1 -1
  102. data/lib/puppet/util/network_device/transport/ssh.rb +1 -1
  103. data/lib/puppet/util/settings.rb +2 -11
  104. data/lib/puppet/util/settings/file_setting.rb +3 -5
  105. data/lib/puppet/util/terminal.rb +16 -0
  106. data/lib/puppet/util/zaml.rb +3 -1
  107. data/lib/semver.rb +15 -7
  108. data/spec/fixtures/releases/jamtur01-apache/metadata.json +1 -1
  109. data/spec/fixtures/unit/parser/lexer/arithmetic_expression.pp +1 -1
  110. data/spec/fixtures/unit/provider/package/pkg/dummy +1 -0
  111. data/spec/fixtures/unit/provider/package/pkg/incomplete +1 -0
  112. data/spec/fixtures/unit/provider/package/pkg/publisher +2 -0
  113. data/spec/fixtures/unit/provider/package/pkg/simple +4 -0
  114. data/spec/fixtures/unit/reports/tagmail/tagmail_email.conf +2 -0
  115. data/spec/fixtures/yaml/report0.25.x.yaml +1 -1
  116. data/spec/fixtures/yaml/report2.6.x.yaml +1 -1
  117. data/spec/integration/faces/documentation_spec.rb +1 -1
  118. data/spec/integration/network/rest_authconfig_spec.rb +1 -1
  119. data/spec/lib/puppet_spec/compiler.rb +6 -0
  120. data/spec/lib/puppet_spec/database.rb +30 -0
  121. data/spec/lib/puppet_spec/files.rb +4 -2
  122. data/spec/shared_behaviours/path_parameters.rb +2 -29
  123. data/spec/shared_contexts/platform.rb +43 -0
  124. data/spec/spec_helper.rb +36 -65
  125. data/spec/unit/agent_spec.rb +0 -32
  126. data/spec/unit/application/kick_spec.rb +2 -2
  127. data/spec/unit/daemon_spec.rb +1 -17
  128. data/spec/unit/face/module/install_spec.rb +158 -0
  129. data/spec/unit/face/module/list_spec.rb +182 -0
  130. data/spec/unit/face/module/search_spec.rb +163 -0
  131. data/spec/unit/face/module/uninstall_spec.rb +77 -0
  132. data/spec/unit/face/module/upgrade_spec.rb +26 -0
  133. data/spec/unit/forge/repository_spec.rb +0 -30
  134. data/spec/unit/forge_spec.rb +28 -86
  135. data/spec/unit/indirector/catalog/active_record_spec.rb +45 -65
  136. data/spec/unit/indirector/facts/inventory_active_record_spec.rb +5 -18
  137. data/spec/unit/indirector/resource/active_record_spec.rb +2 -11
  138. data/spec/unit/indirector/resource/ral_spec.rb +7 -2
  139. data/spec/unit/module_spec.rb +240 -107
  140. data/spec/unit/module_tool/application_spec.rb +3 -5
  141. data/spec/unit/module_tool/applications/application_spec.rb +19 -0
  142. data/spec/unit/module_tool/applications/installer_spec.rb +205 -0
  143. data/spec/unit/module_tool/applications/uninstaller_spec.rb +206 -0
  144. data/spec/unit/module_tool/applications/upgrader_spec.rb +37 -0
  145. data/spec/unit/module_tool/metadata_spec.rb +2 -2
  146. data/spec/unit/module_tool_spec.rb +109 -1
  147. data/spec/unit/node/environment_spec.rb +16 -1
  148. data/spec/unit/parser/ast/leaf_spec.rb +16 -1
  149. data/spec/unit/parser/collector_spec.rb +2 -12
  150. data/spec/unit/parser/functions/create_resources_spec.rb +135 -86
  151. data/spec/unit/parser/functions/generate_spec.rb +2 -10
  152. data/spec/unit/parser/scope_spec.rb +345 -16
  153. data/spec/unit/provider/augeas/augeas_spec.rb +19 -0
  154. data/spec/unit/provider/exec/shell_spec.rb +17 -14
  155. data/spec/unit/provider/exec/windows_spec.rb +1 -7
  156. data/spec/unit/provider/exec_spec.rb +35 -0
  157. data/spec/unit/provider/nameservice/directoryservice_spec.rb +10 -0
  158. data/spec/unit/provider/package/dpkg_spec.rb +2 -1
  159. data/spec/unit/provider/package/gem_spec.rb +15 -0
  160. data/spec/unit/provider/package/openbsd_spec.rb +5 -4
  161. data/spec/unit/provider/package/pacman_spec.rb +3 -2
  162. data/spec/unit/provider/package/pkg_spec.rb +56 -33
  163. data/spec/unit/provider/selmodule_spec.rb +11 -4
  164. data/spec/unit/provider/service/redhat_spec.rb +1 -3
  165. data/spec/unit/provider/service/smf_spec.rb +1 -3
  166. data/spec/unit/provider/service/upstart_spec.rb +38 -0
  167. data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +28 -0
  168. data/spec/unit/rails/host_spec.rb +6 -12
  169. data/spec/unit/rails/param_value_spec.rb +3 -8
  170. data/spec/unit/rails/resource_spec.rb +2 -8
  171. data/spec/unit/reports/http_spec.rb +47 -31
  172. data/spec/unit/reports/tagmail_spec.rb +77 -0
  173. data/spec/unit/resource/type_spec.rb +2 -2
  174. data/spec/unit/resource_spec.rb +18 -20
  175. data/spec/unit/semver_spec.rb +31 -13
  176. data/spec/unit/type/exec_spec.rb +8 -15
  177. data/spec/unit/type/group_spec.rb +0 -9
  178. data/spec/unit/type/package_spec.rb +10 -0
  179. data/spec/unit/type/resources_spec.rb +4 -5
  180. data/spec/unit/type/ssh_authorized_key_spec.rb +4 -15
  181. data/spec/unit/type/sshkey_spec.rb +9 -11
  182. data/spec/unit/type/user_spec.rb +123 -127
  183. data/spec/unit/type_spec.rb +20 -0
  184. data/spec/unit/util/command_line_spec.rb +2 -2
  185. data/spec/unit/util/instrumentation/data_spec.rb +1 -1
  186. data/spec/unit/util/instrumentation/indirection_probe_spec.rb +1 -1
  187. data/spec/unit/util/instrumentation/instrumentable_spec.rb +1 -1
  188. data/spec/unit/util/instrumentation/listener_spec.rb +1 -1
  189. data/spec/unit/util/instrumentation/listeners/log_spec.rb +1 -1
  190. data/spec/unit/util/instrumentation/listeners/performance_spec.rb +1 -1
  191. data/spec/unit/util/instrumentation_spec.rb +1 -1
  192. data/spec/unit/util/log/destinations_spec.rb +4 -8
  193. data/spec/unit/util/log_spec.rb +47 -0
  194. data/spec/unit/util/reference_spec.rb +1 -1
  195. data/spec/unit/util/settings/file_setting_spec.rb +9 -0
  196. data/spec/unit/util/settings_spec.rb +0 -53
  197. data/spec/unit/util/terminal_spec.rb +42 -0
  198. data/spec/unit/util/zaml_spec.rb +7 -0
  199. data/spec/unit/util_spec.rb +63 -20
  200. data/tasks/rake/manpages.rake +1 -1
  201. data/test/data/snippets/arithmetic_expression.pp +1 -1
  202. data/test/other/puppet.rb +0 -1
  203. data/test/util/log.rb +6 -6
  204. metadata +41 -16
  205. data/lib/puppet/external/event-loop.rb +0 -1
  206. data/lib/puppet/external/event-loop/better-definers.rb +0 -367
  207. data/lib/puppet/external/event-loop/event-loop.rb +0 -355
  208. data/lib/puppet/external/event-loop/signal-system.rb +0 -218
  209. data/lib/puppet/face/module/clean.rb +0 -30
  210. data/lib/puppet/module_tool/applications/cleaner.rb +0 -16
  211. data/lib/puppet/module_tool/skeleton/templates/generator/metadata.json +0 -12
  212. data/lib/puppet/module_tool/utils.rb +0 -5
  213. data/lib/puppet/module_tool/utils/interrogation.rb +0 -25
  214. data/spec/integration/module_tool_spec.rb +0 -475
  215. data/spec/unit/module_tool/uninstaller_spec.rb +0 -124
@@ -0,0 +1,45 @@
1
+ module Puppet::ModuleTool::Errors
2
+
3
+ class UninstallError < ModuleToolError; end
4
+
5
+ class NoVersionMatchesError < UninstallError
6
+ def initialize(options)
7
+ @module_name = options[:module_name]
8
+ @modules = options[:installed_modules]
9
+ @version = options[:version_range]
10
+ super "Could not uninstall '#{@module_name}'; no installed version matches"
11
+ end
12
+
13
+ def multiline
14
+ message = []
15
+ message << "Could not uninstall module '#{@module_name}' (#{v(@version)})"
16
+ message << " No installed version of '#{@module_name}' matches (#{v(@version)})"
17
+ message += @modules.map do |mod|
18
+ " '#{mod[:name]}' (#{v(mod[:version])}) is installed in #{mod[:path]}"
19
+ end
20
+ message.join("\n")
21
+ end
22
+ end
23
+
24
+ class ModuleIsRequiredError < UninstallError
25
+ def initialize(options)
26
+ @module_name = options[:module_name]
27
+ @required_by = options[:required_by]
28
+ @requested_version = options[:requested_version]
29
+ @installed_version = options[:installed_version]
30
+
31
+ super "Could not uninstall '#{@module_name}'; installed modules still depend upon it"
32
+ end
33
+
34
+ def multiline
35
+ message = []
36
+ message << ("Could not uninstall module '#{@module_name}'" << (@requested_version ? " (#{v(@requested_version)})" : ''))
37
+ message << " Other installed modules have dependencies on '#{@module_name}' (#{v(@installed_version)})"
38
+ message += @required_by.map do |mod|
39
+ " '#{mod['name']}' (#{v(mod['version'])}) requires '#{@module_name}' (#{v(mod['version_requirement'])})"
40
+ end
41
+ message << " Use `puppet module uninstall --force` to uninstall this module anyway"
42
+ message.join("\n")
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,72 @@
1
+ module Puppet::ModuleTool::Errors
2
+
3
+ class UpgradeError < ModuleToolError
4
+ def initialize(msg)
5
+ @action = :upgrade
6
+ super
7
+ end
8
+ end
9
+
10
+ class VersionAlreadyInstalledError < UpgradeError
11
+ def initialize(options)
12
+ @module_name = options[:module_name]
13
+ @requested_version = options[:requested_version]
14
+ @installed_version = options[:installed_version]
15
+ @dependency_name = options[:dependency_name]
16
+ @conditions = options[:conditions]
17
+ super "Could not upgrade '#{@module_name}'; module is not installed"
18
+ end
19
+
20
+ def multiline
21
+ message = []
22
+ message << "Could not upgrade module '#{@module_name}' (#{vstring})"
23
+ if @conditions.length == 1 && @conditions.last[:version].nil?
24
+ message << " The installed version is already the latest version"
25
+ else
26
+ message << " The installed version is already the best fit for the current dependencies"
27
+ message += @conditions.select { |c| c[:module] == :you && c[:version] }.map do |c|
28
+ " You specified '#{@module_name}' (#{v(c[:version])})"
29
+ end
30
+ message += @conditions.select { |c| c[:module] != :you }.sort_by { |c| c[:module] }.map do |c|
31
+ " '#{c[:module]}' (#{v(c[:version])}) requires '#{@module_name}' (#{v(c[:dependency])})"
32
+ end
33
+ end
34
+ message << " Use `puppet module install --force` to re-install this module"
35
+ message.join("\n")
36
+ end
37
+ end
38
+
39
+ class UnknownModuleError < UpgradeError
40
+ def initialize(options)
41
+ @module_name = options[:module_name]
42
+ @installed_version = options[:installed_version]
43
+ @requested_version = options[:requested_version]
44
+ @repository = options[:repository]
45
+ super "Could not upgrade '#{@module_name}'; module is unknown to #{@repository}"
46
+ end
47
+
48
+ def multiline
49
+ message = []
50
+ message << "Could not upgrade module '#{@module_name}' (#{vstring})"
51
+ message << " Module '#{@module_name}' does not exist on #{@repository}"
52
+ message.join("\n")
53
+ end
54
+ end
55
+
56
+ class UnknownVersionError < UpgradeError
57
+ def initialize(options)
58
+ @module_name = options[:module_name]
59
+ @installed_version = options[:installed_version]
60
+ @requested_version = options[:requested_version]
61
+ @repository = options[:repository]
62
+ super "Could not upgrade '#{@module_name}' (#{vstring}); module has no versions #{ @requested_version && "matching #{v(@requested_version)} "}published on #{@repository}"
63
+ end
64
+
65
+ def multiline
66
+ message = []
67
+ message << "Could not upgrade module '#{@module_name}' (#{vstring})"
68
+ message << " No version matching '#{@requested_version || ">= 0.0.0"}' exists on #{@repository}"
69
+ message.join("\n")
70
+ end
71
+ end
72
+ end
@@ -1,4 +1,4 @@
1
- module Puppet::Module::Tool
1
+ module Puppet::ModuleTool
2
2
 
3
3
  # = Metadata
4
4
  #
@@ -31,7 +31,7 @@ module Puppet::Module::Tool
31
31
  # module +name+.
32
32
  def full_module_name=(full_module_name)
33
33
  @full_module_name = full_module_name
34
- @username, @name = Puppet::Module::Tool::username_and_modname_from(full_module_name)
34
+ @username, @name = Puppet::ModuleTool::username_and_modname_from(full_module_name)
35
35
  end
36
36
 
37
37
  # Return an array of the module's Dependency objects.
@@ -1,4 +1,4 @@
1
- module Puppet::Module::Tool
1
+ module Puppet::ModuleTool
2
2
 
3
3
  # = Modulefile
4
4
  #
@@ -10,13 +10,13 @@ module Puppet::Module::Tool
10
10
  # Read the +filename+ and eval its Ruby code to set values in the Metadata
11
11
  # +metadata+ instance.
12
12
  def self.evaluate(metadata, filename)
13
- returning(new(metadata)) do |builder|
14
- if File.file?(filename)
15
- builder.instance_eval(File.read(filename.to_s), filename.to_s, 1)
16
- else
17
- Puppet.warning "No Modulefile: #{filename}"
18
- end
13
+ builder = new(metadata)
14
+ if File.file?(filename)
15
+ builder.instance_eval(File.read(filename.to_s), filename.to_s, 1)
16
+ else
17
+ Puppet.warning "No Modulefile: #{filename}"
19
18
  end
19
+ return builder
20
20
  end
21
21
 
22
22
  # Instantiate with the Metadata +metadata+ instance.
@@ -0,0 +1,161 @@
1
+ module Puppet::ModuleTool::Shared
2
+
3
+ include Puppet::ModuleTool::Errors
4
+
5
+ def get_local_constraints
6
+ @local = Hash.new { |h,k| h[k] = { } }
7
+ @conditions = Hash.new { |h,k| h[k] = [] }
8
+ @installed = Hash.new { |h,k| h[k] = [] }
9
+
10
+ @environment.modules_by_path.values.flatten.each do |mod|
11
+ mod_name = (mod.forge_name || mod.name).gsub('/', '-')
12
+ @installed[mod_name] << mod
13
+ d = @local["#{mod_name}@#{mod.version}"]
14
+ (mod.dependencies || []).each do |hash|
15
+ name, conditions = hash['name'], hash['version_requirement']
16
+ name = name.gsub('/', '-')
17
+ d[name] = conditions
18
+ @conditions[name] << {
19
+ :module => mod_name,
20
+ :version => mod.version,
21
+ :dependency => conditions
22
+ }
23
+ end
24
+ end
25
+ end
26
+
27
+ def get_remote_constraints
28
+ @remote = Hash.new { |h,k| h[k] = { } }
29
+ @urls = {}
30
+ @versions = Hash.new { |h,k| h[k] = [] }
31
+
32
+ Puppet.notice "Downloading from #{Puppet::Forge.repository.uri} ..."
33
+ author, modname = Puppet::ModuleTool.username_and_modname_from(@module_name)
34
+ info = Puppet::Forge.remote_dependency_info(author, modname, @options[:version])
35
+ info.each do |pair|
36
+ mod_name, releases = pair
37
+ mod_name = mod_name.gsub('/', '-')
38
+ releases.each do |rel|
39
+ semver = SemVer.new(rel['version'] || '0.0.0') rescue SemVer.MIN
40
+ @versions[mod_name] << { :vstring => rel['version'], :semver => semver }
41
+ @versions[mod_name].sort! { |a, b| a[:semver] <=> b[:semver] }
42
+ @urls["#{mod_name}@#{rel['version']}"] = rel['file']
43
+ d = @remote["#{mod_name}@#{rel['version']}"]
44
+ (rel['dependencies'] || []).each do |name, conditions|
45
+ d[name.gsub('/', '-')] = conditions
46
+ end
47
+ end
48
+ end
49
+ end
50
+
51
+ def implicit_version(mod)
52
+ return :latest if @conditions[mod].empty?
53
+ if @conditions[mod].all? { |c| c[:queued] || c[:module] == :you }
54
+ return :latest
55
+ end
56
+ return :best
57
+ end
58
+
59
+ def annotated_version(mod, versions)
60
+ if versions.empty?
61
+ return implicit_version(mod)
62
+ else
63
+ return "#{implicit_version(mod)}: #{versions.last}"
64
+ end
65
+ end
66
+
67
+ def resolve_constraints(dependencies, source = [{:name => :you}], seen = {}, action = @action)
68
+ dependencies = dependencies.map do |mod, range|
69
+ source.last[:dependency] = range
70
+
71
+ @conditions[mod] << {
72
+ :module => source.last[:name],
73
+ :version => source.last[:version],
74
+ :dependency => range,
75
+ :queued => true
76
+ }
77
+
78
+ if @force
79
+ range = SemVer[@version] rescue SemVer['>= 0.0.0']
80
+ else
81
+ range = (@conditions[mod]).map do |r|
82
+ SemVer[r[:dependency]] rescue SemVer['>= 0.0.0']
83
+ end.inject(&:&)
84
+ end
85
+
86
+ if @action == :install && seen.include?(mod)
87
+ next if range === seen[mod][:semver]
88
+
89
+ req_module = @module_name
90
+ req_versions = @versions["#{@module_name}"].map { |v| v[:semver] }
91
+ raise InvalidDependencyCycleError,
92
+ :module_name => mod,
93
+ :source => (source + [{ :name => mod, :version => source.last[:dependency] }]),
94
+ :requested_module => req_module,
95
+ :requested_version => @version || annotated_version(req_module, req_versions),
96
+ :conditions => @conditions
97
+ end
98
+
99
+ if !(@force || @installed[mod].empty? || source.last[:name] == :you)
100
+ next if range === SemVer.new(@installed[mod].first.version)
101
+ action = :upgrade
102
+ elsif @installed[mod].empty?
103
+ action = :install
104
+ end
105
+
106
+ if action == :upgrade
107
+ @conditions.each { |_, conds| conds.delete_if { |c| c[:module] == mod } }
108
+ end
109
+
110
+ valid_versions = @versions["#{mod}"].select { |h| range === h[:semver] }
111
+
112
+ unless version = valid_versions.last
113
+ req_module = @module_name
114
+ req_versions = @versions["#{@module_name}"].map { |v| v[:semver] }
115
+ raise NoVersionsSatisfyError,
116
+ :requested_name => req_module,
117
+ :requested_version => @version || annotated_version(req_module, req_versions),
118
+ :installed_version => @installed[@module_name].empty? ? nil : @installed[@module_name].first.version,
119
+ :dependency_name => mod,
120
+ :conditions => @conditions[mod],
121
+ :action => @action
122
+ end
123
+
124
+ seen[mod] = version
125
+
126
+ {
127
+ :module => mod,
128
+ :version => version,
129
+ :action => action,
130
+ :previous_version => @installed[mod].empty? ? nil : @installed[mod].first.version,
131
+ :file => @urls["#{mod}@#{version[:vstring]}"],
132
+ :path => action == :install ? @options[:target_dir] : (@installed[mod].empty? ? @options[:target_dir] : @installed[mod].first.modulepath),
133
+ :dependencies => []
134
+ }
135
+ end.compact
136
+ dependencies.each do |mod|
137
+ deps = @remote["#{mod[:module]}@#{mod[:version][:vstring]}"].sort_by(&:first)
138
+ mod[:dependencies] = resolve_constraints(deps, source + [{ :name => mod[:module], :version => mod[:version][:vstring] }], seen, :install)
139
+ end unless @ignore_dependencies
140
+ return dependencies
141
+ end
142
+
143
+ def download_tarballs(graph, default_path)
144
+ graph.map do |release|
145
+ begin
146
+ if release[:tarball]
147
+ cache_path = Pathname(release[:tarball])
148
+ else
149
+ cache_path = Puppet::Forge.repository.retrieve(release[:file])
150
+ end
151
+ rescue OpenURI::HTTPError => e
152
+ raise RuntimeError, "Could not download module: #{e.message}"
153
+ end
154
+
155
+ [
156
+ { (release[:path] ||= default_path) => cache_path},
157
+ *download_tarballs(release[:dependencies], default_path)
158
+ ]
159
+ end.flatten
160
+ end
161
+ end
@@ -1,4 +1,4 @@
1
- module Puppet::Module::Tool
1
+ module Puppet::ModuleTool
2
2
 
3
3
  # = Skeleton
4
4
  #
@@ -127,8 +127,10 @@ class Puppet::Node::Environment
127
127
  modules_by_path = {}
128
128
  modulepath.each do |path|
129
129
  Dir.chdir(path) do
130
- module_names = Dir.glob('*').select { |d| FileTest.directory? d }
131
- modules_by_path[path] = module_names.map do |name|
130
+ module_names = Dir.glob('*').select do |d|
131
+ FileTest.directory?(d) && (File.basename(d) =~ /^[\w]+([-]{1}[\w]+)*$/)
132
+ end
133
+ modules_by_path[path] = module_names.sort.map do |name|
132
134
  Puppet::Module.new(name, :environment => self, :path => File.join(path, name))
133
135
  end
134
136
  end
@@ -202,7 +202,7 @@ class Puppet::Parser::AST
202
202
  end
203
203
 
204
204
  def evaluate_match(value, scope, options = {})
205
- value = value.is_a?(String) ? value : value.to_s
205
+ value = value == :undef ? '' : value.to_s
206
206
 
207
207
  if matched = @value.match(value)
208
208
  scope.ephemeral_from(matched, options[:file], options[:line])
@@ -51,14 +51,15 @@ Puppet::Parser::Functions::newfunction(:create_resources, :doc => <<-'ENDHEREDOC
51
51
  # iterate through the resources to create
52
52
  defaults = args[2] || {}
53
53
  args[1].each do |title, params|
54
- raise ArgumentError, 'params should not contain title' if(params['title'])
55
54
  params = defaults.merge(params)
55
+ Puppet::Util.symbolizehash!(params)
56
+ raise ArgumentError, 'params should not contain title' if(params[:title])
56
57
  case type_of_resource
57
58
  # JJM The only difference between a type and a define is the call to instantiate_resource
58
59
  # for a defined type.
59
60
  when :type, :define
60
61
  p_resource = Puppet::Parser::Resource.new(type_name, title, :scope => self, :source => resource)
61
- params.merge(:name => title).each do |k,v|
62
+ {:name => title}.merge(params).each do |k,v|
62
63
  p_resource.set_parameter(k,v)
63
64
  end
64
65
  if type_of_resource == :define then
@@ -21,7 +21,7 @@ class Puppet::Parser::Scope
21
21
  attr_accessor :source, :resource
22
22
  attr_accessor :base, :keyword
23
23
  attr_accessor :top, :translated, :compiler
24
- attr_accessor :parent, :dynamic
24
+ attr_accessor :parent
25
25
  attr_reader :namespaces
26
26
 
27
27
  # thin wrapper around an ephemeral
@@ -222,13 +222,52 @@ class Puppet::Parser::Scope
222
222
 
223
223
  private :qualified_scope
224
224
 
225
- # Look up a variable. The simplest value search we do.
225
+ # Look up a variable with traditional scoping and then with new scoping. If
226
+ # the answers differ then print a deprecation warning.
226
227
  def lookupvar(name, options = {})
228
+ dynamic_value = dynamic_lookupvar(name,options)
229
+ twoscope_value = twoscope_lookupvar(name,options)
230
+ if dynamic_value != twoscope_value
231
+ location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : ''
232
+ Puppet.deprecation_warning("Dynamic lookup of $#{name}#{location} is deprecated. For more information, see http://docs.puppetlabs.com/guides/scope_and_puppet.html. To see the change in behavior, use the --debug flag.")
233
+ Puppet.debug("Currently $#{name} is #{dynamic_value.inspect}")
234
+ Puppet.debug("In the future $#{name} will be #{twoscope_value == :undefined ? "undefined" : twoscope_value.inspect}")
235
+ end
236
+ dynamic_value
237
+ end
238
+
239
+ # Look up a variable. The simplest value search we do.
240
+ def twoscope_lookupvar(name, options = {})
241
+ # Save the originating scope for the request
242
+ options[:origin] = self unless options[:origin]
243
+ table = ephemeral?(name) ? @ephemeral.last : @symtable
244
+ if name =~ /^(.*)::(.+)$/
245
+ begin
246
+ qualified_scope($1).twoscope_lookupvar($2, options.merge({:origin => nil}))
247
+ rescue RuntimeError => e
248
+ location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : ''
249
+ warning "Could not look up qualified variable '#{name}'; #{e.message}#{location}"
250
+ :undefined
251
+ end
252
+ # If the value is present and either we are top/node scope or originating scope...
253
+ elsif (ephemeral_include?(name) or table.include?(name)) and (compiler and self == compiler.topscope or (self.resource and self.resource.type == "Node") or self == options[:origin])
254
+ table[name]
255
+ elsif resource and resource.type == "Class" and parent_type = resource.resource_type.parent
256
+ class_scope(parent_type).twoscope_lookupvar(name,options.merge({:origin => nil}))
257
+ elsif parent
258
+ parent.twoscope_lookupvar(name, options)
259
+ else
260
+ :undefined
261
+ end
262
+ end
263
+
264
+ # Look up a variable. The simplest value search we do.
265
+ def dynamic_lookupvar(name, options = {})
227
266
  table = ephemeral?(name) ? @ephemeral.last : @symtable
228
267
  # If the variable is qualified, then find the specified scope and look the variable up there instead.
229
268
  if name =~ /^(.*)::(.+)$/
230
269
  begin
231
- qualified_scope($1).lookupvar($2,options)
270
+ qualified_scope($1).dynamic_lookupvar($2,options)
232
271
  rescue RuntimeError => e
233
272
  location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : ''
234
273
  warning "Could not look up qualified variable '#{name}'; #{e.message}#{location}"
@@ -236,13 +275,9 @@ class Puppet::Parser::Scope
236
275
  end
237
276
  elsif ephemeral_include?(name) or table.include?(name)
238
277
  # We can't use "if table[name]" here because the value might be false
239
- if options[:dynamic] and self != compiler.topscope
240
- location = (options[:file] && options[:line]) ? " at #{options[:file]}:#{options[:line]}" : ''
241
- Puppet.deprecation_warning "Dynamic lookup of $#{name}#{location} is deprecated. Support will be removed in Puppet 2.8. Use a fully-qualified variable name (e.g., $classname::variable) or parameterized classes."
242
- end
243
278
  table[name]
244
279
  elsif parent
245
- parent.lookupvar(name,options.merge(:dynamic => (dynamic || options[:dynamic])))
280
+ parent.dynamic_lookupvar(name,options)
246
281
  else
247
282
  :undefined
248
283
  end
@@ -374,7 +409,7 @@ class Puppet::Parser::Scope
374
409
 
375
410
  # check if name exists in one of the ephemeral scope.
376
411
  def ephemeral_include?(name)
377
- @ephemeral.reverse.each do |eph|
412
+ @ephemeral.reverse_each do |eph|
378
413
  return true if eph.include?(name)
379
414
  end
380
415
  false