apache-config-generator/lib/apache/config.rb

237 lines
6.8 KiB
Ruby
Raw Normal View History

2010-05-18 16:43:57 +00:00
require 'rubygems'
2010-10-26 13:53:48 +00:00
require 'bundler'
Bundler.require(:default)
2010-05-05 16:25:07 +00:00
require 'fileutils'
2010-10-26 14:24:45 +00:00
require 'rainbow'
2010-05-05 16:25:07 +00:00
2010-05-04 15:48:59 +00:00
Dir[File.join(File.dirname(__FILE__), '*.rb')].each { |f| require f }
2010-04-27 20:11:47 +00:00
module Apache
2010-05-10 19:57:34 +00:00
# The core class of Apache Config Generator.
#
# Configuration is built by calling either build or build_if:
#
# Ex: Build a config file regardless of current environment:
#
# Apache::Config.build('my-config.conf') do
# document_root '/my/document/root'
# ...
# end
#
# Ex: Build a config file only if you're in the development environment:
#
# Apache::Config.build_if('my-config.conf', :development) do
# document_root '/my/document/root'
# ...
# end
#
# By default, methods called within the block are NerdCapsed to match the Apache config directive format:
#
# document_root #=> DocumentRoot
# options #=> Options
# allow_override #=> AllowOverride
#
# Parameters passed into the methods are quoted if they're Strings or Integers, and not quoted if they're Symbols:
#
# document_root '/my/document/root' #=> DocumentRoot "/my/document/root"
# document_root '/my/document/root'.to_sym #=> DocumentRoot /my/document/root
# accept_path_info :off #=> AcceptPathInfo off
#
# Suffixing the method name with an exclamation point turns off quoting for all parameters:
#
# document_root! '/my/document/root' #=> DocumentRoot /my/document/root
#
# Block-level directives work the same as the top-level build method:
#
# directory '/my/site' do
# allow_from_all
# satisfy :any
# end
#
# Directives that require a regular expression take a Regexp:
#
# location_match %r{^/my/site} do
# set_env 'this_is_my_site', 'yes'
# end
2010-04-27 20:11:47 +00:00
class Config
class << self
2010-05-07 15:26:40 +00:00
attr_accessor :line_indent, :rotate_logs_path
2010-05-04 15:48:59 +00:00
2010-04-27 20:11:47 +00:00
include Apache::Master
2010-04-27 21:00:43 +00:00
include Apache::Permissions
2010-05-05 14:44:20 +00:00
include Apache::Directories
include Apache::Logging
2010-05-05 16:25:07 +00:00
include Apache::Performance
include Apache::Rewrites
2010-05-07 20:04:06 +00:00
include Apache::MPM
2010-05-10 21:43:34 +00:00
include Apache::SSL
2010-04-27 20:11:47 +00:00
2010-05-07 15:26:40 +00:00
# Build the provided configuration only if the current environment matches one of the conditions
2010-05-06 14:40:45 +00:00
def build_if(target, *conditions, &block)
build(target, &block) if conditions.include? APACHE_ENV
end
2010-05-07 15:26:40 +00:00
# Build the provided configuration
2010-05-18 16:43:57 +00:00
def build_and_return(&block)
2010-05-04 15:48:59 +00:00
reset!
2010-04-27 20:11:47 +00:00
self.instance_eval(&block)
2010-05-05 14:44:20 +00:00
@config
2010-05-04 15:48:59 +00:00
end
2010-04-27 20:11:47 +00:00
2010-05-18 16:43:57 +00:00
def build_and_return_if(*conditions, &block)
build_and_return(&block) if conditions.include? APACHE_ENV
end
def build(target, &block)
config = build_and_return(&block)
FileUtils.mkdir_p File.split(target).first
File.open(target, 'w') { |file| file.puts [ "# Generated by apache-config-generator #{Time.now.to_s}", config ].flatten * "\n" }
config
end
2010-05-04 15:48:59 +00:00
# Reset the current settings
def reset!
@config = []
@line_indent = 0
2010-04-27 20:11:47 +00:00
end
2010-04-28 20:19:03 +00:00
2010-05-04 15:48:59 +00:00
# Indent the string by the current @line_indent level
2010-05-05 16:25:07 +00:00
def indent(string_or_array)
case string_or_array
when Array
2010-05-18 16:43:57 +00:00
string_or_array.collect { |line| indent(line) }
2010-05-05 16:25:07 +00:00
else
" " * (@line_indent * 2) + string_or_array.to_s
end
2010-04-28 20:19:03 +00:00
end
2010-05-04 15:48:59 +00:00
# Add the string to the current config
2010-04-28 20:19:03 +00:00
def <<(string)
@config << indent(string)
end
2010-05-04 15:48:59 +00:00
2010-05-07 15:26:40 +00:00
# Append the array to the current config
2010-05-05 16:25:07 +00:00
def +(other)
@config += other
end
2010-05-07 15:26:40 +00:00
# Get the config
def to_a
@config
end
2010-05-04 15:48:59 +00:00
# Handle options that aren't specially handled
2010-05-10 19:57:34 +00:00
#
# Method names are NerdCapsed and paramters are quoted, unless the method ends with !
2010-05-04 15:48:59 +00:00
def method_missing(method, *args)
2010-05-18 16:43:57 +00:00
method_name = method.to_s
if method_name[-1..-1] == "!"
method = method_name[0..-2].to_sym
2010-05-04 15:48:59 +00:00
else
2010-05-18 17:08:17 +00:00
args.quoteize!
2010-05-04 15:48:59 +00:00
end
2010-05-18 16:43:57 +00:00
self << [ method.apachify, *args ].compact * ' '
2010-05-04 15:48:59 +00:00
end
# Handle creating block methods
2010-05-10 19:57:34 +00:00
#
# Methods created this way are:
# * virtual_host
# * location
# * files
2010-05-04 15:48:59 +00:00
def block_methods(*methods)
methods.each do |method|
self.class.class_eval <<-EOT
def #{method}(*name, &block)
2010-05-18 16:43:57 +00:00
blockify("#{method}".apachify, name, &block)
2010-05-04 15:48:59 +00:00
end
EOT
end
end
2010-05-10 19:57:34 +00:00
# If the given module is loaded, process the directives within.
#
# The provided module name is converted into Apache module name format:
# if_module(:php5) do #=> <IfModule mod_php5>
2010-05-05 14:44:20 +00:00
def if_module(mod, &block)
2010-05-18 16:43:57 +00:00
blockify('if_module'.apachify, "#{mod}_module".to_sym, &block)
2010-05-05 14:44:20 +00:00
end
2010-05-10 19:57:34 +00:00
# Create a directory block, checking to see if the source directory exists.
2010-05-05 14:44:20 +00:00
def directory(dir, &block)
directory? dir
2010-05-18 16:43:57 +00:00
blockify('directory'.apachify, dir, &block)
2010-05-05 14:44:20 +00:00
end
2010-05-10 19:57:34 +00:00
# Create a LocationMatch block with the provided Regexp:
# location_match %r{^/my/location/[a-z0-9]+\.html} do #=> <LocationMatch "^/my/location/[a-z0-9]+\.html">
2010-05-06 14:40:45 +00:00
def location_match(regexp, &block)
2010-05-18 16:43:57 +00:00
blockify('location_match'.apachify, regexp.source, &block)
2010-05-06 14:40:45 +00:00
end
2010-05-10 19:57:34 +00:00
# Create a FilesMatch block with the provied Regexp:
# files_match %r{\.html$} do #=> FilesMatch "\.html$">
def files_match(regexp, &block)
2010-05-18 16:43:57 +00:00
blockify('files_match'.apachify, regexp.source, &block)
2010-05-05 16:25:07 +00:00
end
2010-05-10 19:57:34 +00:00
# Only execute the provided block if APACHE_ENV matches one of the provided enviroment symbols:
# if_environment(:production) do
def if_environment(*env, &block)
self.instance_eval(&block) if env.include?(APACHE_ENV)
end
2010-05-07 15:26:40 +00:00
# Handle the blockification of a provided block
def blockify(tag_name, name, &block)
2010-05-18 17:20:49 +00:00
self + [ '', "<#{[ tag_name, name.blockify ].compact * ' '}>" ]
2010-05-04 15:48:59 +00:00
@line_indent += 1
self.instance_eval(&block)
@line_indent -= 1
2010-05-18 16:43:57 +00:00
self + [ "</#{tag_name}>", '' ]
end
def blank_line!
2010-05-06 14:40:45 +00:00
self << ""
2010-05-04 15:48:59 +00:00
end
2010-05-05 14:44:20 +00:00
2010-05-10 19:57:34 +00:00
# Build a string that invokes Apache's rotatelogs command
2010-05-05 16:25:07 +00:00
def rotatelogs(path, time)
2010-05-10 19:57:34 +00:00
begin
time = time.to_i
rescue
raise "Time should be an integer: #{path} #{time}"
end
2010-05-05 16:25:07 +00:00
"|#{@rotate_logs_path} #{path} #{time}"
end
2010-05-11 19:19:16 +00:00
def warn_msg(from, color = :red)
"[warn::#{from}]".foreground(color)
end
2010-05-05 14:44:20 +00:00
private
def writable?(path)
2010-05-11 19:19:16 +00:00
puts " #{warn_msg('writable?')} #{path.foreground(:yellow)} may not be writable!" if !File.directory? File.split(path).first
2010-05-05 14:44:20 +00:00
end
def directory?(path)
2010-05-11 19:19:16 +00:00
puts " #{warn_msg('directory?')} #{path.foreground(:yellow)} does not exist!" if !File.directory? path
2010-05-05 14:44:20 +00:00
end
2010-05-07 20:04:06 +00:00
def exist?(path)
2010-05-11 19:19:16 +00:00
puts " #{warn_msg('exist?')} #{path.foreground(:yellow)} does not exist!" if !File.exist?(path)
2010-05-07 20:04:06 +00:00
end
2010-04-27 20:11:47 +00:00
end
2010-05-10 19:57:34 +00:00
block_methods :virtual_host, :location, :files
2010-04-27 20:11:47 +00:00
end
end