/lib/passenger_pane/application.rb
Ruby | 219 lines | 174 code | 40 blank | 5 comment | 13 complexity | 4db2564c41c8e596af18d605cff0b5e0 MD5 | raw file
1require 'fileutils' 2 3module PassengerPane 4 class Application 5 RAILS_APP_REGEXP = /::Initializer\.run|Application\.initialize!/ 6 ATTRIBUTES = [:config_filename, :host, :aliases, :path, :framework, :environment, :vhost_address, :user_defined_data] 7 8 def self.glob(configuration) 9 File.join( 10 configuration.apache_directory, 11 configuration.passenger_vhosts, 12 "*.#{configuration.passenger_vhosts_ext}" 13 ) 14 end 15 16 def self.all(configuration) 17 Dir.glob(glob(configuration)).map do |config_filename| 18 new(configuration, :config_filename => config_filename) 19 end 20 end 21 22 def self.find(configuration, conditions={}) 23 if conditions[:host] 24 all(configuration).detect do |app| 25 app.host == conditions[:host] 26 end 27 end 28 end 29 30 attr_accessor(*ATTRIBUTES) 31 32 def initialize(configuration, options={}) 33 @configuration = configuration 34 set(options) 35 if options[:config_filename] 36 @new = false 37 _parse 38 elsif options[:path] 39 @new = true 40 _derive 41 else 42 raise ArgumentError, "Please specify either a :config_filename or :path" 43 end 44 @before_changes = to_hash 45 end 46 47 def set(options) 48 options.each do |key, value| 49 setter = trust("#{key}=") 50 send(setter, trust(value)) if respond_to?(setter) 51 end 52 end 53 54 def new? 55 @new 56 end 57 58 # -- Virtual Host reading and writing 59 60 def contents 61 @contents ||= File.read(trust(@config_filename)) 62 end 63 64 attr_writer :contents 65 66 def _parse 67 data = contents.dup 68 69 data.gsub!(/\n\s*ServerName\s+(.+)/, '') 70 @host = $1 71 72 data.gsub!(/\n\s*ServerAlias\s+(.+)/, '') 73 @aliases = $1 || '' 74 75 data.gsub!(/\n\s*DocumentRoot\s+"(.+)"/, '') 76 path = $1 77 if path.end_with?('public') 78 @path = File.dirname(path) 79 else 80 @path = path 81 end 82 83 data.gsub!(/\n\s*(Rails|Rack)Env\s+(\w+)/, '') 84 @framework = $1 ? $1.downcase : nil 85 @environment = $2 86 87 data.gsub!(/<VirtualHost\s(.+?)>/, '') 88 @vhost_address = $1 89 90 data.gsub!(/\s*<\/VirtualHost>\n*/, '').gsub!(/^\n*/, '') 91 @user_defined_data = data.strip 92 end 93 94 def _document_root 95 File.join(@path, 'public') 96 end 97 98 def _directory_defaults 99 %{ 100 <Directory "#{_document_root}"> 101 Order allow,deny 102 Allow from all 103 </Directory> 104 }.strip 105 end 106 107 def _config_filename 108 File.join( 109 @configuration.apache_directory, 110 @configuration.passenger_vhosts, 111 "#{@host}.#{@configuration.passenger_vhosts_ext}" 112 ) 113 end 114 115 def _framework 116 environment_file = File.join(@path, 'config', 'environment.rb') 117 if File.exist?(environment_file) and File.read(environment_file) =~ RAILS_APP_REGEXP 118 'rails' 119 else 120 'rack' 121 end 122 end 123 124 def _derive 125 @host ||= "#{File.basename(path).downcase.gsub('_','-')}.local" 126 @aliases ||= '' 127 @environment ||= 'development' 128 @vhost_address ||= '*:80' 129 @user_defined_data ||= _directory_defaults 130 @config_filename ||= _config_filename 131 @framework ||= _framework 132 end 133 134 def rails?; @framework == 'rails' end 135 def rack?; @framework == 'rack' end 136 137 def vhost_snippet 138 lines = [] 139 lines << "<VirtualHost #{vhost_address}>" 140 lines << " ServerName #{host}" 141 lines << " ServerAlias #{aliases}" unless aliases == '' 142 lines << " DocumentRoot \"#{_document_root}\"" 143 if @framework 144 lines << " #{rails? ? 'RailsEnv' : 'RackEnv'} #{environment}" 145 end 146 lines << " #{user_defined_data}" unless user_defined_data.strip == '' 147 lines << "</VirtualHost>" 148 lines.join("\n") 149 end 150 151 def write 152 FileUtils.mkdir_p(File.dirname(@config_filename)) 153 File.open(@config_filename, 'w') do |file| 154 file.write(vhost_snippet) 155 end; true 156 end 157 158 # -- Dirty checking 159 160 def to_hash 161 hash = { 'hosts' => [host, *aliases.split] } 162 ATTRIBUTES.each do |key| 163 hash[key.to_s] = instance_variable_get("@#{key}") 164 end; hash 165 end 166 167 def changed? 168 @before_changes != to_hash 169 end 170 171 def added_hosts 172 to_hash['hosts'] - @before_changes['hosts'] 173 end 174 175 def removed_hosts 176 @before_changes['hosts'] - to_hash['hosts'] 177 end 178 179 # -- Directory services 180 181 def register 182 PassengerPane::DirectoryServices.register(to_hash['hosts']) 183 end 184 185 def unregister 186 PassengerPane::DirectoryServices.unregister(to_hash['hosts']) 187 end 188 189 def sync_host_registration 190 if new? 191 register 192 else 193 PassengerPane::DirectoryServices.register(added_hosts) and 194 PassengerPane::DirectoryServices.unregister(removed_hosts) 195 end 196 end 197 198 # -- Persisting 199 200 def save 201 write and sync_host_registration 202 end 203 204 def delete 205 FileUtils.rm_rf(config_filename) 206 unregister 207 true 208 end 209 210 # -- Operational 211 212 def restart 213 if File.exist?(@path) 214 FileUtils.mkdir_p(File.join(File.join(@path, 'tmp'))) 215 FileUtils.touch(File.join(@path, 'tmp', 'restart.txt')) 216 end 217 end 218 end 219end