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
@@ -1,8 +1,11 @@
1
+ require 'puppet/util/terminal'
2
+
1
3
  Puppet::Face.define(:module, '1.0.0') do
2
4
  action(:search) do
3
5
  summary "Search a repository for a module."
4
6
  description <<-EOT
5
- Search a repository for modules whose names match a specific substring.
7
+ Searches a repository for modules whose names, descriptions, or keywords
8
+ match the provided search term.
6
9
  EOT
7
10
 
8
11
  returns "Array of module metadata hashes"
@@ -15,41 +18,71 @@ Puppet::Face.define(:module, '1.0.0') do
15
18
  bacula This is a generic Apache module @puppetlabs backups
16
19
  EOT
17
20
 
18
- arguments "<term>"
19
-
20
- option "--module-repository=", "-r=" do
21
- default_to { Puppet.settings[:module_repository] }
22
- summary "Module repository to use."
23
- description <<-EOT
24
- Module repository to use.
25
- EOT
26
- end
21
+ arguments "<search_term>"
27
22
 
28
23
  when_invoked do |term, options|
29
- Puppet::Module::Tool::Applications::Searcher.run(term, options)
24
+ Puppet::ModuleTool::Applications::Searcher.run(term, options)
30
25
  end
31
26
 
32
- when_rendering :console do |return_value|
27
+ when_rendering :console do |results, term, options|
28
+ return "No results found for '#{term}'." if results.empty?
29
+
30
+ padding = ' '
31
+ headers = {
32
+ 'full_name' => 'NAME',
33
+ 'desc' => 'DESCRIPTION',
34
+ 'author' => 'AUTHOR',
35
+ 'tag_list' => 'KEYWORDS',
36
+ }
33
37
 
34
- FORMAT = "%-10s %-32s %-14s %s\n"
38
+ min_widths = Hash[ *headers.map { |k,v| [k, v.length] }.flatten ]
39
+ min_widths['full_name'] = min_widths['author'] = 12
35
40
 
36
- def header
37
- FORMAT % ['NAME', 'DESCRIPTION', 'AUTHOR', 'KEYWORDS']
41
+ min_width = min_widths.inject(0) { |sum,pair| sum += pair.last } + (padding.length * (headers.length - 1))
42
+
43
+ terminal_width = [Puppet::Util::Terminal.width, min_width].max
44
+
45
+ columns = results.inject(min_widths) do |hash, result|
46
+ {
47
+ 'full_name' => [ hash['full_name'], result['full_name'].length ].max,
48
+ 'desc' => [ hash['desc'], result['desc'].length ].max,
49
+ 'author' => [ hash['author'], "@#{result['author']}".length ].max,
50
+ 'tag_list' => [ hash['tag_list'], result['tag_list'].join(' ').length ].max,
51
+ }
38
52
  end
39
53
 
40
- def format_row(name, description, author, tag_list)
41
- keywords = tag_list.join(' ')
42
- FORMAT % [name[0..10], description[0..32], "@#{author[0..14]}", keywords]
54
+ flex_width = terminal_width - columns['full_name'] - columns['author'] - (padding.length * (headers.length - 1))
55
+ tag_lists = results.map { |r| r['tag_list'] }
56
+
57
+ while (columns['tag_list'] > flex_width / 3)
58
+ longest_tag_list = tag_lists.sort_by { |tl| tl.join(' ').length }.last
59
+ break if [ [], [term] ].include? longest_tag_list
60
+ longest_tag_list.delete(longest_tag_list.sort_by { |t| t == term ? -1 : t.length }.last)
61
+ columns['tag_list'] = tag_lists.map { |tl| tl.join(' ').length }.max
43
62
  end
44
63
 
45
- output = ''
46
- output << header unless return_value.empty?
64
+ columns['tag_list'] = [
65
+ flex_width / 3,
66
+ tag_lists.map { |tl| tl.join(' ').length }.max,
67
+ ].max
68
+ columns['desc'] = flex_width - columns['tag_list']
69
+
70
+ format = %w{full_name desc author tag_list}.map do |k|
71
+ "%-#{ [ columns[k], min_widths[k] ].max }s"
72
+ end.join(padding) + "\n"
47
73
 
48
- return_value.map do |match|
49
- output << format_row(match['name'], match['desc'], match['author'], match['tag_list'])
74
+ highlight = proc do |s|
75
+ s = s.gsub(term, colorize(:green, term))
76
+ s = s.gsub(term.gsub('/', '-'), colorize(:green, term.gsub('/', '-'))) if term =~ /\//
77
+ s
50
78
  end
