# Phusion Passenger - https://www.phusionpassenger.com/ # Copyright (c) 2013 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. require 'phusion_passenger' require 'phusion_passenger/platform_info' require 'phusion_passenger/platform_info/ruby' require 'phusion_passenger/platform_info/apache' require 'phusion_passenger/utils/ansi_colors' module PhusionPassenger module PlatformInfo # Detects all possible Apache installations on the system, and presents the # autodetection information to the user in a friendly way. It turns out too # many people have multiple Apache installations on their system, but they # don't know about that, or they don't know how to compile against the # correct Apache installation. This tool helps them. class ApacheDetector class Result # These are required and are never nil. attr_accessor :apxs2, :httpd, :ctl, :version, :config_file # These are optional and may be nil. attr_accessor :a2enmod, :a2dismod # This may be nil. It depends on how well we can infer information from the config file. attr_accessor :error_log def initialize(detector) @detector = detector end def report log " * Found Apache #{version}!" log " Information:" log " apxs2 : #{apxs2}" log " Main executable: #{httpd}" log " Control command: #{ctl}" log " Config file : #{config_file}" log " Error log file : #{error_log}" log "" log " To install Phusion Passenger against this specific Apache version:" log " #{PlatformInfo.ruby_command} #{PhusionPassenger.bin_dir}/passenger-install-apache2-module --apxs2-path='#{apxs2}'" log "" log " To start, stop or restart this specific Apache version:" log " #{ctl} start" log " #{ctl} stop" log " #{ctl} restart" log "" log " To troubleshoot, please read the logs in this file:" log " #{error_log}" log "" end private def log(message) @detector.send(:log, message) end end def initialize(output) @output = output @results = [] PlatformInfo.verbose = true PlatformInfo.log_implementation = lambda do |message| if message =~ /: found$/ log(" * #{message}") else log(" * #{message}") end end end def finish PlatformInfo.verbose = false PlatformInfo.log_implementation = nil end def detect_all log "Looking for possible Apache installations..." apxses = PlatformInfo.find_all_commands("apxs2") + PlatformInfo.find_all_commands("apxs") apxses = remove_symlink_duplications(apxses) log "" apxses.each do |apxs2| detect_one(apxs2) end end def detect_one(apxs2) log "Analyzing #{apxs2}..." add_result do |result| result.apxs2 = apxs2 log "Detecting main Apache executable..." result.httpd = PlatformInfo.httpd(:apxs2 => apxs2) if result.httpd if result.version = PlatformInfo.httpd_version(:httpd => result.httpd) log "Version detected: #{result.version}" else log "Cannot detect version!" result.httpd = nil end end if result.httpd log "Detecting control command..." result.ctl = PlatformInfo.apache2ctl(:apxs2 => apxs2) result.httpd = nil if !result.ctl end if result.httpd result.config_file = PlatformInfo.httpd_default_config_file(:httpd => result.httpd) if result.config_file log "Default config file location detected: #{result.config_file}" else log "Cannot detect default config file location!" result.httpd = nil end end if result.httpd result.error_log = PlatformInfo.httpd_actual_error_log(:httpd => result.httpd) if result.error_log log "Error log file detected: #{result.error_log}" else log "Cannot detect error log file!" result.httpd = nil end end if result.httpd if PlatformInfo.httpd_supports_a2enmod?(:httpd => result.httpd) log "This Apache installation does not support a2enmod." else log "Detecting a2enmod and a2dismod..." result.a2enmod = PlatformInfo.a2enmod(:apxs2 => apxs2) result.a2dismod = PlatformInfo.a2dismod(:apxs2 => apxs2) end end if result.httpd log "Found a usable Apache installation using #{apxs2}." true else log "Cannot find a usable Apache installation using #{apxs2}." false end end log "" end def report log "Final autodetection results" @results.each do |result| result.report end if @results.empty? log "Sorry, this program cannot find an Apache installation." log "" log "To install Apache, please run the following. It will tell you how to install Apache." log "" log " #{PhusionPassenger.bin_dir}/passenger-install-apache2-module" log "" log "If you are sure that you have Apache installed, please read the documentation:" log " * #{PhusionPassenger.doc_dir}/Users guide Apache.html, section" log " section 'Installation' -> 'Customizing the compilation process' ->" log " 'Forcing location of command line tools and dependencies'" log " * Or visit the online version:" log " http://www.modrails.com/documentation/Users%20guide%20Apache.html#_forcing_location_of_command_line_tools_and_dependencies" elsif @results.size > 1 log "WARNING: You have multiple Apache installations on your system!" log "You are strongly recommended to read this section of the documentation:" log " * #{PhusionPassenger.doc_dir}/Users guide Apache.html, section" log " section 'Installation' -> 'Customizing the compilation process' ->" log " 'Forcing location of command line tools and dependencies'" log " * Or visit the online version:" log " http://www.modrails.com/documentation/Users%20guide%20Apache.html#_forcing_location_of_command_line_tools_and_dependencies" end end private def log(message) @output.puts(Utils::AnsiColors.ansi_colorize(message)) end # On Ubuntu, /usr/bin/apxs2 is a symlink to /usr/bin/apxs. We're only # supposed to detect one Apache in that case so we need to resolve symlinks. def remove_symlink_duplications(filenames) result = [] symlink_files = [] filenames.each do |filename| if File.symlink?(filename) symlink_files << filename else result << filename end end symlink_files.each do |filename| full_filename = File.expand_path(File.readlink(filename), File.dirname(filename)) if result.include?(full_filename) log "#{filename} is a symlink to #{full_filename}. Ignoring it." else result << full_filename end end return result end def add_result result = Result.new(self) @results << result if yield(result) end end end end # module Phusion Passenger