choria-mcorpc-support 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/bin/mco +64 -0
- data/lib/mcollective.rb +63 -0
- data/lib/mcollective/agent.rb +5 -0
- data/lib/mcollective/agents.rb +149 -0
- data/lib/mcollective/aggregate.rb +85 -0
- data/lib/mcollective/aggregate/average.ddl +33 -0
- data/lib/mcollective/aggregate/average.rb +29 -0
- data/lib/mcollective/aggregate/base.rb +40 -0
- data/lib/mcollective/aggregate/result.rb +9 -0
- data/lib/mcollective/aggregate/result/base.rb +25 -0
- data/lib/mcollective/aggregate/result/collection_result.rb +19 -0
- data/lib/mcollective/aggregate/result/numeric_result.rb +13 -0
- data/lib/mcollective/aggregate/sum.ddl +33 -0
- data/lib/mcollective/aggregate/sum.rb +18 -0
- data/lib/mcollective/aggregate/summary.ddl +33 -0
- data/lib/mcollective/aggregate/summary.rb +53 -0
- data/lib/mcollective/application.rb +365 -0
- data/lib/mcollective/application/completion.rb +104 -0
- data/lib/mcollective/application/describe_filter.rb +87 -0
- data/lib/mcollective/application/facts.rb +62 -0
- data/lib/mcollective/application/find.rb +23 -0
- data/lib/mcollective/application/help.rb +28 -0
- data/lib/mcollective/application/inventory.rb +344 -0
- data/lib/mcollective/application/ping.rb +82 -0
- data/lib/mcollective/application/plugin.rb +369 -0
- data/lib/mcollective/application/rpc.rb +111 -0
- data/lib/mcollective/applications.rb +134 -0
- data/lib/mcollective/cache.rb +145 -0
- data/lib/mcollective/client.rb +353 -0
- data/lib/mcollective/config.rb +245 -0
- data/lib/mcollective/connector.rb +18 -0
- data/lib/mcollective/connector/base.rb +26 -0
- data/lib/mcollective/data.rb +91 -0
- data/lib/mcollective/data/agent_data.ddl +22 -0
- data/lib/mcollective/data/agent_data.rb +17 -0
- data/lib/mcollective/data/base.rb +67 -0
- data/lib/mcollective/data/collective_data.ddl +20 -0
- data/lib/mcollective/data/collective_data.rb +9 -0
- data/lib/mcollective/data/fact_data.ddl +28 -0
- data/lib/mcollective/data/fact_data.rb +55 -0
- data/lib/mcollective/data/fstat_data.ddl +89 -0
- data/lib/mcollective/data/fstat_data.rb +56 -0
- data/lib/mcollective/data/result.rb +45 -0
- data/lib/mcollective/ddl.rb +113 -0
- data/lib/mcollective/ddl/agentddl.rb +253 -0
- data/lib/mcollective/ddl/base.rb +217 -0
- data/lib/mcollective/ddl/dataddl.rb +56 -0
- data/lib/mcollective/ddl/discoveryddl.rb +52 -0
- data/lib/mcollective/ddl/validatorddl.rb +6 -0
- data/lib/mcollective/discovery.rb +143 -0
- data/lib/mcollective/discovery/flatfile.ddl +11 -0
- data/lib/mcollective/discovery/flatfile.rb +48 -0
- data/lib/mcollective/discovery/mc.ddl +11 -0
- data/lib/mcollective/discovery/mc.rb +30 -0
- data/lib/mcollective/discovery/stdin.ddl +11 -0
- data/lib/mcollective/discovery/stdin.rb +68 -0
- data/lib/mcollective/exceptions.rb +28 -0
- data/lib/mcollective/facts.rb +39 -0
- data/lib/mcollective/facts/base.rb +100 -0
- data/lib/mcollective/facts/yaml_facts.rb +65 -0
- data/lib/mcollective/generators.rb +7 -0
- data/lib/mcollective/generators/agent_generator.rb +51 -0
- data/lib/mcollective/generators/base.rb +46 -0
- data/lib/mcollective/generators/data_generator.rb +51 -0
- data/lib/mcollective/generators/templates/action_snippet.erb +13 -0
- data/lib/mcollective/generators/templates/data_input_snippet.erb +7 -0
- data/lib/mcollective/generators/templates/ddl.erb +8 -0
- data/lib/mcollective/generators/templates/plugin.erb +7 -0
- data/lib/mcollective/log.rb +118 -0
- data/lib/mcollective/logger.rb +5 -0
- data/lib/mcollective/logger/base.rb +77 -0
- data/lib/mcollective/logger/console_logger.rb +61 -0
- data/lib/mcollective/logger/file_logger.rb +53 -0
- data/lib/mcollective/logger/syslog_logger.rb +53 -0
- data/lib/mcollective/matcher.rb +224 -0
- data/lib/mcollective/matcher/parser.rb +128 -0
- data/lib/mcollective/matcher/scanner.rb +241 -0
- data/lib/mcollective/message.rb +248 -0
- data/lib/mcollective/monkey_patches.rb +152 -0
- data/lib/mcollective/optionparser.rb +197 -0
- data/lib/mcollective/pluginmanager.rb +180 -0
- data/lib/mcollective/pluginpackager.rb +98 -0
- data/lib/mcollective/pluginpackager/agent_definition.rb +94 -0
- data/lib/mcollective/pluginpackager/debpackage_packager.rb +237 -0
- data/lib/mcollective/pluginpackager/modulepackage_packager.rb +127 -0
- data/lib/mcollective/pluginpackager/ospackage_packager.rb +59 -0
- data/lib/mcollective/pluginpackager/rpmpackage_packager.rb +180 -0
- data/lib/mcollective/pluginpackager/standard_definition.rb +69 -0
- data/lib/mcollective/pluginpackager/templates/debian/Makefile.erb +7 -0
- data/lib/mcollective/pluginpackager/templates/debian/changelog.erb +5 -0
- data/lib/mcollective/pluginpackager/templates/debian/compat.erb +1 -0
- data/lib/mcollective/pluginpackager/templates/debian/control.erb +15 -0
- data/lib/mcollective/pluginpackager/templates/debian/copyright.erb +8 -0
- data/lib/mcollective/pluginpackager/templates/debian/rules.erb +6 -0
- data/lib/mcollective/pluginpackager/templates/module/Modulefile.erb +5 -0
- data/lib/mcollective/pluginpackager/templates/module/README.md.erb +37 -0
- data/lib/mcollective/pluginpackager/templates/module/_manifest.pp.erb +9 -0
- data/lib/mcollective/pluginpackager/templates/redhat/rpm_spec.erb +63 -0
- data/lib/mcollective/registration/base.rb +91 -0
- data/lib/mcollective/rpc.rb +182 -0
- data/lib/mcollective/rpc/actionrunner.rb +158 -0
- data/lib/mcollective/rpc/agent.rb +374 -0
- data/lib/mcollective/rpc/audit.rb +38 -0
- data/lib/mcollective/rpc/client.rb +1066 -0
- data/lib/mcollective/rpc/helpers.rb +321 -0
- data/lib/mcollective/rpc/progress.rb +63 -0
- data/lib/mcollective/rpc/reply.rb +87 -0
- data/lib/mcollective/rpc/request.rb +86 -0
- data/lib/mcollective/rpc/result.rb +90 -0
- data/lib/mcollective/rpc/stats.rb +294 -0
- data/lib/mcollective/runnerstats.rb +90 -0
- data/lib/mcollective/security.rb +26 -0
- data/lib/mcollective/security/base.rb +244 -0
- data/lib/mcollective/shell.rb +126 -0
- data/lib/mcollective/ssl.rb +285 -0
- data/lib/mcollective/util.rb +579 -0
- data/lib/mcollective/validator.rb +85 -0
- data/lib/mcollective/validator/array_validator.ddl +7 -0
- data/lib/mcollective/validator/array_validator.rb +9 -0
- data/lib/mcollective/validator/ipv4address_validator.ddl +7 -0
- data/lib/mcollective/validator/ipv4address_validator.rb +16 -0
- data/lib/mcollective/validator/ipv6address_validator.ddl +7 -0
- data/lib/mcollective/validator/ipv6address_validator.rb +16 -0
- data/lib/mcollective/validator/length_validator.ddl +7 -0
- data/lib/mcollective/validator/length_validator.rb +11 -0
- data/lib/mcollective/validator/regex_validator.ddl +7 -0
- data/lib/mcollective/validator/regex_validator.rb +9 -0
- data/lib/mcollective/validator/shellsafe_validator.ddl +7 -0
- data/lib/mcollective/validator/shellsafe_validator.rb +13 -0
- data/lib/mcollective/validator/typecheck_validator.ddl +7 -0
- data/lib/mcollective/validator/typecheck_validator.rb +28 -0
- metadata +215 -0
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
# A simple plugin manager, it stores one plugin each of a specific type
|
|
3
|
+
# the idea is that we can only have one security provider, one connector etc.
|
|
4
|
+
module PluginManager
|
|
5
|
+
@plugins = {}
|
|
6
|
+
|
|
7
|
+
# Adds a plugin to the list of plugins, we expect a hash like:
|
|
8
|
+
#
|
|
9
|
+
# {:type => "base",
|
|
10
|
+
# :class => foo.new}
|
|
11
|
+
#
|
|
12
|
+
# or like:
|
|
13
|
+
# {:type => "base",
|
|
14
|
+
# :class => "Foo::Bar"}
|
|
15
|
+
#
|
|
16
|
+
# In the event that we already have a class with the given type
|
|
17
|
+
# an exception will be raised.
|
|
18
|
+
#
|
|
19
|
+
# If the :class passed is a String then we will delay instantiation
|
|
20
|
+
# till the first time someone asks for the plugin, this is because most likely
|
|
21
|
+
# the registration gets done by inherited() hooks, at which point the plugin class is not final.
|
|
22
|
+
#
|
|
23
|
+
# If we were to do a .new here the Class initialize method would get called and not
|
|
24
|
+
# the plugins, we there for only initialize the classes when they get requested via []
|
|
25
|
+
#
|
|
26
|
+
# By default all plugin instances are cached and returned later so there's
|
|
27
|
+
# always a single instance. You can pass :single_instance => false when
|
|
28
|
+
# calling this to instruct it to always return a new instance when a copy
|
|
29
|
+
# is requested. This only works with sending a String for :class.
|
|
30
|
+
def self.<<(plugin)
|
|
31
|
+
plugin[:single_instance] = true unless plugin.include?(:single_instance)
|
|
32
|
+
|
|
33
|
+
type = plugin[:type]
|
|
34
|
+
klass = plugin[:class]
|
|
35
|
+
single = plugin[:single_instance]
|
|
36
|
+
|
|
37
|
+
raise("Plugin #{type} already loaded") if @plugins.include?(type)
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
# If we get a string then store 'nil' as the instance, signalling that we'll
|
|
41
|
+
# create the class later on demand.
|
|
42
|
+
if klass.is_a?(String)
|
|
43
|
+
@plugins[type] = {:loadtime => Time.now, :class => klass, :instance => nil, :single => single}
|
|
44
|
+
Log.debug("Registering plugin #{type} with class #{klass} single_instance: #{single}")
|
|
45
|
+
else
|
|
46
|
+
@plugins[type] = {:loadtime => Time.now, :class => klass.class, :instance => klass, :single => true}
|
|
47
|
+
Log.debug("Registering plugin #{type} with class #{klass.class} single_instance: true")
|
|
48
|
+
end
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
# Removes a plugim the list
|
|
52
|
+
def self.delete(plugin)
|
|
53
|
+
@plugins.delete(plugin) if @plugins.include?(plugin)
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
# Finds out if we have a plugin with the given name
|
|
57
|
+
def self.include?(plugin)
|
|
58
|
+
@plugins.include?(plugin)
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
# Provides a list of plugins we know about
|
|
62
|
+
def self.pluginlist
|
|
63
|
+
@plugins.keys.sort
|
|
64
|
+
end
|
|
65
|
+
|
|
66
|
+
# deletes all registered plugins
|
|
67
|
+
def self.clear
|
|
68
|
+
@plugins.clear
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
# Gets a plugin by type
|
|
72
|
+
def self.[](plugin)
|
|
73
|
+
raise("No plugin #{plugin} defined") unless @plugins.include?(plugin)
|
|
74
|
+
|
|
75
|
+
klass = @plugins[plugin][:class]
|
|
76
|
+
|
|
77
|
+
if @plugins[plugin][:single]
|
|
78
|
+
# Create an instance of the class if one hasn't been done before
|
|
79
|
+
if @plugins[plugin][:instance] == nil
|
|
80
|
+
Log.debug("Returning new plugin #{plugin} with class #{klass}")
|
|
81
|
+
@plugins[plugin][:instance] = create_instance(klass)
|
|
82
|
+
else
|
|
83
|
+
Log.debug("Returning cached plugin #{plugin} with class #{klass}")
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
@plugins[plugin][:instance]
|
|
87
|
+
else
|
|
88
|
+
Log.debug("Returning new plugin #{plugin} with class #{klass}")
|
|
89
|
+
create_instance(klass)
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# use eval to create an instance of a class
|
|
94
|
+
def self.create_instance(klass)
|
|
95
|
+
begin
|
|
96
|
+
eval("#{klass}.new")
|
|
97
|
+
rescue Exception => e
|
|
98
|
+
raise("Could not create instance of plugin #{klass}: #{e}")
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
# Finds plugins in all configured libdirs
|
|
103
|
+
#
|
|
104
|
+
# find("agent")
|
|
105
|
+
#
|
|
106
|
+
# will return an array of just agent names, for example:
|
|
107
|
+
#
|
|
108
|
+
# ["puppetd", "package"]
|
|
109
|
+
#
|
|
110
|
+
# Can also be used to find files of other extensions:
|
|
111
|
+
#
|
|
112
|
+
# find("agent", "ddl")
|
|
113
|
+
#
|
|
114
|
+
# Will return the same list but only of files with extension .ddl
|
|
115
|
+
# in the agent subdirectory
|
|
116
|
+
def self.find(type, extension="rb")
|
|
117
|
+
extension = ".#{extension}" unless extension.match(/^\./)
|
|
118
|
+
|
|
119
|
+
plugins = []
|
|
120
|
+
|
|
121
|
+
Config.instance.libdir.each do |libdir|
|
|
122
|
+
plugdir = File.join([libdir, "mcollective", type.to_s])
|
|
123
|
+
next unless File.directory?(plugdir)
|
|
124
|
+
|
|
125
|
+
Dir.new(plugdir).grep(/#{extension}$/).map do |plugin|
|
|
126
|
+
plugins << File.basename(plugin, extension)
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
plugins.sort.uniq
|
|
131
|
+
end
|
|
132
|
+
|
|
133
|
+
# Finds and loads from disk all plugins from all libdirs that match
|
|
134
|
+
# certain criteria.
|
|
135
|
+
#
|
|
136
|
+
# find_and_load("pluginpackager")
|
|
137
|
+
#
|
|
138
|
+
# Will find all .rb files in the libdir/mcollective/pluginpackager/
|
|
139
|
+
# directory in all libdirs and load them from disk.
|
|
140
|
+
#
|
|
141
|
+
# You can influence what plugins get loaded using a block notation:
|
|
142
|
+
#
|
|
143
|
+
# find_and_load("pluginpackager") do |plugin|
|
|
144
|
+
# plugin.match(/puppet/)
|
|
145
|
+
# end
|
|
146
|
+
#
|
|
147
|
+
# This will load only plugins matching /puppet/
|
|
148
|
+
def self.find_and_load(type, extension="rb")
|
|
149
|
+
extension = ".#{extension}" unless extension.match(/^\./)
|
|
150
|
+
|
|
151
|
+
klasses = find(type, extension).map do |plugin|
|
|
152
|
+
if block_given?
|
|
153
|
+
next unless yield(plugin)
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
"%s::%s::%s" % [ "MCollective", type.capitalize, plugin.capitalize ]
|
|
157
|
+
end.compact
|
|
158
|
+
|
|
159
|
+
klasses.sort.uniq.each {|klass| loadclass(klass, true)}
|
|
160
|
+
end
|
|
161
|
+
|
|
162
|
+
# Loads a class from file by doing some simple search/replace
|
|
163
|
+
# on class names and then doing a require.
|
|
164
|
+
def self.loadclass(klass, squash_failures=false)
|
|
165
|
+
fname = klass.gsub("::", "/").downcase + ".rb"
|
|
166
|
+
|
|
167
|
+
Log.debug("Loading #{klass} from #{fname}")
|
|
168
|
+
|
|
169
|
+
load fname
|
|
170
|
+
rescue Exception => e
|
|
171
|
+
Log.error("Failed to load #{klass}: #{e}")
|
|
172
|
+
raise unless squash_failures
|
|
173
|
+
end
|
|
174
|
+
|
|
175
|
+
# Grep's over the plugin list and returns the list found
|
|
176
|
+
def self.grep(regex)
|
|
177
|
+
@plugins.keys.grep(regex)
|
|
178
|
+
end
|
|
179
|
+
end
|
|
180
|
+
end
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module PluginPackager
|
|
3
|
+
# Plugin definition classes
|
|
4
|
+
require "mcollective/pluginpackager/agent_definition"
|
|
5
|
+
require "mcollective/pluginpackager/standard_definition"
|
|
6
|
+
|
|
7
|
+
# Package implementation plugins
|
|
8
|
+
def self.load_packagers
|
|
9
|
+
PluginManager.find_and_load("pluginpackager")
|
|
10
|
+
end
|
|
11
|
+
|
|
12
|
+
def self.[](klass)
|
|
13
|
+
const_get("#{klass}")
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
# Fetch and return metadata from plugin DDL
|
|
17
|
+
def self.get_metadata(path, type)
|
|
18
|
+
ddl = DDL.new("package", type.to_sym, false)
|
|
19
|
+
|
|
20
|
+
begin
|
|
21
|
+
ddl_file = File.read(Dir.glob(File.join(path, type, "*.ddl")).first)
|
|
22
|
+
rescue Exception
|
|
23
|
+
raise "failed to load ddl file in plugin directory : #{File.join(path, type)}"
|
|
24
|
+
end
|
|
25
|
+
ddl.instance_eval ddl_file
|
|
26
|
+
|
|
27
|
+
return ddl.meta, ddl.requirements[:mcollective]
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
# Checks if a directory is present and not empty
|
|
31
|
+
def self.check_dir_present(path)
|
|
32
|
+
(File.directory?(path) && !Dir.glob(File.join(path, "*")).empty?)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
# Quietly calls a block if verbose parameter is false
|
|
36
|
+
def self.execute_verbosely(verbose, &block)
|
|
37
|
+
unless verbose
|
|
38
|
+
old_stdout = $stdout.clone
|
|
39
|
+
$stdout.reopen(File.new("/dev/null", "w"))
|
|
40
|
+
begin
|
|
41
|
+
block.call
|
|
42
|
+
rescue Exception => e
|
|
43
|
+
$stdout.reopen old_stdout
|
|
44
|
+
raise e
|
|
45
|
+
ensure
|
|
46
|
+
$stdout.reopen old_stdout
|
|
47
|
+
end
|
|
48
|
+
else
|
|
49
|
+
block.call
|
|
50
|
+
end
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
# Checks if a build tool is present on the system
|
|
54
|
+
def self.command_available?(build_tool)
|
|
55
|
+
ENV["PATH"].split(File::PATH_SEPARATOR).each do |path|
|
|
56
|
+
builder = File.join(path, build_tool)
|
|
57
|
+
if File.exists?(builder)
|
|
58
|
+
return true
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
false
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
def self.safe_system(*args)
|
|
65
|
+
raise(RuntimeError, "Failed: #{args.join(' ')}") unless system *args
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
# Filter out platform specific dependencies
|
|
69
|
+
# Given a list of dependencies named -
|
|
70
|
+
# debian::foo
|
|
71
|
+
# redhat::bar
|
|
72
|
+
# PluginPackager.filter_dependencies('debian', dependencies)
|
|
73
|
+
# will return foo.
|
|
74
|
+
def self.filter_dependencies(prefix, dependencies)
|
|
75
|
+
dependencies.map do |dependency|
|
|
76
|
+
if dependency[:name] =~ /^(\w+)::(\w+)/
|
|
77
|
+
if prefix == $1
|
|
78
|
+
dependency[:name] = $2
|
|
79
|
+
dependency
|
|
80
|
+
else
|
|
81
|
+
nil
|
|
82
|
+
end
|
|
83
|
+
else
|
|
84
|
+
dependency
|
|
85
|
+
end
|
|
86
|
+
end.reject{ |dependency| dependency == nil }
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Return the path to a plugin's core directories
|
|
90
|
+
def self.get_plugin_path(target)
|
|
91
|
+
if (File.exists?(File.join(target, "lib", "mcollective")))
|
|
92
|
+
return File.join(target, "lib", "mcollective")
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
return target
|
|
96
|
+
end
|
|
97
|
+
end
|
|
98
|
+
end
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module PluginPackager
|
|
3
|
+
# MCollective Agent Plugin package
|
|
4
|
+
class AgentDefinition
|
|
5
|
+
attr_accessor :path, :packagedata, :metadata, :target_path, :vendor, :revision, :preinstall
|
|
6
|
+
attr_accessor :plugintype, :dependencies, :postinstall, :mcname, :mcversion
|
|
7
|
+
|
|
8
|
+
def initialize(configuration, mcdependency, plugintype)
|
|
9
|
+
@plugintype = plugintype
|
|
10
|
+
@path = PluginPackager.get_plugin_path(configuration[:target])
|
|
11
|
+
@packagedata = {}
|
|
12
|
+
@revision = configuration[:revision] || 1
|
|
13
|
+
@preinstall = configuration[:preinstall]
|
|
14
|
+
@postinstall = configuration[:postinstall]
|
|
15
|
+
@vendor = configuration[:vendor] || "Puppet Labs"
|
|
16
|
+
@dependencies = configuration[:dependency] || []
|
|
17
|
+
@target_path = File.expand_path(@path)
|
|
18
|
+
@metadata, mcversion = PluginPackager.get_metadata(@path, "agent")
|
|
19
|
+
@mcname = mcdependency[:mcname] || "mcollective"
|
|
20
|
+
@mcversion = mcdependency[:mcversion] || mcversion
|
|
21
|
+
@metadata[:version] = (configuration[:version] || @metadata[:version])
|
|
22
|
+
@dependencies << {:name => "#{@mcname}-common", :version => @mcversion}
|
|
23
|
+
@metadata[:name] = (configuration[:pluginname] || @metadata[:name]).downcase.gsub(/\s+|_/, "-")
|
|
24
|
+
identify_packages
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
# Identify present packages and populate packagedata hash.
|
|
28
|
+
def identify_packages
|
|
29
|
+
common_package = common
|
|
30
|
+
@packagedata[:common] = common_package if common_package
|
|
31
|
+
agent_package = agent
|
|
32
|
+
@packagedata[:agent] = agent_package if agent_package
|
|
33
|
+
client_package = client
|
|
34
|
+
@packagedata[:client] = client_package if client_package
|
|
35
|
+
end
|
|
36
|
+
|
|
37
|
+
# Obtain Agent package files and dependencies.
|
|
38
|
+
def agent
|
|
39
|
+
agent = {:files => [],
|
|
40
|
+
:dependencies => @dependencies.clone,
|
|
41
|
+
:description => "Agent plugin for #{@metadata[:name]}"}
|
|
42
|
+
|
|
43
|
+
agentdir = File.join(@path, "agent")
|
|
44
|
+
|
|
45
|
+
if (PluginPackager.check_dir_present(agentdir))
|
|
46
|
+
ddls = Dir.glob(File.join(agentdir, "*.ddl"))
|
|
47
|
+
agent[:files] = (Dir.glob(File.join(agentdir, "**", "**")) - ddls)
|
|
48
|
+
else
|
|
49
|
+
return nil
|
|
50
|
+
end
|
|
51
|
+
agent[:plugindependency] = {:name => "#{@mcname}-#{@metadata[:name]}-common", :version => @metadata[:version], :revision => @revision}
|
|
52
|
+
agent
|
|
53
|
+
end
|
|
54
|
+
|
|
55
|
+
# Obtain client package files and dependencies.
|
|
56
|
+
def client
|
|
57
|
+
client = {:files => [],
|
|
58
|
+
:dependencies => @dependencies.clone,
|
|
59
|
+
:description => "Client plugin for #{@metadata[:name]}"}
|
|
60
|
+
|
|
61
|
+
clientdir = File.join(@path, "application")
|
|
62
|
+
aggregatedir = File.join(@path, "aggregate")
|
|
63
|
+
|
|
64
|
+
client[:files] += Dir.glob(File.join(clientdir, "*")) if PluginPackager.check_dir_present clientdir
|
|
65
|
+
client[:files] += Dir.glob(File.join(aggregatedir, "*")) if PluginPackager.check_dir_present aggregatedir
|
|
66
|
+
client[:plugindependency] = {:name => "#{@mcname}-#{@metadata[:name]}-common", :version => @metadata[:version], :revision => @revision}
|
|
67
|
+
client[:files].empty? ? nil : client
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
# Obtain common package files and dependencies.
|
|
71
|
+
def common
|
|
72
|
+
common = {:files =>[],
|
|
73
|
+
:dependencies => @dependencies.clone,
|
|
74
|
+
:description => "Common libraries for #{@metadata[:name]}"}
|
|
75
|
+
|
|
76
|
+
datadir = File.join(@path, "data", "**")
|
|
77
|
+
utildir = File.join(@path, "util", "**", "**")
|
|
78
|
+
ddldir = File.join(@path, "agent", "*.ddl")
|
|
79
|
+
validatordir = File.join(@path, "validator", "**")
|
|
80
|
+
|
|
81
|
+
[datadir, utildir, validatordir, ddldir].each do |directory|
|
|
82
|
+
common[:files] += Dir.glob(directory)
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# We fail if there is no ddl file present
|
|
86
|
+
if common[:files].grep(/^.*\.ddl$/).empty?
|
|
87
|
+
raise "cannot create package - No ddl file found in #{File.join(@path, "agent")}"
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
common[:files].empty? ? nil : common
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
end
|
|
@@ -0,0 +1,237 @@
|
|
|
1
|
+
module MCollective
|
|
2
|
+
module PluginPackager
|
|
3
|
+
class DebpackagePackager
|
|
4
|
+
require 'erb'
|
|
5
|
+
|
|
6
|
+
def initialize(plugin, pluginpath = nil, signature = nil, verbose = false, keep_artifacts = nil, module_template = nil)
|
|
7
|
+
if PluginPackager.command_available?('debuild')
|
|
8
|
+
@plugin = plugin
|
|
9
|
+
@verbose = verbose
|
|
10
|
+
@libdir = pluginpath || '/usr/share/mcollective/plugins/mcollective/'
|
|
11
|
+
@signature = signature
|
|
12
|
+
@package_name = "#{@plugin.mcname}-#{@plugin.metadata[:name]}"
|
|
13
|
+
@keep_artifacts = keep_artifacts
|
|
14
|
+
else
|
|
15
|
+
raise("Cannot build package. 'debuild' is not present on the system.")
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
# Build process :
|
|
20
|
+
# - create buildroot
|
|
21
|
+
# - craete buildroot/debian
|
|
22
|
+
# - create the relative directories with package contents
|
|
23
|
+
# - create install files for each of the plugins that are going to be built
|
|
24
|
+
# - create debian build files
|
|
25
|
+
# - create tarball
|
|
26
|
+
# - create pre and post install files
|
|
27
|
+
# - run the build script
|
|
28
|
+
# - move packages to cwd
|
|
29
|
+
# - clean up
|
|
30
|
+
def create_packages
|
|
31
|
+
begin
|
|
32
|
+
puts "Building packages for #{@package_name} plugin."
|
|
33
|
+
|
|
34
|
+
@tmpdir = Dir.mktmpdir('mcollective_packager')
|
|
35
|
+
@build_dir = File.join(@tmpdir, "#{@package_name}_#{@plugin.metadata[:version]}")
|
|
36
|
+
Dir.mkdir(@build_dir)
|
|
37
|
+
|
|
38
|
+
create_debian_dir
|
|
39
|
+
@plugin.packagedata.each do |type, data|
|
|
40
|
+
prepare_tmpdirs(data)
|
|
41
|
+
create_install_file(type, data)
|
|
42
|
+
create_pre_and_post_install(type)
|
|
43
|
+
end
|
|
44
|
+
create_debian_files
|
|
45
|
+
create_tar
|
|
46
|
+
run_build
|
|
47
|
+
move_packages
|
|
48
|
+
|
|
49
|
+
puts "Completed building all packages for #{@package_name} plugin."
|
|
50
|
+
ensure
|
|
51
|
+
if @keep_artifacts
|
|
52
|
+
puts 'Keeping build artifacts.'
|
|
53
|
+
puts "Build artifacts saved - #{@tmpdir}"
|
|
54
|
+
else
|
|
55
|
+
puts 'Removing build artifacts.'
|
|
56
|
+
cleanup_tmpdirs
|
|
57
|
+
end
|
|
58
|
+
end
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
private
|
|
62
|
+
|
|
63
|
+
def create_debian_files
|
|
64
|
+
['control', 'Makefile', 'compat', 'rules', 'copyright', 'changelog'].each do |f|
|
|
65
|
+
create_file(f)
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
|
|
69
|
+
def run_build
|
|
70
|
+
FileUtils.cd(@build_dir) do
|
|
71
|
+
PluginPackager.execute_verbosely(@verbose) do
|
|
72
|
+
if @signature
|
|
73
|
+
if @signature.is_a?(String)
|
|
74
|
+
PluginPackager.safe_system("debuild --no-lintian -i -k#{@signature}")
|
|
75
|
+
else
|
|
76
|
+
PluginPackager.safe_system("debuild --no-lintian -i")
|
|
77
|
+
end
|
|
78
|
+
else
|
|
79
|
+
PluginPackager.safe_system("debuild --no-lintian -i -us -uc")
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
# Creates a string used by the control file to specify dependencies
|
|
86
|
+
# Dependencies can be formatted as :
|
|
87
|
+
# foo (>= x.x-x)
|
|
88
|
+
# foo (>= x.x)
|
|
89
|
+
# foo
|
|
90
|
+
def build_dependency_string(data)
|
|
91
|
+
dependencies = []
|
|
92
|
+
PluginPackager.filter_dependencies('debian', data[:dependencies]).each do |dep|
|
|
93
|
+
if dep[:version] && dep[:revision]
|
|
94
|
+
dependencies << "#{dep[:name]} (>=#{dep[:version]}-#{dep[:revision]}) | puppet-agent"
|
|
95
|
+
elsif dep[:version]
|
|
96
|
+
dependencies << "#{dep[:name]} (>=#{dep[:version]}) | puppet-agent"
|
|
97
|
+
else
|
|
98
|
+
dependencies << "#{dep[:name]} | puppet-agent"
|
|
99
|
+
end
|
|
100
|
+
end
|
|
101
|
+
|
|
102
|
+
if data[:plugindependency]
|
|
103
|
+
dependencies << "#{data[:plugindependency][:name]} (= ${binary:Version})"
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
dependencies.join(', ')
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# Creates an install file for each of the packages that are going to be created
|
|
110
|
+
# for the plugin
|
|
111
|
+
def create_install_file(type, data)
|
|
112
|
+
install_file = "#{@package_name}-#{type}"
|
|
113
|
+
begin
|
|
114
|
+
install_file = File.join(@build_dir, 'debian', "#{install_file}.install")
|
|
115
|
+
File.open(install_file, 'w') do |file|
|
|
116
|
+
data[:files].each do |f|
|
|
117
|
+
extended_filename = File.join(@libdir, File.expand_path(f).gsub(/^#{@plugin.target_path}/, ''))
|
|
118
|
+
file.puts "#{extended_filename} #{File.dirname(extended_filename)}"
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
rescue Errno::EACCES => e
|
|
122
|
+
puts "Could not create install file '#{install_file}'. Permission denied"
|
|
123
|
+
raise e
|
|
124
|
+
rescue => e
|
|
125
|
+
puts "Could not create install file '#{install_file}'."
|
|
126
|
+
raise e
|
|
127
|
+
end
|
|
128
|
+
end
|
|
129
|
+
|
|
130
|
+
# Move source package and debs to cwd
|
|
131
|
+
def move_packages
|
|
132
|
+
begin
|
|
133
|
+
files_to_copy = Dir.glob(File.join(@tmpdir, '*.{deb,dsc,diff.gz,orig.tar.gz,changes}'))
|
|
134
|
+
FileUtils.cp(files_to_copy, '.')
|
|
135
|
+
rescue => e
|
|
136
|
+
puts 'Could not copy packages to working directory.'
|
|
137
|
+
raise e
|
|
138
|
+
end
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
# Create pre and post install files in $buildroot/debian
|
|
142
|
+
# from supplied scripts.
|
|
143
|
+
# Note that all packages built for the plugin will invoke
|
|
144
|
+
# the same pre and post install scripts.
|
|
145
|
+
def create_pre_and_post_install(type)
|
|
146
|
+
if @plugin.preinstall
|
|
147
|
+
if !File.exists?(@plugin.preinstall)
|
|
148
|
+
puts "pre-install script '#{@plugin.preinstall}' not found."
|
|
149
|
+
raise(Errno::ENOENT, @plugin.preinstall)
|
|
150
|
+
else
|
|
151
|
+
FileUtils.cp(@plugin.preinstall, File.join(@build_dir, 'debian', "#{@package_name}-#{type}.preinst"))
|
|
152
|
+
end
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
if @plugin.postinstall
|
|
156
|
+
if !File.exists?(@plugin.postinstall)
|
|
157
|
+
puts "post-install script '#{@plugin.postinstall}' not found."
|
|
158
|
+
raise(Errno::ENOENT, @plugin.postinstall)
|
|
159
|
+
else
|
|
160
|
+
FileUtils.cp(@plugin.postinstall, File.join(@build_dir, 'debian', "#{@package_name}-#{type}.postinst"))
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# Tar up source
|
|
166
|
+
# Expects directory : $mcollective-$agent_$version
|
|
167
|
+
# Creates file : $buildroot/$mcollective-$agent_$version.orig.tar.gz
|
|
168
|
+
def create_tar
|
|
169
|
+
name_and_version = "#{@package_name}_#{@plugin.metadata[:version]}"
|
|
170
|
+
tarfile = "#{name_and_version}.orig.tar.gz"
|
|
171
|
+
begin
|
|
172
|
+
PluginPackager.execute_verbosely(@verbose) do
|
|
173
|
+
Dir.chdir(@tmpdir) do
|
|
174
|
+
PluginPackager.safe_system("tar -Pcvzf #{File.join(@tmpdir, tarfile)} #{name_and_version}")
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
rescue Exception => e
|
|
178
|
+
puts "Could not create tarball - #{tarfile}"
|
|
179
|
+
raise e
|
|
180
|
+
end
|
|
181
|
+
end
|
|
182
|
+
|
|
183
|
+
def create_file(filename)
|
|
184
|
+
begin
|
|
185
|
+
file = ERB.new(File.read(File.join(File.dirname(__FILE__), 'templates', 'debian', "#{filename}.erb")), nil, '-')
|
|
186
|
+
File.open(File.join(@build_dir, 'debian', filename), 'w') do |f|
|
|
187
|
+
f.puts file.result(binding)
|
|
188
|
+
end
|
|
189
|
+
rescue => e
|
|
190
|
+
puts "Could not create file - '#{filename}'"
|
|
191
|
+
raise e
|
|
192
|
+
end
|
|
193
|
+
end
|
|
194
|
+
|
|
195
|
+
# Move files contained in the plugin to the correct directory
|
|
196
|
+
# relative to the build root.
|
|
197
|
+
def prepare_tmpdirs(data)
|
|
198
|
+
data[:files].each do |file|
|
|
199
|
+
begin
|
|
200
|
+
targetdir = File.join(@build_dir, @libdir, File.dirname(File.expand_path(file)).gsub(/^#{@plugin.target_path}/, ""))
|
|
201
|
+
FileUtils.mkdir_p(targetdir) unless File.directory?(targetdir)
|
|
202
|
+
FileUtils.cp_r(file, targetdir)
|
|
203
|
+
rescue Errno::EACCES => e
|
|
204
|
+
puts "Could not create directory '#{targetdir}'. Permission denied"
|
|
205
|
+
raise e
|
|
206
|
+
rescue Errno::ENOENT => e
|
|
207
|
+
puts "Could not copy file '#{file}' to '#{targetdir}'. File does not exist"
|
|
208
|
+
raise e
|
|
209
|
+
rescue => e
|
|
210
|
+
puts 'Could not prepare build directory'
|
|
211
|
+
raise e
|
|
212
|
+
end
|
|
213
|
+
end
|
|
214
|
+
end
|
|
215
|
+
|
|
216
|
+
# Create the $buildroot/debian directory
|
|
217
|
+
def create_debian_dir
|
|
218
|
+
deb_dir = File.join(@build_dir, 'debian')
|
|
219
|
+
begin
|
|
220
|
+
FileUtils.mkdir_p(deb_dir)
|
|
221
|
+
rescue => e
|
|
222
|
+
puts "Could not create directory '#{deb_dir}'"
|
|
223
|
+
raise e
|
|
224
|
+
end
|
|
225
|
+
end
|
|
226
|
+
|
|
227
|
+
def cleanup_tmpdirs
|
|
228
|
+
begin
|
|
229
|
+
FileUtils.rm_r(@tmpdir) if File.directory?(@tmpdir)
|
|
230
|
+
rescue => e
|
|
231
|
+
puts "Could not remove temporary build directory - '#{@tmpdir}'"
|
|
232
|
+
raise e
|
|
233
|
+
end
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
end
|
|
237
|
+
end
|