51
79
 
52
- output
80
+ format % [ headers['full_name'], headers['desc'], headers['author'], headers['tag_list'] ] +
81
+ results.map do |match|
82
+ name, desc, author, keywords = %w{full_name desc author tag_list}.map { |k| match[k] }
83
+ desc = desc[0...(columns['desc'] - 3)] + '...' if desc.length > columns['desc']
84
+ highlight[format % [ name.sub('/', '-'), desc, "@#{author}", [keywords].flatten.join(' ') ]]
85
+ end.join
53
86
  end
54
87
  end
55
88
  end
@@ -2,50 +2,57 @@ Puppet::Face.define(:module, '1.0.0') do
2
2
  action(:uninstall) do
3
3
  summary "Uninstall a puppet module."
4
4
  description <<-EOT
5
- Uninstall a puppet module from the modulepath or a specific
6
- target directory which defaults to
7
- #{Puppet.settings[:modulepath].split(File::PATH_SEPARATOR).join(', ')}.
5
+ Uninstalls a puppet module from the modulepath (or a specific
6
+ target directory).
8
7
  EOT
9
8
 
10
9
  returns "Hash of module objects representing uninstalled modules and related errors."
11
10
 
12
11
  examples <<-EOT
13
- Uninstall a module from all directories in the modulepath:
12
+ Uninstall a module:
14
13
 
15
- $ puppet module uninstall ssh
14
+ $ puppet module uninstall puppetlabs-ssh
16
15
  Removed /etc/puppet/modules/ssh (v1.0.0)
17
16
 
18
17
  Uninstall a module from a specific directory:
19
18
 
20
- $ puppet module uninstall --modulepath /usr/share/puppet/modules ssh
19
+ $ puppet module uninstall puppetlabs-ssh --modulepath /usr/share/puppet/modules
21
20
  Removed /usr/share/puppet/modules/ssh (v1.0.0)
22
21
 
23
22
  Uninstall a module from a specific environment:
24
23
 
25
- $ puppet module uninstall --environment development
24
+ $ puppet module uninstall puppetlabs-ssh --environment development
26
25
  Removed /etc/puppet/environments/development/modules/ssh (v1.0.0)
27
-
26
+
28
27
  Uninstall a specific version of a module:
29
28
 
30
- $ puppet module uninstall --version 2.0.0 ssh
29
+ $ puppet module uninstall puppetlabs-ssh --version 2.0.0
31
30
  Removed /etc/puppet/modules/ssh (v2.0.0)
32
31
  EOT
33
32
 
34
33
  arguments "<name>"
35
34
 
36
- option "--environment=NAME", "--env=NAME" do
35
+ option "--force", "-f" do
36
+ summary "Force uninstall of an installed module."
37
+ description <<-EOT
38
+ Force the uninstall of an installed module even if there are local
39
+ changes or the possibility of causing broken dependencies.
40
+ EOT
41
+ end
42
+
43
+ option "--environment NAME" do
37
44
  default_to { "production" }
38
- summary "The target environment to search for modules."
45
+ summary "The target environment to uninstall modules from."
39
46
  description <<-EOT
40
- The target environment to search for modules.
47
+ The target environment to uninstall modules from.
41
48
  EOT
42
49
  end
43
-
50
+
44
51
  option "--version=" do
45
52
  summary "The version of the module to uninstall"
46
53
  description <<-EOT
47
- The version of the module to uninstall. When using this option a module
48
- that matches the specified version must be installed or an error is raised.
54
+ The version of the module to uninstall. When using this option, a module
55
+ matching the specified version must be installed or else an error is raised.
49
56
  EOT
50
57
  end
51
58
 
@@ -57,35 +64,23 @@ Puppet::Face.define(:module, '1.0.0') do
57
64
  end
58
65
 
59
66
  when_invoked do |name, options|
60
- if options[:modulepath]
61
- unless File.directory?(options[:modulepath])
62
- raise ArgumentError, "Directory #{options[:modulepath]} does not exist"
63
- end
64
- end
65
-
66
67
  Puppet[:modulepath] = options[:modulepath] if options[:modulepath]
67
- options[:name] = name
68
+ name = name.gsub('/', '-')
68
69
 
