Class PhusionPassenger::AdminTools::ServerInstance
In: lib/phusion_passenger/admin_tools/server_instance.rb
Parent: Object

Methods

Classes and Modules

Class PhusionPassenger::AdminTools::ServerInstance::CorruptedDirectoryError
Class PhusionPassenger::AdminTools::ServerInstance::GenerationsAbsentError
Class PhusionPassenger::AdminTools::ServerInstance::Group
Class PhusionPassenger::AdminTools::ServerInstance::Process
Class PhusionPassenger::AdminTools::ServerInstance::RoleDeniedError
Class PhusionPassenger::AdminTools::ServerInstance::StaleDirectoryError
Class PhusionPassenger::AdminTools::ServerInstance::Stats
Class PhusionPassenger::AdminTools::ServerInstance::UnsupportedGenerationStructureVersionError

Constants

DIR_STRUCTURE_MAJOR_VERSION = 1   If you change the structure version then don‘t forget to change ext/common/ServerInstanceDir.h too.
DIR_STRUCTURE_MINOR_VERSION = 0
GENERATION_STRUCTURE_MAJOR_VERSION = 1
GENERATION_STRUCTURE_MINOR_VERSION = 0
STALE_TIME_THRESHOLD = 60

Attributes

generation_path  [R] 
path  [R] 
pid  [R] 

Public Class methods

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 136
136:         def self.for_pid(pid, options = {})
137:                 return list(options).find { |c| c.pid == pid }
138:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 109
109:         def self.list(options = {})
110:                 options = {
111:                         :clean_stale_or_corrupted => true
112:                 }.merge(options)
113:                 instances = []
114:                 
115:                 Dir["#{AdminTools.tmpdir}/passenger.*"].each do |dir|
116:                         next if File.basename(dir) !~ /passenger\.#{DIR_STRUCTURE_MAJOR_VERSION}\.(\d+)\.(\d+)\Z/
117:                         minor = $1
118:                         next if minor.to_i > DIR_STRUCTURE_MINOR_VERSION
119:                         
120:                         begin
121:                                 instances << ServerInstance.new(dir)
122:                         rescue StaleDirectoryError, CorruptedDirectoryError
123:                                 if options[:clean_stale_or_corrupted] &&
124:                                    File.stat(dir).mtime < current_time - STALE_TIME_THRESHOLD
125:                                         log_cleaning_action(dir)
126:                                         FileUtils.chmod_R(0700, dir) rescue nil
127:                                         FileUtils.rm_rf(dir)
128:                                 end
129:                         rescue UnsupportedGenerationStructureVersionError, GenerationsAbsentError
130:                                 # Do nothing.
131:                         end
132:                 end
133:                 return instances
134:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 140
140:         def initialize(path)
141:                 raise ArgumentError, "Path may not be nil." if path.nil?
142:                 @path = path
143:                 
144:                 if File.exist?("#{path}/control_process.pid")
145:                         data = File.read("#{path}/control_process.pid").strip
146:                         @pid = data.to_i
147:                 else
148:                         path =~ /passenger\.\d+\.\d+\.(\d+)\Z/
149:                         @pid = $1.to_i
150:                 end
151:                 
152:                 generations = Dir["#{path}/generation-*"]
153:                 if generations.empty?
154:                         raise GenerationsAbsentError, "There are no generation subdirectories in this instance directory."
155:                 end
156:                 highest_generation_number = 0
157:                 generations.each do |generation|
158:                         File.basename(generation) =~ /(\d+)/
159:                         generation_number = $1.to_i
160:                         if generation_number > highest_generation_number
161:                                 highest_generation_number = generation_number
162:                         end
163:                 end
164:                 @generation_path = "#{path}/generation-#{highest_generation_number}"
165:                 
166:                 if !File.exist?("#{@generation_path}/structure_version.txt")
167:                         raise CorruptedDirectoryError, "The generation directory doesn't contain a structure version specification file."
168:                 end
169:                 version_data = File.read("#{@generation_path}/structure_version.txt").strip
170:                 major, minor = version_data.split(".", 2)
171:                 if major.nil? || minor.nil? || major !~ /\A\d+\Z/ || minor !~ /\A\d+\Z/
172:                         raise CorruptedDirectoryError, "The generation directory doesn't contain a valid structure version specification file."
173:                 end
174:                 major = major.to_i
175:                 minor = minor.to_i
176:                 if major != GENERATION_STRUCTURE_MAJOR_VERSION || minor > GENERATION_STRUCTURE_MINOR_VERSION
177:                         raise UnsupportedGenerationStructureVersionError, "Unsupported generation directory structure version."
178:                 end
179:                 
180:                 if @pid == 0
181:                         raise CorruptedDirectoryError, "Instance directory contains corrupted control_process.pid file."
182:                 elsif !AdminTools.process_is_alive?(@pid)
183:                         raise StaleDirectoryError, "There is no instance with PID #{@pid}."
184:                 end
185:         end

