#!/usr/bin/env ruby # Phusion Passenger - http://www.modrails.com/ # Copyright (c) 2008, 2009 Phusion # # "Phusion Passenger" is a trademark of Hongli Lai & Ninh Bui. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN # THE SOFTWARE. PASSENGER_ROOT = File.expand_path(File.dirname(__FILE__) << "/..") $LOAD_PATH.unshift("#{PASSENGER_ROOT}/lib") $LOAD_PATH.unshift("#{PASSENGER_ROOT}/ext") # The Apache executable may be located in an 'sbin' folder. We add # the 'sbin' folders to $PATH just in case. On some systems # 'sbin' isn't in $PATH unless the user is logged in as root from # the start (i.e. not via 'su' or 'sudo'). ENV["PATH"] += ":/usr/sbin:/sbin:/usr/local/sbin" require 'optparse' require 'phusion_passenger/platform_info' require 'phusion_passenger/dependencies' require 'phusion_passenger/abstract_installer' include PlatformInfo class Installer < PhusionPassenger::AbstractInstaller include PhusionPassenger def dependencies result = [ Dependencies::GCC, Dependencies::Ruby_DevHeaders, Dependencies::Ruby_OpenSSL, Dependencies::RubyGems, Dependencies::Rake, Dependencies::Apache2, Dependencies::Apache2_DevHeaders ] if Dependencies.fastthread_required? result << Dependencies::FastThread end # Some broken servers don't have apr-config or apu-config installed. # Nevertheless, it is possible to compile Apache modules if Apache # was configured with --included-apr. So here we check whether # apr-config and apu-config are available. If they're not available, # then we only register them as required dependency if no Apache # module can be compiled without their presence. if (PlatformInfo.apr_config && PlatformInfo.apu_config) || PlatformInfo.apr_config_needed_for_building_apache_modules? result << Dependencies::APR_DevHeaders result << Dependencies::APU_DevHeaders end return result end def users_guide return "#{DOCDIR}/Users guide Apache.html" end def install! if PhusionPassenger.natively_packaged? check_dependencies || exit(1) show_apache2_config_snippets show_deployment_example exit end Dir.chdir(PASSENGER_ROOT) show_welcome_screen check_dependencies || exit(1) check_whether_apache_uses_compatible_mpm check_write_permission_to_passenger_root || exit(1) if install_apache2_module show_apache2_config_snippets show_deployment_example else show_possible_solutions_for_compilation_and_installation_problems exit(1) end end private def show_welcome_screen render_template 'apache2/welcome', :version => VERSION_STRING wait end def check_whether_apache_uses_compatible_mpm # 'httpd -V' output is in the form of: # # Server MPM: Prefork # <--- this line is not always available! # ... # Server compiled with.... # -D APACHE_MPM_DIR="server/mpm/prefork" output = `#{PlatformInfo.httpd} -V` output =~ /^Server MPM: +(.*)$/ if $1 mpm = $1.downcase else output =~ /APACHE_MPM_DIR="server\/mpm\/(.*)"/ if $1 mpm = $1.downcase else mpm = nil end end if mpm != "prefork" && mpm != "worker" new_screen render_template 'apache2/apache_must_be_compiled_with_compatible_mpm', :current_mpm => mpm wait end end def check_write_permission_to_passenger_root File.new("__test__.txt", "w").close return true rescue SystemCallError puts line if Process.uid == 0 render_template 'apache2/no_write_permission_to_passenger_root' else render_template 'apache2/run_installer_as_root' end return false ensure File.unlink("__test__.txt") rescue nil end def install_apache2_module puts line color_puts 'Compiling and installing Apache 2 module...' puts "cd #{PASSENGER_ROOT}" if ENV['TRACE'] puts "#{RUBY} -S #{PlatformInfo.rake} --trace clean apache2" return sh(RUBY, "-S", PlatformInfo.rake, "--trace", "clean", "apache2") else puts "#{RUBY} -S #{PlatformInfo.rake} clean apache2" return sh(RUBY, "-S", PlatformInfo.rake, "clean", "apache2") end end def show_apache2_config_snippets puts line if PhusionPassenger.natively_packaged? module_location = "#{PASSENGER_ROOT}/lib/phusion_passenger/mod_passenger.so" else module_location = "#{PASSENGER_ROOT}/ext/apache2/mod_passenger.so" end render_template 'apache2/config_snippets', :module_location => module_location, :passenger_root => PASSENGER_ROOT, :ruby => RUBY if PhusionPassenger.natively_packaged? wait(10) else wait end end def show_deployment_example puts line render_template 'apache2/deployment_example', :users_guide => users_guide, :phusion_website => PHUSION_WEBSITE, :passenger_website => PASSENGER_WEBSITE end def show_possible_solutions_for_compilation_and_installation_problems new_screen render_template 'apache2/possible_solutions_for_compilation_and_installation_problems', :users_guide => users_guide, :passenger_website => PASSENGER_WEBSITE end end options = {} parser = OptionParser.new do |opts| opts.banner = "Usage: passenger-install-apache2-module [options]" opts.separator "" opts.separator "Options:" opts.on("-a", "--auto", String, "Automatically build the Apache module,\n" << "#{' ' * 37}without interactively asking for user\n" << "#{' ' * 37}input.") do options[:auto] = true end opts.on("--apxs2-path PATH", String, "Path to 'apxs2' command.") do |value| ENV['APXS2'] = value end opts.on("--apr-config-path PATH", String, "Path to 'apr-config' command.") do |value| ENV['APR_CONFIG'] = value end end begin parser.parse! rescue OptionParser::ParseError => e puts e puts puts "Please see '--help' for valid options." exit 1 end Installer.new(options).start