Methods
- analytics_log_dir
- backtraces
- connect
- for_pid
- global_queue_size
- groups
- helper_server_pid
- list
- new
- processes
- stats
- status
- web_server_config_files
- web_server_description
- xml
Classes and Modules
Class PhusionPassenger::AdminTools::ServerInstance::CorruptedDirectoryErrorClass 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
| [R] | generation_path | |
| [R] | path | |
| [R] | pid |
Public Class methods
[ show 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
[ show 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
[ show 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
[ show 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
[ show 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.
[ show 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
[ show 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
[ show 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
[ show 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
[ show 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
[ show 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
[ show source ]
# File lib/phusion_passenger/admin_tools/server_instance.rb, line 245
245: def status
246: return @client.status
247: end
[ show 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
[ show 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
[ show source ]
# File lib/phusion_passenger/admin_tools/server_instance.rb, line 253
253: def xml
254: return @client.xml
255: end