Public Instance methods

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 239
239:         def analytics_log_dir
240:                 return File.read("#{@generation_path}/analytics_log_dir.txt")
241:         rescue Errno::ENOENT
242:                 return nil
243:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 249
249:         def backtraces
250:                 return @client.backtraces
251:         end

Raises:

  • ArgumentError: Unsupported role
  • RoleDeniedError: The user that the current process is as is not authorized to utilize the given role.
  • EOFError: The server unexpectedly closed the connection during authentication.
  • SecurityError: The server denied our authentication credentials.

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 192
192:         def connect(role_or_username, password = nil)
193:                 if role_or_username.is_a?(Symbol)
194:                         case role_or_username
195:                         when :passenger_status
196:                                 username = "_passenger-status"
197:                                 begin
198:                                         filename = "#{@generation_path}/passenger-status-password.txt"
199:                                         password = File.open(filename, "rb") do |f|
200:                                                 f.read
201:                                         end
202:                                 rescue Errno::EACCES
203:                                         raise RoleDeniedError
204:                                 end
205:                         else
206:                                 raise ArgumentError, "Unsupported role #{role_or_username}"
207:                         end
208:                 else
209:                         username = role_or_username
210:                 end
211:                 
212:                 @client = MessageClient.new(username, password, "unix:#{@generation_path}/socket")
213:                 begin
214:                         yield self
215:                 ensure
216:                         @client.close
217:                 end
218:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 267
267:         def global_queue_size
268:                 return stats.global_queue_size
269:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 271
271:         def groups
272:                 doc = REXML::Document.new(xml)
273:                 
274:                 groups = []
275:                 doc.elements.each("info/groups/group") do |group_xml|
276:                         group = Group.new(group_xml.elements["app_root"].text,
277:                                 group_xml.elements["name"].text,
278:                                 group_xml.elements["environment"].text)
279:                         group_xml.elements.each("processes/process") do |process_xml|
280:                                 process = Process.new(group)
281:                                 process_xml.elements.each do |element|
282:                                         if element.name == "server_sockets"
283:                                                 element.elements.each("server_socket") do |server_socket|
284:                                                         name = server_socket.elements["name"].text.to_sym
285:                                                         address = server_socket.elements["address"].text
286:                                                         address_type = server_socket.elements["type"].text
287:                                                         process.server_sockets[name] = OpenStruct.new(
288:                                                                 :address => address,
289:                                                                 :address_type => address_type
290:                                                         )
291:                                                 end
292:                                         else
293:                                                 if process.respond_to?("#{element.name}=")
294:                                                         if Process::INT_PROPERTIES.include?(element.name.to_sym)
295:                                                                 value = element.text.to_i
296:                                                         elsif Process::BOOL_PROPERTIES.include?(element.name.to_sym)
297:                                                                 value = element.text == "true"
298:                                                         else
299:                                                                 value = element.text
300:                                                         end
301:                                                         process.send("#{element.name}=", value)
302:                                                 end
303:                                         end
304:                                 end
305:                                 group.processes << process
306:                         end
307:                         groups << group
308:                 end
309:                 return groups
310:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 235
235:         def helper_server_pid
236:                 return File.read("#{@generation_path}/helper_server.pid").strip.to_i
237:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 312
312:         def processes
313:                 return groups.map do |group|
314:                         group.processes
315:                 end.flatten
316:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 257
257:         def stats
258:                 doc = REXML::Document.new(xml)
259:                 stats = Stats.new
260:                 stats.max = doc.elements["info/max"].text.to_i
261:                 stats.count = doc.elements["info/count"].text.to_i
262:                 stats.active = doc.elements["info/active"].text.to_i
263:                 stats.global_queue_size = doc.elements["info/global_queue_size"].text.to_i
264:                 return stats
265:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 245
245:         def status
246:                 return @client.status
247:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 224
224:         def web_server_config_files
225:                 config_files = File.read("#{@generation_path}/config_files.txt").split("\n")
226:                 config_files.map! do |filename|
227:                         filename.strip
228:                 end
229:                 config_files.reject do |filename|
230:                         filename.empty?
231:                 end
232:                 return config_files
233:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 220
220:         def web_server_description
221:                 return File.read("#{@generation_path}/web_server.txt")
222:         end

[Source]

     # File lib/phusion_passenger/admin_tools/server_instance.rb, line 253
253:         def xml
254:                 return @client.xml
255:         end

[Validate]