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
@@ -15,7 +15,7 @@ module Puppet
15
15
  setdefaults(:main,
16
16
  :trace => [false, "Whether to print stack traces on some errors"],
17
17
  :autoflush => {
18
- :default => false,
18
+ :default => true,
19
19
  :desc => "Whether log files should always flush to disk.",
20
20
  :hook => proc { |value| Log.autoflush = value }
21
21
  },
@@ -103,7 +103,7 @@ Puppet::Indirector::Face.define(:certificate, '0.0.1') do
103
103
 
104
104
  when_invoked do |name, options|
105
105
  host = Puppet::SSL::Host.new(name)
106
- if options[:ca_location] == :remote
106
+ if Puppet::SSL::Host.ca_location == :remote
107
107
  if options[:allow_dns_alt_names]
108
108
  raise ArgumentError, "--allow-dns-alt-names may not be specified with a remote CA"
109
109
  end
@@ -71,7 +71,7 @@ ACTIONS
71
71
 
72
72
  <% unique_options.sort.each do |name|
73
73
  option = action.get_option name
74
- text = option.description || option.summary -%>
74
+ text = (option.description || option.summary).chomp + "\n" -%>
75
75
  <%= '<' + option.optparse.join("> | <") + '>' %> -
76
76
  <%= text.gsub(/^/, ' ') %>
77
77
  <% end -%>
@@ -0,0 +1,17 @@
1
+ require 'puppet/face'
2
+ require 'puppet/module_tool'
3
+ require 'puppet/util/colors'
4
+
5
+ Puppet::Face.define(:module, '1.0.0') do
6
+ extend Puppet::Util::Colors
7
+
8
+ copyright "Puppet Labs", 2012
9
+ license "Apache 2 license; see COPYING"
10
+
11
+ summary "Creates, installs and searches for modules on the Puppet Forge."
12
+ description <<-EOT
13
+ This subcommand can find, install, and manage modules from the Puppet Forge,
14
+ a repository of user-contributed Puppet code. It can also generate empty
15
+ modules, and prepare locally developed modules for release on the Forge.
16
+ EOT
17
+ end
@@ -2,9 +2,15 @@ Puppet::Face.define(:module, '1.0.0') do
2
2
  action(:build) do
3
3
  summary "Build a module release package."
4
4
  description <<-EOT
5
- Build a module release archive file by processing the Modulefile in the
6
- module directory. The release archive file will be stored in the pkg
7
- directory of the module directory.
5
+ Prepares a local module for release on the Puppet Forge by building a
6
+ ready-to-upload archive file.
7
+
8
+ This action uses the Modulefile in the module directory to set metadata
9
+ used by the Forge. See <http://links.puppetlabs.com/modulefile> for more
10
+ about writing modulefiles.
11
+
12
+ After being built, the release archive file can be found in the module's
13
+ `pkg` directory.
8
14
  EOT
9
15
 
10
16
  returns "Pathname object representing the path to the release archive."
@@ -20,7 +26,7 @@ Puppet::Face.define(:module, '1.0.0') do
20
26
  arguments "<path>"
21
27
 
22
28
  when_invoked do |path, options|
23
- Puppet::Module::Tool::Applications::Builder.run(path, options)
29
+ Puppet::ModuleTool::Applications::Builder.run(path, options)
24
30
  end
25
31
 
26
32
  when_rendering :console do |return_value|
@@ -2,9 +2,9 @@ Puppet::Face.define(:module, '1.0.0') do
2
2
  action(:changes) do
3
3
  summary "Show modified files of an installed module."
4
4
  description <<-EOT
5
- Show files that have been modified after installation of a given module
6
- by comparing the on-disk md5 checksum of each file against the module's
7
- metadata.
5
+ Shows any files in a module that have been modified since it was
6
+ installed. This action compares the files on disk to the md5 checksums
7
+ included in the module's metadata.
8
8
  EOT
9
9
 
10
10
  returns "Array of strings representing paths of modified files."
@@ -20,8 +20,8 @@ Puppet::Face.define(:module, '1.0.0') do
20
20
  arguments "<path>"
21
21
 
22
22
  when_invoked do |path, options|
23
- root_path = Puppet::Module::Tool.find_module_root(path)
24
- Puppet::Module::Tool::Applications::Checksummer.run(root_path, options)
23
+ root_path = Puppet::ModuleTool.find_module_root(path)
24
+ Puppet::ModuleTool::Applications::Checksummer.run(root_path, options)
25
25
  end
26
26
 
27
27
  when_rendering :console do |return_value|
@@ -2,9 +2,11 @@ Puppet::Face.define(:module, '1.0.0') do
2
2
  action(:generate) do
3
3
  summary "Generate boilerplate for a new module."
4
4
  description <<-EOT
5
- Generate boilerplate for a new module by creating a directory
6
- pre-populated with a directory structure and files recommended for
7
- Puppet best practices.
5
+ Generates boilerplate for a new module by creating the directory
6
+ structure and files recommended for the Puppet community's best practices.
7
+
8
+ A module may need additional directories beyond this boilerplate
9
+ if it provides plugins, files, or templates.
8
10
  EOT
9
11
 
10
12
  returns "Array of Pathname objects representing paths of generated files."
@@ -30,7 +32,7 @@ Puppet::Face.define(:module, '1.0.0') do
30
32
  arguments "<name>"
31
33
 
32
34
  when_invoked do |name, options|
33
- Puppet::Module::Tool::Applications::Generator.run(name, options)
35
+ Puppet::ModuleTool::Applications::Generator.run(name, options)
34
36
  end
35
37
 
36
38
  when_rendering :console do |return_value|
@@ -1,39 +1,82 @@
1
+ # encoding: UTF-8
2
+
1
3
  Puppet::Face.define(:module, '1.0.0') do
2
4
  action(:install) do
3
5
  summary "Install a module from a repository or release archive."
4
6
  description <<-EOT
5
- Install a module from a release archive file on-disk or by downloading
6
- one from a repository. Unpack the archive into the install directory
7
- specified by the --install-dir option, which defaults to
8
- #{Puppet.settings[:modulepath].split(File::PATH_SEPARATOR).first}
7
+ Installs a module from the Puppet Forge, from a release archive file
8
+ on-disk, or from a private Forge-like repository.
9
+
10
+ The specified module will be installed into the directory
11
+ specified with the `--target-dir` option, which defaults to
12
+ #{Puppet.settings[:modulepath].split(File::PATH_SEPARATOR).first}.
9
13
  EOT
10
14
 
11
15
  returns "Pathname object representing the path to the installed module."
12
16
 
13
17
  examples <<-EOT
14
- Install a module from the default repository:
18
+ Install a module:
19
+
20
+ $ puppet module install puppetlabs-vcsrepo
21
+ Preparing to install into /etc/puppet/modules ...
22
+ Downloading from http://forge.puppetlabs.com ...
23
+ Installing -- do not interrupt ...
24
+ /etc/puppet/modules
25
+ └── puppetlabs-vcsrepo (v0.0.4)
15
26
 
16
- $ puppet module install puppetlabs/vcsrepo
17
- notice: Installing puppetlabs-vcsrepo-0.0.4.tar.gz to /etc/puppet/modules/vcsrepo
18
- /etc/puppet/modules/vcsrepo
27
+ Install a module to a specific environment:
19
28
 
20
- Install a specific module version from a repository:
29
+ $ puppet module install puppetlabs-vcsrepo --environment development
30
+ Preparing to install into /etc/puppet/environments/development/modules ...
31
+ Downloading from http://forge.puppetlabs.com ...
32
+ Installing -- do not interrupt ...
33
+ /etc/puppet/environments/development/modules
34
+ └── puppetlabs-vcsrepo (v0.0.4)
21
35
 
22
- $ puppet module install puppetlabs/vcsrepo -v 0.0.4
23
- notice: Installing puppetlabs-vcsrepo-0.0.4.tar.gz to /etc/puppet/modules/vcsrepo
24
- /etc/puppet/modules/vcsrepo
36
+ Install a specific module version:
37
+
38
+ $ puppet module install puppetlabs-vcsrepo -v 0.0.4
39
+ Preparing to install into /etc/puppet/modules ...
40
+ Downloading from http://forge.puppetlabs.com ...
41
+ Installing -- do not interrupt ...
42
+ /etc/puppet/modules
43
+ └── puppetlabs-vcsrepo (v0.0.4)
25
44
 
26
45
  Install a module into a specific directory:
27
46
 
28
- $ puppet module install puppetlabs/vcsrepo --install-dir=/usr/share/puppet/modules
29
- notice: Installing puppetlabs-vcsrepo-0.0.4.tar.gz to /usr/share/puppet/modules/vcsrepo
30
- /usr/share/puppet/modules/vcsrepo
47
+ $ puppet module install puppetlabs-vcsrepo --target-dir=/usr/share/puppet/modules
48
+ Preparing to install into /usr/share/puppet/modules ...
49
+ Downloading from http://forge.puppetlabs.com ...
50
+ Installing -- do not interrupt ...
51
+ /usr/share/puppet/modules
52
+ └── puppetlabs-vcsrepo (v0.0.4)
53
+
54
+ Install a module into a specific directory and check for dependencies in other directories:
55
+
56
+ $ puppet module install puppetlabs-vcsrepo --target-dir=/usr/share/puppet/modules --modulepath /etc/puppet/modules
57
+ Preparing to install into /usr/share/puppet/modules ...
58
+ Downloading from http://forge.puppetlabs.com ...
59
+ Installing -- do not interrupt ...
60
+ /usr/share/puppet/modules
61
+ └── puppetlabs-vcsrepo (v0.0.4)
31
62
 
32
63
  Install a module from a release archive:
33
64
 
34
65
  $ puppet module install puppetlabs-vcsrepo-0.0.4.tar.gz
35
- notice: Installing puppetlabs-vcsrepo-0.0.4.tar.gz to /etc/puppet/modules/vcsrepo
36
- /etc/puppet/modules/vcsrepo
66
+ Preparing to install into /etc/puppet/modules ...
67
+ Downloading from http://forge.puppetlabs.com ...
68
+ Installing -- do not interrupt ...
69
+ /etc/puppet/modules
70
+ └── puppetlabs-vcsrepo (v0.0.4)
71
+
72
+ Install a module from a release archive and ignore dependencies:
73
+
74
+ $ puppet module install puppetlabs-vcsrepo-0.0.4.tar.gz --ignore-dependencies
75
+ Preparing to install into /etc/puppet/modules ...
76
+ Installing -- do not interrupt ...
77
+ /etc/puppet/modules
78
+ └── puppetlabs-vcsrepo (v0.0.4)
79
+
37
80
  EOT
38
81
 
39
82
  arguments "<name>"
@@ -45,39 +88,86 @@ Puppet::Face.define(:module, '1.0.0') do
45
88
  EOT
46
89
  end
47
90
 
48
- option "--install-dir=", "-i=" do
49
- default_to { Puppet.settings[:modulepath].split(File::PATH_SEPARATOR).first }
91
+ option "--target-dir DIR", "-i DIR" do
50
92
  summary "The directory into which modules are installed."
51
93
  description <<-EOT
52
- The directory into which modules are installed, defaults to the first
94
+ The directory into which modules are installed; defaults to the first
53
95
  directory in the modulepath.
96
+
97
+ Specifying this option will change the installation directory, and
98
+ will use the existing modulepath when checking for dependencies. If
99
+ you wish to check a different set of directories for dependencies, you
100
+ must also use the `--environment` or `--modulepath` options.
54
101
  EOT
55
102
  end
56
103
 
57
- option "--module-repository=", "-r=" do
58
- default_to { Puppet.settings[:module_repository] }
59
- summary "Module repository to use."
104
+ option "--ignore-dependencies" do
105
+ summary "Do not attempt to install dependencies"
60
106
  description <<-EOT
61
- Module repository to use.
107
+ Do not attempt to install dependencies.
62
108
  EOT
63
109
  end
64
110
 
65
- option "--version=", "-v=" do
111
+ option "--modulepath MODULEPATH" do
112
+ default_to { Puppet.settings[:modulepath] }
113
+ summary "Which directories to look for modules in"
114
+ description <<-EOT
115
+ The list of directories to check for modules. When installing a new
116
+ module, this setting determines where the module tool will look for
117
+ its dependencies. If the `--target dir` option is not specified, the
118
+ first directory in the modulepath will also be used as the install
119
+ directory.
120
+
121
+ When installing a module into an environment whose modulepath is
122
+ specified in puppet.conf, you can use the `--environment` option
123
+ instead, and its modulepath will be used automatically.
124
+
125
+ This setting should be a list of directories separated by the path
126
+ separator character. (The path separator is `:` on Unix-like platforms
127
+ and `;` on Windows.)
128
+ EOT
129
+ end
130
+
131
+ option "--version VER", "-v VER" do
66
132
  summary "Module version to install."
67
133
  description <<-EOT
68
- Module version to install, can be a requirement string, eg '>= 1.0.3',
69
- defaults to latest version.
134
+ Module version to install; can be an exact version or a requirement string,
135
+ eg '>= 1.0.3'. Defaults to latest version.
136
+ EOT
137
+ end
138
+
139
+ option "--environment NAME" do
140
+ default_to { "production" }
141
+ summary "The target environment to install modules into."
142
+ description <<-EOT
143
+ The target environment to install modules into. Only applicable if
144
+ multiple environments (with different modulepaths) have been
145
+ configured in puppet.conf.
70
146
  EOT
71
147
  end
72
148
 
73
149
  when_invoked do |name, options|
74
- Puppet::Module::Tool::Applications::Installer.run(name, options)
150
+ sep = File::PATH_SEPARATOR
151
+ if options[:target_dir]
152
+ options[:modulepath] = "#{options[:target_dir]}#{sep}#{options[:modulepath]}"
153
+ end
154
+
155
+ Puppet.settings[:modulepath] = options[:modulepath]
156
+ options[:target_dir] = Puppet.settings[:modulepath].split(sep).first
157
+
158
+ Puppet.notice "Preparing to install into #{options[:target_dir]} ..."
159
+ Puppet::ModuleTool::Applications::Installer.run(name, options)
75
160
  end
76
161
 
77
- when_rendering :console do |return_value|
78
- # Get the string representation of the Pathname object and print it to
79
- # the console.
80
- return_value.to_s
162
+ when_rendering :console do |return_value, name, options|
163
+ if return_value[:result] == :failure
164
+ Puppet.err(return_value[:error][:multiline])
165
+ exit 1
166
+ else
167
+ tree = Puppet::ModuleTool.build_tree(return_value[:installed_modules], return_value[:install_dir])
168
+ return_value[:install_dir] + "\n" +
169
+ Puppet::ModuleTool.format_tree(tree)
170
+ end
81
171
  end
82
172
  end
83
173
  end
@@ -1,21 +1,37 @@
1
+ # encoding: UTF-8
2
+
1
3
  Puppet::Face.define(:module, '1.0.0') do
2
4
  action(:list) do
3
5
  summary "List installed modules"
4
6
  description <<-HEREDOC
5
- List puppet modules from a specific environment, specified modulepath or
6
- default to listing modules in the default modulepath. The output will
7
- include information about unmet module dependencies based on information
8
- from module metadata.
9
- #{Puppet.settings[:modulepath]}
7
+ Lists the installed puppet modules. By default, this action scans the
8
+ modulepath from puppet.conf's `[main]` block; use the --modulepath
9
+ option to change which directories are scanned.
10
+
11
+ The output of this action includes information from the module's
12
+ metadata, including version numbers and unmet module dependencies.
10
13
  HEREDOC
11
14
  returns "hash of paths to module objects"
12
15
 
13
- option "--env ENVIRONMENT" do
16
+ option "--environment NAME" do
17
+ default_to { "production" }
14
18
  summary "Which environments' modules to list"
19
+ description <<-EOT
20
+ Which environments' modules to list.
21
+ EOT
15
22
  end
16
23
 
17
24
  option "--modulepath MODULEPATH" do
18
25
  summary "Which directories to look for modules in"
26
+ description <<-EOT
27
+ Which directories to look for modules in; use the system path separator
28
+ character (`:` on Unix-like systems and `;` on Windows) to specify
29
+ multiple directories.
30
+ EOT
31
+ end
32
+
33
+ option "--tree" do
34
+ summary "Whether to show dependencies as a tree view"
19
35
  end
20
36
 
21
37
  examples <<-EOT
@@ -23,32 +39,44 @@ Puppet::Face.define(:module, '1.0.0') do
23
39
 
24
40
  $ puppet module list
25
41
  /etc/puppet/modules
26
- bacula (0.0.2)
27
- /usr/share/puppet/modules
28
- apache (0.0.3)
29
- bacula (0.0.1)
42
+ ├── bodepd-create_resources (v0.0.1)
43
+ ├── puppetlabs-bacula (v0.0.2)
44
+ ├── puppetlabs-mysql (v0.0.1)
45
+ ├── puppetlabs-sqlite (v0.0.1)
46
+ └── puppetlabs-stdlib (v2.2.1)
47
+ /usr/share/puppet/modules (no modules installed)
30
48
 
31
- List installed modules from a specified environment:
49
+ List installed modules in a tree view:
32
50
 
33
- $ puppet module list --env 'test'
34
- Missing dependency `stdlib`:
35
- `rrd` (0.0.2) requires `puppetlabs/stdlib` (>= 2.2.0)
51
+ $ puppet module list --tree
52
+ /etc/puppet/modules
53
+ └─┬ puppetlabs-bacula (v0.0.2)
54
+ ├── puppetlabs-stdlib (v2.2.1)
55
+ ├─┬ puppetlabs-mysql (v0.0.1)
56
+ │ └── bodepd-create_resources (v0.0.1)
57
+ └── puppetlabs-sqlite (v0.0.1)
58
+ /usr/share/puppet/modules (no modules installed)
59
+
60
+ List installed modules from a specified environment:
36
61
 
37
- /tmp/puppet/modules
38
- rrd (0.0.2)
62
+ $ puppet module list --environment production
63
+ /etc/puppet/modules
64
+ ├── bodepd-create_resources (v0.0.1)
65
+ ├── puppetlabs-bacula (v0.0.2)
66
+ ├── puppetlabs-mysql (v0.0.1)
67
+ ├── puppetlabs-sqlite (v0.0.1)
68
+ └── puppetlabs-stdlib (v2.2.1)
69
+ /usr/share/puppet/modules (no modules installed)
39
70
 
40
71
  List installed modules from a specified modulepath:
41
72
 
42
- $ puppet module list --modulepath /tmp/facts1:/tmp/facts2
43
- /tmp/facts1
44
- stdlib
45
- /tmp/facts2
46
- nginx (1.0.0)
73
+ $ puppet module list --modulepath /usr/share/puppet/modules
74
+ /usr/share/puppet/modules (no modules installed)
47
75
  EOT
48
76
 
49
77
  when_invoked do |options|
50
78
  Puppet[:modulepath] = options[:modulepath] if options[:modulepath]
51
- environment = Puppet::Node::Environment.new(options[:env])
79
+ environment = Puppet::Node::Environment.new(options[:environment])
52
80
 
53
81
  environment.modules_by_path
54
82
  end
@@ -57,28 +85,201 @@ Puppet::Face.define(:module, '1.0.0') do
57
85
  output = ''
58
86
 
59
87
  Puppet[:modulepath] = options[:modulepath] if options[:modulepath]
60
- environment = Puppet::Node::Environment.new(options[:env])
88
+ environment = Puppet::Node::Environment.new(options[:production])
61
89
 
62
- dependency_errors = false
90
+ error_types = {
91
+ :non_semantic_version => {
92
+ :title => "Non semantic version dependency"
93
+ },
94
+ :missing => {
95
+ :title => "Missing dependency"
96
+ },
97
+ :version_mismatch => {
98
+ :title => "Module '%s' (v%s) fails to meet some dependencies:"
99
+ }
100
+ }
63
101
 
102
+ @unmet_deps = {}
103
+ error_types.each_key do |type|
104
+ @unmet_deps[type] = Hash.new do |hash, key|
105
+ hash[key] = { :errors => [], :parent => nil }
106
+ end
107
+ end
108
+
109
+ # Prepare the unmet dependencies for display on the console.
64
110
  environment.modules.sort_by {|mod| mod.name}.each do |mod|
65
- mod.unmet_dependencies.sort_by {|dep| dep[:name]}.each do |dep|
66
- dependency_errors = true
67
- $stderr.puts dep[:error]
111
+ unmet_grouped = Hash.new { |h,k| h[k] = [] }
112
+ unmet_grouped = mod.unmet_dependencies.inject(unmet_grouped) do |acc, dep|
113
+ acc[dep[:reason]] << dep
114
+ acc
115
+ end
116
+ unmet_grouped.each do |type, deps|
117
+ unless deps.empty?
118
+ unmet_grouped[type].sort_by { |dep| dep[:name] }.each do |dep|
119
+ dep_name = dep[:name].gsub('/', '-')
120
+ installed_version = dep[:mod_details][:installed_version]
121
+ version_constraint = dep[:version_constraint]
122
+ parent_name = dep[:parent][:name].gsub('/', '-')
123
+ parent_version = dep[:parent][:version]
124
+
125
+ msg = "'#{parent_name}' (#{parent_version})"
126
+ msg << " requires '#{dep_name}' (#{version_constraint})"
127
+ @unmet_deps[type][dep[:name]][:errors] << msg
128
+ @unmet_deps[type][dep[:name]][:parent] = {
129
+ :name => dep[:parent][:name],
130
+ :version => parent_version
131
+ }
132
+ @unmet_deps[type][dep[:name]][:version] = installed_version
133
+ end
134
+ end
135
+ end
136
+ end
137
+
138
+ # Display unmet dependencies by category.
139
+ error_display_order = [:non_semantic_version, :version_mismatch, :missing]
140
+ error_display_order.each do |type|
141
+ unless @unmet_deps[type].empty?
142
+ @unmet_deps[type].keys.sort_by {|dep| dep }.each do |dep|
143
+ name = dep.gsub('/', '-')
144
+ title = error_types[type][:title]
145
+ errors = @unmet_deps[type][dep][:errors]
146
+ version = @unmet_deps[type][dep][:version]
147
+
148
+ msg = case type
149
+ when :version_mismatch
150
+ title % [name, version] + "\n"
151
+ when :non_semantic_version
152
+ title + " '#{name}' (v#{version}):\n"
153
+ else
154
+ title + " '#{name}':\n"
155
+ end
156
+
157
+ errors.each { |error_string| msg << " #{error_string}\n" }
158
+ Puppet.warning msg.chomp
159
+ end
68
160
  end
69
161
  end
70
162
 
71
- output << "\n" if dependency_errors
163
+ environment.modulepath.each do |path|
164
+ modules = modules_by_path[path]
165
+ no_mods = modules.empty? ? ' (no modules installed)' : ''
166
+ output << "#{path}#{no_mods}\n"
72
167
 
73
- modules_by_path.each do |path, modules|
74
- output << "#{path}\n"
75
- modules.sort_by {|mod| mod.name }.each do |mod|
76
- version_string = mod.version ? "(#{mod.version})" : ''
77
- output << " #{mod.name} #{version_string}\n"
168
+ if options[:tree]
169
+ # The modules with fewest things depending on them will be the
170
+ # parent of the tree. Can't assume to start with 0 dependencies
171
+ # since dependencies may be cyclical.
172
+ modules_by_num_requires = modules.sort_by {|m| m.required_by.size}
173
+ @seen = {}
174
+ tree = list_build_tree(modules_by_num_requires, [], nil,
175
+ :label_unmet => true, :path => path, :label_invalid => false)
176
+ else
177
+ tree = []
178
+ modules.sort_by { |mod| mod.forge_name or mod.name }.each do |mod|
179
+ tree << list_build_node(mod, path, :label_unmet => false,
180
+ :path => path, :label_invalid => true)
181
+ end
78
182
  end
183
+
184
+ output << Puppet::ModuleTool.format_tree(tree)
79
185
  end
186
+
80
187
  output
81
188
  end
189
+ end
190
+
191
+ # Prepare a list of module objects and their dependencies for print in a
192
+ # tree view.
193
+ #
194
+ # Returns an Array of Hashes
195
+ #
196
+ # Example:
197
+ #
198
+ # [
199
+ # {
200
+ # :text => "puppetlabs-bacula (v0.0.2)",
201
+ # :dependencies=> [
202
+ # { :text => "puppetlabs-stdlib (v2.2.1)", :dependencies => [] },
203
+ # {
204
+ # :text => "puppetlabs-mysql (v1.0.0)"
205
+ # :dependencies => [
206
+ # {
207
+ # :text => "bodepd-create_resources (v0.0.1)",
208
+ # :dependencies => []
209
+ # }
210
+ # ]
211
+ # },
212
+ # { :text => "puppetlabs-sqlite (v0.0.1)", :dependencies => [] },
213
+ # ]
214
+ # }
215
+ # ]
216
+ #
217
+ # When the above data structure is passed to Puppet::ModuleTool.build_tree
218
+ # you end up with something like this:
219
+ #
220
+ # /etc/puppet/modules
221
+ # └─┬ puppetlabs-bacula (v0.0.2)
222
+ # ├── puppetlabs-stdlib (v2.2.1)
223
+ # ├─┬ puppetlabs-mysql (v1.0.0)
224
+ # │ └── bodepd-create_resources (v0.0.1)
225
+ # └── puppetlabs-sqlite (v0.0.1)
226
+ #
227
+ def list_build_tree(list, ancestors=[], parent=nil, params={})
228
+ list.map do |mod|
229
+ next if @seen[(mod.forge_name or mod.name)]
230
+ node = list_build_node(mod, parent, params)
231
+ @seen[(mod.forge_name or mod.name)] = true
232
+
233
+ unless ancestors.include?(mod)
234
+ node[:dependencies] ||= []
235
+ missing_deps = mod.unmet_dependencies.select do |dep|
236
+ dep[:reason] == :missing
237
+ end
238
+ missing_deps.map do |mis_mod|
239
+ str = "#{colorize(:bg_red, 'UNMET DEPENDENCY')} #{mis_mod[:name].gsub('/', '-')} "
240
+ str << "(#{colorize(:cyan, mis_mod[:version_constraint])})"
241
+ node[:dependencies] << { :text => str }
242
+ end
243
+ node[:dependencies] += list_build_tree(mod.dependencies_as_modules,
244
+ ancestors + [mod], mod, params)
245
+ end
246
+
247
+ node
248
+ end.compact
249
+ end
250
+
251
+ # Prepare a module object for print in a tree view. Each node in the tree
252
+ # must be a Hash in the following format:
253
+ #
254
+ # { :text => "puppetlabs-mysql (v1.0.0)" }
255
+ #
256
+ # The value of a module's :text is affected by three (3) factors: the format
257
+ # of the tree, it's dependency status, and the location in the modulepath
258
+ # relative to it's parent.
259
+ #
260
+ # Returns a Hash
261
+ #
262
+ def list_build_node(mod, parent, params)
263
+ str = ''
264
+ str << (mod.forge_name ? mod.forge_name.gsub('/', '-') : mod.name)
265
+ str << ' (' + colorize(:cyan, mod.version ? "v#{mod.version}" : '???') + ')'
266
+
267
+ unless File.dirname(mod.path) == params[:path]
268
+ str << " [#{File.dirname(mod.path)}]"
269
+ end
270
+
271
+ if @unmet_deps[:version_mismatch].include?(mod.forge_name)
272
+ if params[:label_invalid]
273
+ str << ' ' + colorize(:red, 'invalid')
274
+ elsif parent.respond_to?(:forge_name)
275
+ unmet_parent = @unmet_deps[:version_mismatch][mod.forge_name][:parent]
276
+ if (unmet_parent[:name] == parent.forge_name &&
277
+ unmet_parent[:version] == "v#{parent.version}")
278
+ str << ' ' + colorize(:red, 'invalid')
279
+ end
280
+ end
281
+ end
82
282
 
283
+ { :text => str }
83
284
  end
84
285
  end