69
- Puppet::Module::Tool::Applications::Uninstaller.run(name, options)
70
+ Puppet.notice "Preparing to uninstall '#{name}'" << (options[:version] ? " (#{colorize(:cyan, options[:version].sub(/^(?=\d)/, 'v'))})" : '') << " ..."
71
+ Puppet::ModuleTool::Applications::Uninstaller.run(name, options)
70
72
  end
71
73
 
72
74
  when_rendering :console do |return_value|
73
- output = ''
74
-
75
- return_value[:removed_mods].each do |mod|
76
- output << "Removed #{mod.path} (v#{mod.version})\n"
75
+ if return_value[:result] == :failure
76
+ Puppet.err(return_value[:error][:multiline])
77
+ exit 1
78
+ else
79
+ mod = return_value[:affected_modules].first
80
+ "Removed '#{return_value[:module_name]}'" <<
81
+ (mod.version ? " (#{colorize(:cyan, mod.version.to_s.sub(/^(?=\d)/, 'v'))})" : '') <<
82
+ " from #{mod.modulepath}"
77
83
  end
78
-
79
- return_value[:errors].map do |mod_name, errors|
80
- if ! errors.empty?
81
- header = "Could not uninstall module #{return_value[:options][:name]}"
82
- header << " (v#{return_value[:options][:version]})" if return_value[:options][:version]
83
- output << "#{header}:\n"
84
- errors.map { |error| output << " #{error}\n" }
85
- end
86
- end
87
-
88
- output
89
84
  end
90
85
  end
91
86
  end
@@ -0,0 +1,84 @@
1
+ # encoding: UTF-8
2
+
3
+ Puppet::Face.define(:module, '1.0.0') do
4
+ action(:upgrade) do
5
+ summary "Upgrade a puppet module."
6
+ description <<-EOT
7
+ Upgrades a puppet module.
8
+ EOT
9
+
10
+ returns "Hash"
11
+
12
+ examples <<-EOT
13
+ upgrade an installed module to the latest version
14
+
15
+ $ puppet module upgrade puppetlabs-apache
16
+ /etc/puppet/modules
17
+ └── puppetlabs-apache (v1.0.0 -> v2.4.0)
18
+
19
+ upgrade an installed module to a specific version
20
+
21
+ $ puppet module upgrade puppetlabs-apache --version 2.1.0
22
+ /etc/puppet/modules
23
+ └── puppetlabs-apache (v1.0.0 -> v2.1.0)
24
+
25
+ upgrade an installed module for a specific environment
26
+
27
+ $ puppet module upgrade puppetlabs-apache --environment test
28
+ /usr/share/puppet/environments/test/modules
29
+ └── puppetlabs-apache (v1.0.0 -> v2.4.0)
30
+ EOT
31
+
32
+ arguments "<name>"
33
+
34
+ option "--force", "-f" do
35
+ summary "Force upgrade of an installed module."
36
+ description <<-EOT
37
+ Force the upgrade of an installed module even if there are local
38
+ changes or the possibility of causing broken dependencies.
39
+ EOT
40
+ end
41
+
42
+ option "--ignore-dependencies" do
43
+ summary "Do not attempt to install dependencies."
44
+ description <<-EOT
45
+ Do not attempt to install dependencies
46
+ EOT
47
+ end
48
+
49
+ option "--environment NAME" do
50
+ default_to { "production" }
51
+ summary "The target environment to search for modules."
52
+ description <<-EOT
53
+ The target environment to search for modules.
54
+ EOT
55
+ end
56
+
57
+ option "--version=" do
58
+ summary "The version of the module to upgrade to."
59
+ description <<-EOT
60
+ The version of the module to upgrade to.
61
+ EOT
62
+ end
63
+
64
+ when_invoked do |name, options|
65
+ name = name.gsub('/', '-')
66
+ Puppet.notice "Preparing to upgrade '#{name}' ..."
67
+ Puppet::ModuleTool::Applications::Upgrader.new(name, options).run
68
+ end
69
+
70
+ when_rendering :console do |return_value|
71
+ if return_value[:result] == :failure
72
+ Puppet.err(return_value[:error][:multiline])
73
+ exit 1
74
+ elsif return_value[:result] == :noop
75
+ Puppet.err(return_value[:error][:multiline])
76
+ exit 0
77
+ else
78
+ tree = Puppet::ModuleTool.build_tree(return_value[:affected_modules], return_value[:base_dir])
79
+ return_value[:base_dir] + "\n" +
80
+ Puppet::ModuleTool.format_tree(tree)
81
+ end
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,6 @@
1
+ require 'puppet/util/feature'
2
+
3
+ if Puppet.features.microsoft_windows?
4
+ Puppet.features.rubygems?
5
+ Puppet.features.add(:eventlog, :libs => %{win32/eventlog})
6
+ end
@@ -6,148 +6,93 @@ require 'puppet/forge/cache'
6
6
  require 'puppet/forge/repository'
