Update version according to OSCI-883
[packages/precise/mcollective.git] / plugins / mcollective / pluginpackager / rpmpackage_packager.rb
index bb6c62509e7ca79325b59d3cee5cba9fb33cf0d0..7d8fa699be6fc543965442d70b580b0d6c57237f 100644 (file)
@@ -1,27 +1,33 @@
 module MCollective
   module PluginPackager
     class RpmpackagePackager
-
       require 'erb'
-      attr_accessor :plugin, :tmpdir, :verbose, :libdir, :workingdir
-      attr_accessor :current_package_type, :current_package_data
-      attr_accessor :current_package_name, :signature
-
-      def initialize(plugin, pluginpath = nil, signature = nil, verbose = false)
-        if(PluginPackager.build_tool?("rpmbuild-md5"))
-          @buildtool = "rpmbuild-md5"
-        elsif(PluginPackager.build_tool?("rpmbuild"))
-          @buildtool = "rpmbuild"
+
+      def initialize(plugin, pluginpath = nil, signature = nil, verbose = false, keep_artifacts = nil, module_template = nil)
+        if @buildtool = select_command
+          @plugin = plugin
+          @package_name = "#{@plugin.mcname}-#{@plugin.metadata[:name]}"
+          @package_name_and_version = "#{@package_name}-#{@plugin.metadata[:version]}"
+          @verbose = verbose
+          @libdir = pluginpath || '/usr/libexec/mcollective/mcollective/'
+          @signature = signature
+          @rpmdir = rpmdir
+          @srpmdir = srpmdir
+          @keep_artifacts = keep_artifacts
         else
-          raise RuntimeError, "creating rpms require 'rpmbuild' or 'rpmbuild-md5' to be installed"
+          raise("Cannot build package. 'rpmbuild' or 'rpmbuild-md5' is not present on the system")
         end
+      end
 
-        @plugin = plugin
-        @verbose = verbose
-        @libdir = pluginpath || "/usr/libexec/mcollective/mcollective/"
-        @signature = signature
-        @rpmdir = rpmdir
-        @srpmdir = srpmdir
+      # Determine the build tool present on the system
+      def select_command
+        if PluginPackager.command_available?('rpmbuild-md5')
+          return 'rpmbuild-md5'
+        elsif PluginPackager.command_available?('rpmbuild')
+          return 'rpmbuild'
+        else
+          return nil
+        end
       end
 
       def rpmdir
@@ -32,65 +38,141 @@ module MCollective
         `rpm --eval '%_srcrpmdir'`.chomp
       end
 
+      # Build Process :
+      # - create temporary buildroot
+      # - create the spec file
+      # - create the tarball
+      # - run the build script
+      # - move pacakges to cwd
+      # - clean up
       def create_packages
-        @plugin.packagedata.each do |type, data|
-          begin
-            @current_package_type = type
-            @current_package_data = data
-            @current_package_name = "#{@plugin.mcname}-#{@plugin.metadata[:name]}-#{@current_package_type}"
-            @tmpdir = Dir.mktmpdir("mcollective_packager")
-            prepare_tmpdirs data
-            create_package type, data
-          rescue Exception => e
-            raise e
-          ensure
+        begin
+          puts "Building packages for #{@package_name} plugin."
+
+          @tmpdir = Dir.mktmpdir('mcollective_packager')
+          prepare_tmpdirs
+
+          make_spec_file
+          run_build
+          move_packages
+
+          puts "Completed building all packages for #{@package_name} plugin."
+        ensure
+          if @keep_artifacts
+            puts 'Keeping build artifacts'
+            puts "Build artifacts saved - #{@tmpdir}"
+          else
             cleanup_tmpdirs
           end
         end
       end
 
-      def create_package(type, data)
+      private
+
+      def run_build
         begin
-          tarfile = "#{@current_package_name}-#{@plugin.metadata[:version]}.tgz"
-          make_spec_file
-          PluginPackager.do_quietly?(verbose) do
+          tarfile = create_tar
+          PluginPackager.execute_verbosely(@verbose) do
+            PluginPackager.safe_system("#{@buildtool} -ta#{" --quiet" unless @verbose}#{" --sign" if @signature} #{tarfile}")
+          end
+        rescue => e
+          puts 'Build process has failed'
+          raise e
+        end
+      end
+
+      # Tar up source
+      # Expects directory $mcollective-$agent-$version
+      # Creates file : $tmpbuildroot/$mcollective-$agent-$version
+      def create_tar
+        tarfile = File.join(@tmpdir, "#{@package_name_and_version}.tgz")
+        begin
+         PluginPackager.execute_verbosely(@verbose) do
             Dir.chdir(@tmpdir) do
-              PluginPackager.safe_system("tar -cvzf #{File.join(@tmpdir, tarfile)} #{@current_package_name}-#{@plugin.metadata[:version]}")
+              PluginPackager.safe_system("tar -cvzf #{tarfile} #{@package_name_and_version}")
             end
