forked from choria-legacy/marionette-collective
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
MCollective plugin application allows us to package mcollective plugins as debs or rpms using the mco command. Plugin types are defined by definition classes that populates a list of files and metadata which are in turn passed over to packager classes which will build the action package. Currently agent plugins are defined in AgentDefinition and debs and rpms are created with the OSpackagePackager, which uses FPM to output the packages. Additionally the info action will display plugin related metadata and a list of packages that will be created from a target directory.
- Loading branch information
Showing
12 changed files
with
876 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
module MCollective | ||
module PluginPackager | ||
# Plugin definition classes | ||
autoload :AgentDefinition, "mcollective/pluginpackager/agent_definition" | ||
|
||
# Package implementation plugins | ||
def self.load_packagers | ||
PluginManager.find_and_load("pluginpackager") | ||
end | ||
|
||
def self.[](klass) | ||
const_get("#{klass}") | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
module MCollective | ||
module PluginPackager | ||
# MCollective Agent Plugin package | ||
class AgentDefinition | ||
attr_accessor :path, :packagedata, :metadata, :target_path, :vendor, :iteration, :postinstall | ||
|
||
def initialize(path, name, vendor, postinstall, iteration) | ||
@path = path | ||
@packagedata = {} | ||
@iteration = iteration || 1 | ||
@postinstall = postinstall | ||
@vendor = vendor || "Puppet Labs" | ||
@target_path = File.expand_path(@path) | ||
@metadata = get_metadata | ||
@metadata[:name] = name if name | ||
@metadata[:name] = @metadata[:name].downcase.gsub(" ", "_") | ||
identify_packages | ||
end | ||
|
||
# Identify present packages and populate packagedata hash. | ||
def identify_packages | ||
@packagedata[:common] = common | ||
@packagedata[:agent] = agent | ||
@packagedata[:client] = client | ||
end | ||
|
||
# Obtain Agent package files and dependencies. | ||
def agent | ||
agent = {:files => [], | ||
:dependencies => ["mcollective"], | ||
:description => "Agent plugin for #{@metadata[:name]}"} | ||
|
||
agentdir = File.join(@path, "agent") | ||
|
||
if check_dir agentdir | ||
ddls = Dir.glob "#{agentdir}/*.ddl" | ||
agent[:files] = (Dir.glob("#{agentdir}/*") - ddls) | ||
implementations = Dir.glob("#{@metadata[:name]}/**") | ||
agent[:files] += implementations unless implementations.empty? | ||
else | ||
return nil | ||
end | ||
|
||
agent[:dependencies] << "mcollective-#{@metadata[:name]}-common" if @packagedata[:common] | ||
agent | ||
end | ||
|
||
# Obtain client package files and dependencies. | ||
def client | ||
client = {:files => [], | ||
:dependencies => ["mcollective-client"], | ||
:description => "Client plugin for #{@metadata[:name]}"} | ||
|
||
clientdir = File.join(@path, "application") | ||
bindir = File.join(@path, "bin") | ||
ddldir = File.join(@path, "agent") | ||
|
||
client[:files] += Dir.glob("#{clientdir}/*") if check_dir clientdir | ||
client[:files] += Dir.glob("#{bindir}/*") if check_dir bindir | ||
client[:files] += Dir.glob("#{ddldir}/*.ddl") if check_dir ddldir | ||
client[:dependencies] << "mcollective-#{@metadata[:name]}-common" if @packagedata[:common] | ||
client[:files].empty? ? nil : client | ||
end | ||
|
||
# Obtain common package files and dependencies. | ||
def common | ||
common = {:files =>[], | ||
:dependencies => ["mcollective-common"], | ||
:description => "Common libraries for #{@metadata[:name]}"} | ||
|
||
commondir = File.join(@path, "util") | ||
common[:files] += Dir.glob("#{commondir}/*") if check_dir commondir | ||
common[:files].empty? ? nil : common | ||
end | ||
|
||
# Load plugin meta data from ddl file. | ||
def get_metadata | ||
ddl = MCollective::RPC::DDL.new("package", false) | ||
ddl.instance_eval File.read(Dir.glob("#{@path}/agent/*.ddl").first) | ||
ddl.meta | ||
rescue | ||
raise "error: could not read agent DDL File" | ||
end | ||
|
||
# Check if directory is present and not empty. | ||
def check_dir(path) | ||
(File.directory?(path) && !Dir.glob(path).empty?) ? true : false | ||
end | ||
end | ||
end | ||
end |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,130 @@ | ||
module MCollective | ||
class Application::Plugin<Application | ||
|
||
exclude_argument_sections "common", "filter", "rpc" | ||
|
||
description "MCollective Plugin Application" | ||
usage <<-END_OF_USAGE | ||
mco plugin package [options] <directory> | ||
mco plugin info <directory> | ||
mco plugin doc <agent> | ||
info : Display plugin information including package details. | ||
package : Create all available plugin packages. | ||
doc : Application list and RPC agent help | ||
END_OF_USAGE | ||
|
||
option :pluginname, | ||
:description => "Plugin name", | ||
:arguments => ["-n", "--name NAME"], | ||
:type => String | ||
|
||
option :postinstall, | ||
:description => "Post install script", | ||
:arguments => ["--postinstall POSTINSTALL"], | ||
:type => String | ||
|
||
option :iteration, | ||
:description => "Iteration number", | ||
:arguments => ["--iteration ITERATION"], | ||
:type => String | ||
|
||
option :vendor, | ||
:description => "Vendor name", | ||
:arguments => ["--vendor VENDOR"], | ||
:type => String | ||
|
||
option :format, | ||
:description => "Package output format. Defaults to rpm or deb", | ||
:arguments => ["--format OUTPUTFORMAT"], | ||
:type => String | ||
|
||
option :plugintype, | ||
:description => "Plugin type.", | ||
:arguments => ["--plugintype PLUGINTYPE"], | ||
:type => String | ||
|
||
option :rpctemplate, | ||
:description => "RPC Template to use.", | ||
:arguments => ["--template RPCHELPTEMPLATE"], | ||
:type => String | ||
|
||
# Handle alternative format that optparser can't parse. | ||
def post_option_parser(configuration) | ||
if ARGV.length >= 1 | ||
configuration[:action] = ARGV.delete_at(0) | ||
|
||
configuration[:target] = ARGV.delete_at(0) || "." | ||
end | ||
end | ||
|
||
# Display info about plugin | ||
def info_command | ||
plugin = prepare_plugin | ||
packager = PluginPackager["#{configuration[:format].capitalize}Packager"] | ||
packager.new(plugin).package_information | ||
end | ||
|
||
# Package plugin | ||
def package_command | ||
plugin = prepare_plugin | ||
packager = PluginPackager["#{configuration[:format].capitalize}Packager"] | ||
packager.new(plugin).create_packages | ||
end | ||
|
||
# Show application list and RPC agent help | ||
def doc_command | ||
if configuration.include?(:target) && configuration[:target] != "." | ||
ddl = MCollective::RPC::DDL.new(configuration[:target]) | ||
puts ddl.help(configuration[:rpctemplate] || Config.instance.rpchelptemplate) | ||
else | ||
puts "The Marionette Collective version #{MCollective.version}" | ||
puts | ||
|
||
PluginManager.find("agent", "ddl").each do |ddl| | ||
help = MCollective::RPC::DDL.new(ddl) | ||
puts " %-15s %s" % [ddl, help.meta[:description]] | ||
end | ||
end | ||
end | ||
|
||
# Creates the correct package plugin object. | ||
def prepare_plugin | ||
set_plugin_type unless configuration[:plugintype] | ||
configuration[:format] = "ospackage" unless configuration[:format] | ||
PluginPackager.load_packagers | ||
plugin_class = PluginPackager[configuration[:plugintype]] | ||
plugin_class.new(configuration[:target], configuration[:pluginname], configuration[:vendor], configuration[:postinstall], configuration[:iteration]) | ||
end | ||
|
||
def directory_for_type(type) | ||
File.directory?(File.join(configuration[:target], type)) | ||
end | ||
|
||
# Identify plugin type if not provided. | ||
def set_plugin_type | ||
if directory_for_type("agent") || directory_for_type("application") | ||
configuration[:plugintype] = "AgentDefinition" | ||
else | ||
raise "error. target directory is not a valid mcollective plugin" | ||
end | ||
end | ||
|
||
# Returns a list of available actions in a pretty format | ||
def list_actions | ||
methods.sort.grep(/_command/).map{|x| x.to_s.gsub("_command", "")}.join("|") | ||
end | ||
|
||
def main | ||
abort "No action specified" unless configuration.include?(:action) | ||
|
||
cmd = "#{configuration[:action]}_command" | ||
|
||
if respond_to? cmd | ||
send cmd | ||
else | ||
abort "Invalid action #{configuration[:action]}. Valid actions are [#{list_actions}]." | ||
end | ||
end | ||
end | ||
end |
Oops, something went wrong.