choria-mcorpc-support 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|