Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Real-time collaboration for Jupyter Notebooks, Linux Terminals, LaTeX, VS Code, R IDE, and more,
all in one place.
Path: blob/master/lib/rex/service_manager.rb
Views: 11765
# -*- coding: binary -*-1require 'singleton'2require 'rex'34module Rex56###7#8# This class manages service allocation and interaction. This class can be9# used to start HTTP servers and manage them and all that stuff. Yup.10#11###12class ServiceManager < Hash1314#15# This class is a singleton.16#17include Singleton1819#20# Calls the instance method to start a service.21#22def self.start(klass, *args, **kwargs)23self.instance.start(klass, *args, **kwargs)24end2526#27# Calls the instance method to stop a service.28#29def self.stop(klass, *args, **kwargs)30self.instance.stop(klass, *args, **kwargs)31end3233#34# Stop a service using the alias that's associated with it.35#36def self.stop_by_alias(als)37self.instance.stop_by_alias(als)38end3940#41# Stop the supplied service instance.42#43def self.stop_service(service)44self.instance.stop_service(service)45end4647#48# Starts a service and assigns it a unique name in the service hash.49#50def start(klass, *args, **kwargs)51# Get the hardcore alias.52hals = "#{klass}" + klass.hardcore_alias(*args, **kwargs)5354# Has a service already been constructed for this guy? If so, increment55# its reference count like it aint no thang.56if (inst = self[hals])57inst.ref58return inst59end6061inst = klass.new(*args, **kwargs)62als = inst.alias6364# Find an alias that isn't taken.65if (self[als])66cnt = 167cnt += 1 while (self[als + " #{cnt}"])68als = inst.alias + " #{cnt}"69end7071# Extend the instance as a service.72inst.extend(Rex::Service)7374# Re-aliases the instance.75inst.alias = als7677# Fire up the engines. If an error occurs an exception will be78# raised.79inst.start8081# Alias associate and initialize reference counting82self[als] = self[hals] = inst.refinit8384# Pass the caller a reference85inst.ref8687inst88end8990#91# Stop a service using a given klass and arguments. These should mirror92# what was originally passed to start exactly. If the reference count of93# the service drops to zero the service will be destroyed.94#95def stop(klass, *args, **kwargs)96stop_service(hals[hardcore_alias(klass, *args, **kwargs)])97end9899#100# Stops a service using the provided alias.101#102def stop_by_alias(als)103stop_service(self[als])104end105106#107# Stops a service instance.108#109def stop_service(inst)110# Stop the service and be done wif it, but only if the number of111# references has dropped to zero112if (inst)113# Since the instance may have multiple aliases, scan through114# all the pairs for matching stuff.115self.each_pair { |cals, cinst|116self.delete(cals) if (inst == cinst)117}118119# Lose the list-held reference to the instance120inst.deref121122return true123end124125# Return false if the service isn't there126return false127end128129#130# Overrides the builtin 'each' operator to avoid the following exception on Ruby 1.9.2+131# "can't add a new key into hash during iteration"132#133def each(&block)134list = []135self.keys.sort.each do |sidx|136list << [sidx, self[sidx]]137end138list.each(&block)139end140141protected142143#144# Returns the alias for a given service instance.145#146def hardcore_alias(klass, *args)147"__#{klass.name}#{args}"148end149150end151152end153154155