7
7
 
8
8
  module Puppet::Forge
9
- class Forge
10
- def initialize(url=Puppet.settings[:module_repository])
11
- @uri = URI.parse(url)
9
+ # Return a list of module metadata hashes that match the search query.
10
+ # This return value is used by the module_tool face install search,
11
+ # and displayed to on the console.
12
+ #
13
+ # Example return value:
14
+ #
15
+ # [
16
+ # {
17
+ # "author" => "puppetlabs",
18
+ # "name" => "bacula",
19
+ # "tag_list" => ["backup", "bacula"],
20
+ # "releases" => [{"version"=>"0.0.1"}, {"version"=>"0.0.2"}],
21
+ # "full_name" => "puppetlabs/bacula",
22
+ # "version" => "0.0.2",
23
+ # "project_url" => "http://github.com/puppetlabs/puppetlabs-bacula",
24
+ # "desc" => "bacula"
25
+ # }
26
+ # ]
27
+ #
28
+ def self.search(term)
29
+ server = Puppet.settings[:module_repository].sub(/^(?!https?:\/\/)/, 'http://')
30
+ Puppet.notice "Searching #{server} ..."
31
+ request = Net::HTTP::Get.new("/modules.json?q=#{URI.escape(term)}")
32
+ response = repository.make_http_request(request)
33
+
34
+ case response.code
35
+ when "200"
36
+ matches = PSON.parse(response.body)
37
+ else
38
+ raise RuntimeError, "Could not execute search (HTTP #{response.code})"
39
+ matches = []
12
40
  end
13
41
 
14
- # Return a list of module metadata hashes that match the search query.
15
- # This return value is used by the module_tool face install search,
16
- # and displayed to on the console.
17
- #
18
- # Example return value:
19
- #
20
- # [
21
- # {
22
- # "author" => "puppetlabs",
23
- # "name" => "bacula",
24
- # "tag_list" => ["backup", "bacula"],
25
- # "releases" => [{"version"=>"0.0.1"}, {"version"=>"0.0.2"}],
26
- # "full_name" => "puppetlabs/bacula",
27
- # "version" => "0.0.2",
28
- # "project_url" => "http://github.com/puppetlabs/puppetlabs-bacula",
29
- # "desc" => "bacula"
30
- # }
31
- # ]
32
- #
33
- def search(term)
34
- request = Net::HTTP::Get.new("/modules.json?q=#{URI.escape(term)}")
35
- response = repository.make_http_request(request)
42
+ matches
43
+ end
36
44
 
37
- case response.code
38
- when "200"
39
- matches = PSON.parse(response.body)
45
+ def self.remote_dependency_info(author, mod_name, version)
46
+ version_string = version ? "&version=#{version}" : ''
47
+ request = Net::HTTP::Get.new("/api/v1/releases.json?module=#{author}/#{mod_name}" + version_string)
48
+ response = repository.make_http_request(request)
49
+ json = PSON.parse(response.body) rescue {}
50
+ case response.code
51
+ when "200"
52
+ return json
53
+ else
54
+ error = json['error'] || ''
55
+ if error =~ /^Module #{author}\/#{mod_name} has no release/
56
+ return []
40
57
  else
41
- raise RuntimeError, "Could not execute search (HTTP #{response.code})"
42
- matches = []
58
+ raise RuntimeError, "Could not find release information for this module (#{author}/#{mod_name}) (HTTP #{response.code})"
43
59
  end
44
-
45
- matches
46
60
  end
61
+ end
47
62
 
48
- # Return a Pathname object representing the path to the module
49
- # release package in the `Puppet.settings[:module_working_dir]`.
50
- def get_release_package(params)
63
+ def self.get_release_packages_from_repository(install_list)
64
+ install_list.map do |release|
65
+ modname, version, file = release
51
66
  cache_path = nil
