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.
- data/CHANGELOG +144 -1
- data/conf/osx/preflight +1 -1
- data/conf/redhat/puppet.spec +9 -5
- data/conf/suse/puppet.spec +4 -1
- data/conf/windows/eventlog/Rakefile +32 -0
- data/conf/windows/eventlog/puppetres.dll +0 -0
- data/conf/windows/eventlog/puppetres.mc +18 -0
- data/ext/rack/files/apache2.conf +3 -0
- data/install.rb +23 -1
- data/lib/puppet.rb +1 -1
- data/lib/puppet/agent.rb +1 -14
- data/lib/puppet/application/kick.rb +1 -1
- data/lib/puppet/application/module.rb +11 -0
- data/lib/puppet/daemon.rb +74 -3
- data/lib/puppet/defaults.rb +1 -1
- data/lib/puppet/face/certificate.rb +1 -1
- data/lib/puppet/face/help/man.erb +1 -1
- data/lib/puppet/face/module.rb +17 -0
- data/lib/puppet/face/module/build.rb +10 -4
- data/lib/puppet/face/module/changes.rb +5 -5
- data/lib/puppet/face/module/generate.rb +6 -4
- data/lib/puppet/face/module/install.rb +122 -32
- data/lib/puppet/face/module/list.rb +234 -33
- data/lib/puppet/face/module/search.rb +56 -23
- data/lib/puppet/face/module/uninstall.rb +33 -38
- data/lib/puppet/face/module/upgrade.rb +84 -0
- data/lib/puppet/feature/eventlog.rb +6 -0
- data/lib/puppet/forge.rb +67 -122
- data/lib/puppet/forge/cache.rb +1 -1
- data/lib/puppet/forge/repository.rb +6 -25
- data/lib/puppet/indirector/facts/network_device.rb +1 -1
- data/lib/puppet/interface/action.rb +1 -1
- data/lib/puppet/module.rb +79 -28
- data/lib/puppet/module_tool.rb +72 -34
- data/lib/puppet/module_tool/applications.rb +12 -14
- data/lib/puppet/module_tool/applications/application.rb +21 -19
- data/lib/puppet/module_tool/applications/builder.rb +4 -4
- data/lib/puppet/module_tool/applications/checksummer.rb +12 -3
- data/lib/puppet/module_tool/applications/generator.rb +1 -1
- data/lib/puppet/module_tool/applications/installer.rb +163 -34
- data/lib/puppet/module_tool/applications/searcher.rb +2 -3
- data/lib/puppet/module_tool/applications/uninstaller.rb +84 -36
- data/lib/puppet/module_tool/applications/unpacker.rb +4 -26
- data/lib/puppet/module_tool/applications/upgrader.rb +109 -0
- data/lib/puppet/module_tool/checksums.rb +2 -2
- data/lib/puppet/module_tool/contents_description.rb +1 -1
- data/lib/puppet/module_tool/dependency.rb +2 -2
- data/lib/puppet/module_tool/errors.rb +9 -0
- data/lib/puppet/module_tool/errors/base.rb +15 -0
- data/lib/puppet/module_tool/errors/installer.rb +90 -0
- data/lib/puppet/module_tool/errors/shared.rb +115 -0
- data/lib/puppet/module_tool/errors/uninstaller.rb +45 -0
- data/lib/puppet/module_tool/errors/upgrader.rb +72 -0
- data/lib/puppet/module_tool/metadata.rb +2 -2
- data/lib/puppet/module_tool/modulefile.rb +7 -7
- data/lib/puppet/module_tool/shared_behaviors.rb +161 -0
- data/lib/puppet/module_tool/skeleton.rb +1 -1
- data/lib/puppet/node/environment.rb +4 -2
- data/lib/puppet/parser/ast/leaf.rb +1 -1
- data/lib/puppet/parser/functions/create_resources.rb +3 -2
- data/lib/puppet/parser/scope.rb +44 -9
- data/lib/puppet/provider/augeas/augeas.rb +2 -2
- data/lib/puppet/provider/exec.rb +8 -3
- data/lib/puppet/provider/exec/shell.rb +1 -2
- data/lib/puppet/provider/nameservice/directoryservice.rb +10 -4
- data/lib/puppet/provider/package/gem.rb +1 -1
- data/lib/puppet/provider/package/pkg.rb +10 -21
- data/lib/puppet/provider/selmodule/semodule.rb +1 -2
- data/lib/puppet/provider/service/upstart.rb +33 -17
- data/lib/puppet/provider/ssh_authorized_key/parsed.rb +1 -1
- data/lib/puppet/rails/inventory_node.rb +7 -7
- data/lib/puppet/reports/http.rb +4 -1
- data/lib/puppet/reports/tagmail.rb +8 -1
- data/lib/puppet/resource/type.rb +1 -1
- data/lib/puppet/test/test_helper.rb +138 -0
- data/lib/puppet/type.rb +9 -1
- data/lib/puppet/type/file.rb +18 -10
- data/lib/puppet/type/package.rb +13 -9
- data/lib/puppet/type/resources.rb +1 -1
- data/lib/puppet/type/ssh_authorized_key.rb +3 -4
- data/lib/puppet/type/sshkey.rb +4 -4
- data/lib/puppet/type/user.rb +1 -0
- data/lib/puppet/type/vlan.rb +1 -1
- data/lib/puppet/util.rb +31 -14
- data/lib/puppet/util/autoload.rb +1 -1
- data/lib/puppet/util/command_line.rb +2 -6
- data/lib/puppet/util/instrumentation/indirection_probe.rb +1 -1
- data/lib/puppet/util/instrumentation/instrumentable.rb +1 -1
- data/lib/puppet/util/instrumentation/listeners/log.rb +1 -1
- data/lib/puppet/util/instrumentation/listeners/performance.rb +1 -1
- data/lib/puppet/util/log.rb +3 -1
- data/lib/puppet/util/log/destinations.rb +38 -0
- data/lib/puppet/util/monkey_patches.rb +45 -0
- data/lib/puppet/util/network_device/base.rb +1 -1
- data/lib/puppet/util/network_device/cisco.rb +1 -1
- data/lib/puppet/util/network_device/cisco/facts.rb +1 -1
- data/lib/puppet/util/network_device/cisco/interface.rb +1 -1
- data/lib/puppet/util/network_device/config.rb +1 -1
- data/lib/puppet/util/network_device/ipcalc.rb +1 -1
- data/lib/puppet/util/network_device/transport.rb +1 -1
- data/lib/puppet/util/network_device/transport/base.rb +1 -1
- data/lib/puppet/util/network_device/transport/ssh.rb +1 -1
- data/lib/puppet/util/settings.rb +2 -11
- data/lib/puppet/util/settings/file_setting.rb +3 -5
- data/lib/puppet/util/terminal.rb +16 -0
- data/lib/puppet/util/zaml.rb +3 -1
- data/lib/semver.rb +15 -7
- data/spec/fixtures/releases/jamtur01-apache/metadata.json +1 -1
- data/spec/fixtures/unit/parser/lexer/arithmetic_expression.pp +1 -1
- data/spec/fixtures/unit/provider/package/pkg/dummy +1 -0
- data/spec/fixtures/unit/provider/package/pkg/incomplete +1 -0
- data/spec/fixtures/unit/provider/package/pkg/publisher +2 -0
- data/spec/fixtures/unit/provider/package/pkg/simple +4 -0
- data/spec/fixtures/unit/reports/tagmail/tagmail_email.conf +2 -0
- data/spec/fixtures/yaml/report0.25.x.yaml +1 -1
- data/spec/fixtures/yaml/report2.6.x.yaml +1 -1
- data/spec/integration/faces/documentation_spec.rb +1 -1
- data/spec/integration/network/rest_authconfig_spec.rb +1 -1
- data/spec/lib/puppet_spec/compiler.rb +6 -0
- data/spec/lib/puppet_spec/database.rb +30 -0
- data/spec/lib/puppet_spec/files.rb +4 -2
- data/spec/shared_behaviours/path_parameters.rb +2 -29
- data/spec/shared_contexts/platform.rb +43 -0
- data/spec/spec_helper.rb +36 -65
- data/spec/unit/agent_spec.rb +0 -32
- data/spec/unit/application/kick_spec.rb +2 -2
- data/spec/unit/daemon_spec.rb +1 -17
- data/spec/unit/face/module/install_spec.rb +158 -0
- data/spec/unit/face/module/list_spec.rb +182 -0
- data/spec/unit/face/module/search_spec.rb +163 -0
- data/spec/unit/face/module/uninstall_spec.rb +77 -0
- data/spec/unit/face/module/upgrade_spec.rb +26 -0
- data/spec/unit/forge/repository_spec.rb +0 -30
- data/spec/unit/forge_spec.rb +28 -86
- data/spec/unit/indirector/catalog/active_record_spec.rb +45 -65
- data/spec/unit/indirector/facts/inventory_active_record_spec.rb +5 -18
- data/spec/unit/indirector/resource/active_record_spec.rb +2 -11
- data/spec/unit/indirector/resource/ral_spec.rb +7 -2
- data/spec/unit/module_spec.rb +240 -107
- data/spec/unit/module_tool/application_spec.rb +3 -5
- data/spec/unit/module_tool/applications/application_spec.rb +19 -0
- data/spec/unit/module_tool/applications/installer_spec.rb +205 -0
- data/spec/unit/module_tool/applications/uninstaller_spec.rb +206 -0
- data/spec/unit/module_tool/applications/upgrader_spec.rb +37 -0
- data/spec/unit/module_tool/metadata_spec.rb +2 -2
- data/spec/unit/module_tool_spec.rb +109 -1
- data/spec/unit/node/environment_spec.rb +16 -1
- data/spec/unit/parser/ast/leaf_spec.rb +16 -1
- data/spec/unit/parser/collector_spec.rb +2 -12
- data/spec/unit/parser/functions/create_resources_spec.rb +135 -86
- data/spec/unit/parser/functions/generate_spec.rb +2 -10
- data/spec/unit/parser/scope_spec.rb +345 -16
- data/spec/unit/provider/augeas/augeas_spec.rb +19 -0
- data/spec/unit/provider/exec/shell_spec.rb +17 -14
- data/spec/unit/provider/exec/windows_spec.rb +1 -7
- data/spec/unit/provider/exec_spec.rb +35 -0
- data/spec/unit/provider/nameservice/directoryservice_spec.rb +10 -0
- data/spec/unit/provider/package/dpkg_spec.rb +2 -1
- data/spec/unit/provider/package/gem_spec.rb +15 -0
- data/spec/unit/provider/package/openbsd_spec.rb +5 -4
- data/spec/unit/provider/package/pacman_spec.rb +3 -2
- data/spec/unit/provider/package/pkg_spec.rb +56 -33
- data/spec/unit/provider/selmodule_spec.rb +11 -4
- data/spec/unit/provider/service/redhat_spec.rb +1 -3
- data/spec/unit/provider/service/smf_spec.rb +1 -3
- data/spec/unit/provider/service/upstart_spec.rb +38 -0
- data/spec/unit/provider/ssh_authorized_key/parsed_spec.rb +28 -0
- data/spec/unit/rails/host_spec.rb +6 -12
- data/spec/unit/rails/param_value_spec.rb +3 -8
- data/spec/unit/rails/resource_spec.rb +2 -8
- data/spec/unit/reports/http_spec.rb +47 -31
- data/spec/unit/reports/tagmail_spec.rb +77 -0
- data/spec/unit/resource/type_spec.rb +2 -2
- data/spec/unit/resource_spec.rb +18 -20
- data/spec/unit/semver_spec.rb +31 -13
- data/spec/unit/type/exec_spec.rb +8 -15
- data/spec/unit/type/group_spec.rb +0 -9
- data/spec/unit/type/package_spec.rb +10 -0
- data/spec/unit/type/resources_spec.rb +4 -5
- data/spec/unit/type/ssh_authorized_key_spec.rb +4 -15
- data/spec/unit/type/sshkey_spec.rb +9 -11
- data/spec/unit/type/user_spec.rb +123 -127
- data/spec/unit/type_spec.rb +20 -0
- data/spec/unit/util/command_line_spec.rb +2 -2
- data/spec/unit/util/instrumentation/data_spec.rb +1 -1
- data/spec/unit/util/instrumentation/indirection_probe_spec.rb +1 -1
- data/spec/unit/util/instrumentation/instrumentable_spec.rb +1 -1
- data/spec/unit/util/instrumentation/listener_spec.rb +1 -1
- data/spec/unit/util/instrumentation/listeners/log_spec.rb +1 -1
- data/spec/unit/util/instrumentation/listeners/performance_spec.rb +1 -1
- data/spec/unit/util/instrumentation_spec.rb +1 -1
- data/spec/unit/util/log/destinations_spec.rb +4 -8
- data/spec/unit/util/log_spec.rb +47 -0
- data/spec/unit/util/reference_spec.rb +1 -1
- data/spec/unit/util/settings/file_setting_spec.rb +9 -0
- data/spec/unit/util/settings_spec.rb +0 -53
- data/spec/unit/util/terminal_spec.rb +42 -0
- data/spec/unit/util/zaml_spec.rb +7 -0
- data/spec/unit/util_spec.rb +63 -20
- data/tasks/rake/manpages.rake +1 -1
- data/test/data/snippets/arithmetic_expression.pp +1 -1
- data/test/other/puppet.rb +0 -1
- data/test/util/log.rb +6 -6
- metadata +41 -16
- data/lib/puppet/external/event-loop.rb +0 -1
- data/lib/puppet/external/event-loop/better-definers.rb +0 -367
- data/lib/puppet/external/event-loop/event-loop.rb +0 -355
- data/lib/puppet/external/event-loop/signal-system.rb +0 -218
- data/lib/puppet/face/module/clean.rb +0 -30
- data/lib/puppet/module_tool/applications/cleaner.rb +0 -16
- data/lib/puppet/module_tool/skeleton/templates/generator/metadata.json +0 -12
- data/lib/puppet/module_tool/utils.rb +0 -5
- data/lib/puppet/module_tool/utils/interrogation.rb +0 -25
- data/spec/integration/module_tool_spec.rb +0 -475
- 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
|
-
|
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 "<
|
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::
|
24
|
+
Puppet::ModuleTool::Applications::Searcher.run(term, options)
|
30
25
|
end
|
31
26
|
|
32
|
-
when_rendering :console do |
|
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
|
-
|
38
|
+
min_widths = Hash[ *headers.map { |k,v| [k, v.length] }.flatten ]
|
39
|
+
min_widths['full_name'] = min_widths['author'] = 12
|
35
40
|
|
36
|
-
|
37
|
-
|
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
|
-
|
41
|
-
|
42
|
-
|
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
|
-
|
46
|
-
|
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
|
-
|
49
|
-
|
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
|
-
|
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
|
-
|
6
|
-
target directory
|
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
|
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
|
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
|
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 "--
|
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
|
45
|
+
summary "The target environment to uninstall modules from."
|
39
46
|
description <<-EOT
|
40
|
-
The target environment to
|
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
|
-
|
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
|
-
|
68
|
+
name = name.gsub('/', '-')
|
68
69
|
|
69
|
-
Puppet
|
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
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
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
|
data/lib/puppet/forge.rb
CHANGED
@@ -6,148 +6,93 @@ require 'puppet/forge/cache'
|
|
6
6
|
require 'puppet/forge/repository'
|
7
7
|
|
8
8
|
module Puppet::Forge
|
9
|
-
|
10
|
-
|
11
|
-
|
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
|
-
|
15
|
-
|
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
|
-
|
38
|
-
|
39
|
-
|
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
|
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
|
-
|
49
|
-
|
50
|
-
|
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
|
-
|
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(
|
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
|
-
|
124
|
-
|
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
|
-
|
128
|
-
|
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
|
-
|
150
|
-
|
95
|
+
def self.repository
|
96
|
+
@repository ||= Puppet::Forge::Repository.new
|
151
97
|
end
|
152
98
|
end
|
153
|
-
|