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.
Files changed (133) hide show
  1. checksums.yaml +7 -0
  2. data/bin/mco +64 -0
  3. data/lib/mcollective.rb +63 -0
  4. data/lib/mcollective/agent.rb +5 -0
  5. data/lib/mcollective/agents.rb +149 -0
  6. data/lib/mcollective/aggregate.rb +85 -0
  7. data/lib/mcollective/aggregate/average.ddl +33 -0
  8. data/lib/mcollective/aggregate/average.rb +29 -0
  9. data/lib/mcollective/aggregate/base.rb +40 -0
  10. data/lib/mcollective/aggregate/result.rb +9 -0
  11. data/lib/mcollective/aggregate/result/base.rb +25 -0
  12. data/lib/mcollective/aggregate/result/collection_result.rb +19 -0
  13. data/lib/mcollective/aggregate/result/numeric_result.rb +13 -0
  14. data/lib/mcollective/aggregate/sum.ddl +33 -0
  15. data/lib/mcollective/aggregate/sum.rb +18 -0
  16. data/lib/mcollective/aggregate/summary.ddl +33 -0
  17. data/lib/mcollective/aggregate/summary.rb +53 -0
  18. data/lib/mcollective/application.rb +365 -0
  19. data/lib/mcollective/application/completion.rb +104 -0
  20. data/lib/mcollective/application/describe_filter.rb +87 -0
  21. data/lib/mcollective/application/facts.rb +62 -0
  22. data/lib/mcollective/application/find.rb +23 -0
  23. data/lib/mcollective/application/help.rb +28 -0
  24. data/lib/mcollective/application/inventory.rb +344 -0
  25. data/lib/mcollective/application/ping.rb +82 -0
  26. data/lib/mcollective/application/plugin.rb +369 -0
  27. data/lib/mcollective/application/rpc.rb +111 -0
  28. data/lib/mcollective/applications.rb +134 -0
  29. data/lib/mcollective/cache.rb +145 -0
  30. data/lib/mcollective/client.rb +353 -0
  31. data/lib/mcollective/config.rb +245 -0
  32. data/lib/mcollective/connector.rb +18 -0
  33. data/lib/mcollective/connector/base.rb +26 -0
  34. data/lib/mcollective/data.rb +91 -0
  35. data/lib/mcollective/data/agent_data.ddl +22 -0
  36. data/lib/mcollective/data/agent_data.rb +17 -0
  37. data/lib/mcollective/data/base.rb +67 -0
  38. data/lib/mcollective/data/collective_data.ddl +20 -0
  39. data/lib/mcollective/data/collective_data.rb +9 -0
  40. data/lib/mcollective/data/fact_data.ddl +28 -0
  41. data/lib/mcollective/data/fact_data.rb +55 -0
  42. data/lib/mcollective/data/fstat_data.ddl +89 -0
  43. data/lib/mcollective/data/fstat_data.rb +56 -0
  44. data/lib/mcollective/data/result.rb +45 -0
  45. data/lib/mcollective/ddl.rb +113 -0
  46. data/lib/mcollective/ddl/agentddl.rb +253 -0
  47. data/lib/mcollective/ddl/base.rb +217 -0
  48. data/lib/mcollective/ddl/dataddl.rb +56 -0
  49. data/lib/mcollective/ddl/discoveryddl.rb +52 -0
  50. data/lib/mcollective/ddl/validatorddl.rb +6 -0
  51. data/lib/mcollective/discovery.rb +143 -0
  52. data/lib/mcollective/discovery/flatfile.ddl +11 -0
  53. data/lib/mcollective/discovery/flatfile.rb +48 -0
  54. data/lib/mcollective/discovery/mc.ddl +11 -0
  55. data/lib/mcollective/discovery/mc.rb +30 -0
  56. data/lib/mcollective/discovery/stdin.ddl +11 -0
  57. data/lib/mcollective/discovery/stdin.rb +68 -0
  58. data/lib/mcollective/exceptions.rb +28 -0
  59. data/lib/mcollective/facts.rb +39 -0
  60. data/lib/mcollective/facts/base.rb +100 -0
  61. data/lib/mcollective/facts/yaml_facts.rb +65 -0
  62. data/lib/mcollective/generators.rb +7 -0
  63. data/lib/mcollective/generators/agent_generator.rb +51 -0
  64. data/lib/mcollective/generators/base.rb +46 -0
  65. data/lib/mcollective/generators/data_generator.rb +51 -0
  66. data/lib/mcollective/generators/templates/action_snippet.erb +13 -0
  67. data/lib/mcollective/generators/templates/data_input_snippet.erb +7 -0
  68. data/lib/mcollective/generators/templates/ddl.erb +8 -0
  69. data/lib/mcollective/generators/templates/plugin.erb +7 -0
  70. data/lib/mcollective/log.rb +118 -0
  71. data/lib/mcollective/logger.rb +5 -0
  72. data/lib/mcollective/logger/base.rb +77 -0
  73. data/lib/mcollective/logger/console_logger.rb +61 -0
  74. data/lib/mcollective/logger/file_logger.rb +53 -0
  75. data/lib/mcollective/logger/syslog_logger.rb +53 -0
  76. data/lib/mcollective/matcher.rb +224 -0
  77. data/lib/mcollective/matcher/parser.rb +128 -0
  78. data/lib/mcollective/matcher/scanner.rb +241 -0
  79. data/lib/mcollective/message.rb +248 -0
  80. data/lib/mcollective/monkey_patches.rb +152 -0
  81. data/lib/mcollective/optionparser.rb +197 -0
  82. data/lib/mcollective/pluginmanager.rb +180 -0
  83. data/lib/mcollective/pluginpackager.rb +98 -0
  84. data/lib/mcollective/pluginpackager/agent_definition.rb +94 -0
  85. data/lib/mcollective/pluginpackager/debpackage_packager.rb +237 -0
  86. data/lib/mcollective/pluginpackager/modulepackage_packager.rb +127 -0
  87. data/lib/mcollective/pluginpackager/ospackage_packager.rb +59 -0
  88. data/lib/mcollective/pluginpackager/rpmpackage_packager.rb +180 -0
  89. data/lib/mcollective/pluginpackager/standard_definition.rb +69 -0
  90. data/lib/mcollective/pluginpackager/templates/debian/Makefile.erb +7 -0
  91. data/lib/mcollective/pluginpackager/templates/debian/changelog.erb +5 -0
  92. data/lib/mcollective/pluginpackager/templates/debian/compat.erb +1 -0
  93. data/lib/mcollective/pluginpackager/templates/debian/control.erb +15 -0
  94. data/lib/mcollective/pluginpackager/templates/debian/copyright.erb +8 -0
  95. data/lib/mcollective/pluginpackager/templates/debian/rules.erb +6 -0
  96. data/lib/mcollective/pluginpackager/templates/module/Modulefile.erb +5 -0
  97. data/lib/mcollective/pluginpackager/templates/module/README.md.erb +37 -0
  98. data/lib/mcollective/pluginpackager/templates/module/_manifest.pp.erb +9 -0
  99. data/lib/mcollective/pluginpackager/templates/redhat/rpm_spec.erb +63 -0
  100. data/lib/mcollective/registration/base.rb +91 -0
  101. data/lib/mcollective/rpc.rb +182 -0
  102. data/lib/mcollective/rpc/actionrunner.rb +158 -0
  103. data/lib/mcollective/rpc/agent.rb +374 -0
  104. data/lib/mcollective/rpc/audit.rb +38 -0
  105. data/lib/mcollective/rpc/client.rb +1066 -0
  106. data/lib/mcollective/rpc/helpers.rb +321 -0
  107. data/lib/mcollective/rpc/progress.rb +63 -0
  108. data/lib/mcollective/rpc/reply.rb +87 -0
  109. data/lib/mcollective/rpc/request.rb +86 -0
  110. data/lib/mcollective/rpc/result.rb +90 -0
  111. data/lib/mcollective/rpc/stats.rb +294 -0
  112. data/lib/mcollective/runnerstats.rb +90 -0
  113. data/lib/mcollective/security.rb +26 -0
  114. data/lib/mcollective/security/base.rb +244 -0
  115. data/lib/mcollective/shell.rb +126 -0
  116. data/lib/mcollective/ssl.rb +285 -0
  117. data/lib/mcollective/util.rb +579 -0
  118. data/lib/mcollective/validator.rb +85 -0
  119. data/lib/mcollective/validator/array_validator.ddl +7 -0
  120. data/lib/mcollective/validator/array_validator.rb +9 -0
  121. data/lib/mcollective/validator/ipv4address_validator.ddl +7 -0
  122. data/lib/mcollective/validator/ipv4address_validator.rb +16 -0
  123. data/lib/mcollective/validator/ipv6address_validator.ddl +7 -0
  124. data/lib/mcollective/validator/ipv6address_validator.rb +16 -0
  125. data/lib/mcollective/validator/length_validator.ddl +7 -0
  126. data/lib/mcollective/validator/length_validator.rb +11 -0
  127. data/lib/mcollective/validator/regex_validator.ddl +7 -0
  128. data/lib/mcollective/validator/regex_validator.rb +9 -0
  129. data/lib/mcollective/validator/shellsafe_validator.ddl +7 -0
  130. data/lib/mcollective/validator/shellsafe_validator.rb +13 -0
  131. data/lib/mcollective/validator/typecheck_validator.ddl +7 -0
  132. data/lib/mcollective/validator/typecheck_validator.rb +28 -0
  133. 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