-
-            PluginPackager.safe_system("#{@buildtool} -ta #{"--quiet" unless verbose} #{"--sign" if @signature} #{File.join(@tmpdir, tarfile)}")
           end
+        rescue => e
+          puts "Could not create tarball - '#{tarfile}'"
+          raise e
+        end
+        tarfile
+      end
 
-          FileUtils.cp(File.join(@rpmdir, "noarch", "#{@current_package_name}-#{@plugin.metadata[:version]}-#{@plugin.iteration}.noarch.rpm"), ".")
-          FileUtils.cp(File.join(@srpmdir, "#{@current_package_name}-#{@plugin.metadata[:version]}-#{@plugin.iteration}.src.rpm"), ".")
-
-          puts "Created RPM and SRPM packages for #{@current_package_name}"
-        rescue Exception => e
-          raise RuntimeError, "Could not build package. Reason - #{e}"
+      # Move rpm's and srpm's to cwd
+      def move_packages
+        begin
+          files_to_copy = Dir.glob(File.join(@rpmdir, 'noarch', "#{@package_name}-*-#{@plugin.metadata[:version]}-#{@plugin.revision}.noarch.rpm"))
+          files_to_copy << File.join(@srpmdir, "#{@package_name}-#{@plugin.metadata[:version]}-#{@plugin.revision}.src.rpm")
+          FileUtils.cp(files_to_copy, '.')
+        rescue => e
+          puts 'Could not copy packages to working directory'
+          raise e
         end
       end
 
+      # Create the specfile and place as $tmpbuildroot/$mcollective-$agent-$version/$mcollective-$agent-$version.spec
       def make_spec_file
+        spec_file = File.join(@tmpdir, @package_name_and_version, "#{@package_name_and_version}.spec")
         begin
-          spec_template = ERB.new(File.read(File.join(File.dirname(__FILE__), "templates", "redhat", "rpm_spec.erb")), nil, "-")
-          File.open(File.join(@tmpdir, "#{@current_package_name}-#{@plugin.metadata[:version]}" ,"#{@current_package_name}-#{@plugin.metadata[:version]}.spec"), "w") do |f|
+          spec_template = ERB.new(File.read(File.join(File.dirname(__FILE__), 'templates', 'redhat', 'rpm_spec.erb')), nil, '-')
+          File.open(spec_file, 'w') do |f|
             f.puts spec_template.result(binding)
           end
-        rescue Exception => e
-          raise RuntimeError, "Could not create specfile - #{e}"
+        rescue => e
+          puts "Could not create specfile - '#{spec_file}'"
+          raise e
         end
       end
 
-      def prepare_tmpdirs(data)
-        data[:files].each do |file|
-          targetdir = File.join(@tmpdir, "#{@current_package_name}-#{@plugin.metadata[:version]}", @libdir, File.dirname(File.expand_path(file)).gsub(@plugin.target_path, ""))
-          FileUtils.mkdir_p(targetdir) unless File.directory? targetdir
-          FileUtils.cp_r(file, targetdir)
+      # Move files contained in the plugin to the correct directory
+      # relative to the build root.
+      def prepare_tmpdirs
+        plugin_files.each do |file|
+          begin
+            targetdir = File.join(@tmpdir, @package_name_and_version, @libdir, File.dirname(File.expand_path(file)).gsub(@plugin.target_path, ""))
+            FileUtils.mkdir_p(targetdir) unless File.directory?(targetdir)
+            FileUtils.cp_r(file, targetdir)
+          rescue Errno::EACCES => e
+            puts "Could not create directory '#{targetdir}'. Permission denied"
+            raise e
+          rescue Errno::ENOENT => e
+            puts "Could not copy file '#{file}' to '#{targetdir}'. File does not exist"
+            raise e
+          rescue => e
+            puts 'Could not prepare temporary build directory'
+            raise e
+          end
         end
       end
 
+      # Extract all the package files from the plugin's package data hash
+      def plugin_files
+        files = []
+        @plugin.packagedata.each do |name, data|
+          files += data[:files].reject{ |f| File.directory?(f) }
+        end
+        files
+      end
+
+      # Extract the package specific files from the file list and omits directories
+      def package_files(files)
+        package_files = []
+        files.each do |f|
+          if !File.directory?(f)
+            package_files << File.join(@libdir, File.expand_path(f).gsub(/#{@plugin.target_path}|\.\//, ''))
+          end
+        end
+        package_files
+      end
+
       def cleanup_tmpdirs
-        FileUtils.rm_r @tmpdir if File.directory? @tmpdir
+        begin
+          FileUtils.rm_r(@tmpdir) if File.directory?(@tmpdir)
+        rescue => e
+          puts "Could not remove temporary build directory - '#{@tmpdir}'"
+          raise e
+        end
       end
     end
   end