52
- case params[:source]
53
- when :repository
54
- if not (params[:author] && params[:modname])
55
- raise ArgumentError, ":author and :modename required"
56
- end
57
- cache_path = get_release_package_from_repository(params[:author], params[:modname], params[:version])
58
- when :filesystem
59
- if not params[:filename]
60
- raise ArgumentError, ":filename required"
61
- end
62
- cache_path = get_release_package_from_filesystem(params[:filename])
63
- else
64
- raise ArgumentError, "Could not determine installation source"
65
- end
66
-
67
- cache_path
68
- end
69
-
70
- def get_releases(author, modname)
71
- request_string = "/#{author}/#{modname}"
72
-
73
- begin
74
- response = repository.make_http_request(request_string)
75
- rescue => e
76
- raise ArgumentError, "Could not find a release for this module (#{e.message})"
77
- end
78
-
79
- results = PSON.parse(response.body)
80
- # At this point releases look like this:
81
- # [{"version" => "0.0.1"}, {"version" => "0.0.2"},{"version" => "0.0.3"}]
82
- #
83
- # Lets fix this up a bit and return something like this to the caller
84
- # ["0.0.1", "0.0.2", "0.0.3"]
85
- results["releases"].collect {|release| release["version"]}
86
- end
87
-
88
- private
89
-
90
- # Locate and download a module release package from the remote forge
91
- # repository into the `Puppet.settings[:module_working_dir]`. Do not
92
- # unpack it, just return the location of the package on disk.
93
- def get_release_package_from_repository(author, modname, version=nil)
94
- release = get_release(author, modname, version)
95
- if release['file']
67
+ if file
96
68
  begin
97
- cache_path = repository.retrieve(release['file'])
69
+ cache_path = repository.retrieve(file)
98
70
  rescue OpenURI::HTTPError => e
99
71
  raise RuntimeError, "Could not download module: #{e.message}"
100
72
  end
101
73
  else
102
74
  raise RuntimeError, "Malformed response from module repository."
103
75
  end
104
-
105
- cache_path
106
- end
107
-
108
- # Locate a module release package on the local filesystem and move it
109
- # into the `Puppet.settings[:module_working_dir]`. Do not unpack it, just
110
- # return the location of the package on disk.
111
- def get_release_package_from_filesystem(filename)
112
- if File.exist?(File.expand_path(filename))
113
- repository = Repository.new('file:///')
114
- uri = URI.parse("file://#{URI.escape(File.expand_path(filename))}")
115
- cache_path = repository.retrieve(uri)
116
- else
117
- raise ArgumentError, "File does not exists: #{filename}"
118
- end
119
-
120
76
  cache_path
121
77
  end
78
+ end
122
79
 
123
- def repository
124
- @repository ||= Puppet::Forge::Repository.new(@uri)
80
+ # Locate a module release package on the local filesystem and move it
81
+ # into the `Puppet.settings[:module_working_dir]`. Do not unpack it, just
82
+ # return the location of the package on disk.
83
+ def self.get_release_package_from_filesystem(filename)
84
+ if File.exist?(File.expand_path(filename))
85
+ repository = Repository.new('file:///')
86
+ uri = URI.parse("file://#{URI.escape(File.expand_path(filename))}")
87
+ cache_path = repository.retrieve(uri)
88
+ else
89
+ raise ArgumentError, "File does not exists: #{filename}"
125
90
  end
126
91
 
127
- # Connect to the remote repository and locate a specific module release
128
- # by author/name combination. If a version requirement is specified, search
129
- # for that exact version, or grab the latest release available.
130
- #
131
- # Return the following response to the caller:
132
- #
133
- # {"file"=>"/system/releases/p/puppetlabs/puppetlabs-apache-0.0.3.tar.gz", "version"=>"0.0.3"}
134
- #
135
- #
136
- def get_release(author, modname, version_requirement=nil)
137
- request_string = "/users/#{author}/modules/#{modname}/releases/find.json"
138
- if version_requirement
139
- request_string + "?version=#{URI.escape(version_requirement)}"
140
- end
141
- request = Net::HTTP::Get.new(request_string)
142
-
143
- begin
144
- response = repository.make_http_request(request)
145
- rescue => e
146
- raise ArgumentError, "Could not find a release for this module (#{e.message})"
147
- end
92
+ cache_path
93
+ end
148
94
 
149
- PSON.parse(response.body)
150
- end
95
+ def self.repository
96
+ @repository ||= Puppet::Forge::Repository.new
151
97
  end
152
98
  end
153
-