module RailsPwnerer::Config

application-specific configuration functions

computes the number of frontends to be used in an application

important paths in the filesystem

keeps track of the available ports on the machine

implements the configuration repository

Public Class Methods

[](db_or_app_name, instance_name = nil) click to toggle source

override [] to make the global DB look like a Hash

    # File lib/rails_pwnerer/config/repository.rb
 99 def self.[](db_or_app_name, instance_name = nil)
100   if instance_name.nil?
101     db_name = db_or_app_name
102   else
103     db_name = app_db_name(db_or_app_name, instance_name)
104   end
105   get_db(db_name)
106 end
all_applications() click to toggle source

all instances of all applications installed on this box

   # File lib/rails_pwnerer/config/app.rb
15 def self.all_applications()
16   self.databases().select { |db| db.include? ?. }.map do |db|
17     lastdot = db.rindex ?.
18     [db[0...lastdot], db[(lastdot + 1)..-1]]
19   end
20 end
alloc_ports(nports = 1) click to toggle source

allocates a contiguous range of ports returns the starting port or nil

   # File lib/rails_pwnerer/config/ports.rb
12 def self.alloc_ports(nports = 1)
13   free_ports = self[:free_ports][:list]
14   free_ports.each_index do |i|
15     next if free_ports[i][1] - free_ports[i][0] < nports      
16     first_port = free_ports[i][0]
17     free_ports[i][0] += nports
18     free_ports.delete_at i if free_ports[i][0] == free_ports[i][1]
19     self[:free_ports][:list] = free_ports
20     self.flush_db :free_ports
21     return first_port
22   end
23 end
app_db_name(app_name, instance_name) click to toggle source

the name of the database storing an app’s configuration

  # File lib/rails_pwnerer/config/app.rb
5 def self.app_db_name(app_name, instance_name)
6   return "#{app_name}.#{instance_name}"
7 end
app_frontends(app_name, instance_name) click to toggle source

the number of frontends for an application

   # File lib/rails_pwnerer/config/frontends.rb
 5 def self.app_frontends(app_name, instance_name)
 6   # TODO: this is duplicated in cluster_config.rb -- pull up somewhere
 7   app_config = self[app_name, instance_name]
 8   return nil unless app_config and fixed_frontends = app_config[:frontends]
 9 
10   frontends_per_core = app_config[:frontends_per_core] || 0
11   detected_cores = app_config[:detected_cores] || 0
12   cores_frontends = frontends_per_core * detected_cores  
13   return (cores_frontends != 0) ? cores_frontends : fixed_frontends
14 end
app_instances(app_name) click to toggle source

the instances of an application installed on this box

   # File lib/rails_pwnerer/config/app.rb
10 def self.app_instances(app_name)
11   self.databases().select { |db| db.include? ?. }.map { |db| db[0...(db.rindex ?.)] }
12 end
create_db(db_name) click to toggle source

creates a new database

   # File lib/rails_pwnerer/config/repository.rb
40 def self.create_db(db_name)
41   db_name = db_name.to_s
42   
43   db_contents = install_db_hooks({}, db_name)
44   @@db_cache[db_name] = db_contents
45   @@db_dirty[db_name] = true
46   flush_db db_name
47   return db_contents
48 end
databases() click to toggle source
    # File lib/rails_pwnerer/config/repository.rb
108 def self.databases()
109   entries = Dir.entries RailsPwnerer::Config.path_to(:config)
110   databases = []
111   entries.each do |entry|      
112     next unless entry =~ /\.yml(2)?$/ 
113     databases << entry.gsub(/\.yml(2)?$/, '')
114   end
115   return databases
116 end
drop_db(db_name) click to toggle source

drops a database

   # File lib/rails_pwnerer/config/repository.rb
51 def self.drop_db(db_name)
52   @@db_cache[db_name] = nil
53   @@db_dirty[db_name] = true
54   flush_db db_name
55 end
flush_db(db_name) click to toggle source

flushes the contents of the given db from cache

   # File lib/rails_pwnerer/config/repository.rb
76 def self.flush_db(db_name)
77   db_name = db_name.to_s
78   return unless @@db_dirty[db_name]
79   db_path = RailsPwnerer::Config.path_to :config
80   if @@db_cache[db_name].nil?
81     atomic_erase db_path, db_name
82   else
83     host_config = get_db :host
84     atomic_write @@db_cache[db_name], db_path, db_name,
85                  :owner => (host_config && host_config[:pwnerer_user])
86   end
87   @@db_dirty[db_name] = false
88 end
flush_db_cache() click to toggle source

flushes the entire database cache (used when exiting)

   # File lib/rails_pwnerer/config/repository.rb
91 def self.flush_db_cache
92   @@db_dirty.each do |db_name, is_dirty|
93     next unless is_dirty
94     flush_db db_name      
95   end
96 end
free_ports(start, count = 1) click to toggle source

returns a continuous range of ports to the free list

   # File lib/rails_pwnerer/config/ports.rb
26 def self.free_ports(start, count = 1)
27   free_ports = self[:free_ports][:list]
28   free_ports << [start, start + count]
29   
30   # concatenate duplicates
31   free_ports.sort! { |a, b| a[0] <=> b[0]}
32   new_ports = [free_ports.first]
33   free_ports.each_index do |i|
34     if new_ports.last[1] >= free_ports[i][0]
35       new_ports.last[1] = [new_ports.last[1], free_ports[i][1]].max
36     else
37       new_ports << free_ports[i]
38     end
39   end
40   
41   # write the new database
42   self[:free_ports][:list] = new_ports
43   self.flush_db :free_ports
44 end
get_db(db_name) click to toggle source

retrieves the contents of a db (from cache if necessary)

   # File lib/rails_pwnerer/config/repository.rb
58 def self.get_db(db_name)
59   db_name = db_name.to_s
60   unless @@db_cache.has_key? db_name    
61     db_path = RailsPwnerer::Config.path_to :config
62     db_contents = atomic_read(db_path, db_name)
63   
64     if db_contents.nil?
65       @@db_cache[db_name] = nil
66     else
67       @@db_cache[db_name] = install_db_hooks db_contents, db_name 
68     end
69     @@db_dirty[db_name] = false
70   end
71   
72   return @@db_cache[db_name]
73 end
init_ports(free_ports = [[8000, 16000]]) click to toggle source
  # File lib/rails_pwnerer/config/ports.rb
4 def self.init_ports(free_ports = [[8000, 16000]])
5   self.create_db :free_ports
6   self[:free_ports][:list] = free_ports
7   self.flush_db :free_ports
8 end
install_db_hooks(db_contents, db_name) click to toggle source

installs the database hooks into a Hash

   # File lib/rails_pwnerer/config/repository.rb
19 def self.install_db_hooks(db_contents, db_name)
20   # hooks:
21   #  (1) automatically convert keys to strings
22   #  (2) flip the dirty flag on writes
23   class << db_contents      
24     def [](key)
25       super(key.to_s)
26     end
27     def []=(key, value)
28       super(key.to_s, value)
29       RailsPwnerer::Config.mark_db_dirty @db_name
30     end
31     def has_key?(key)
32       super(key.to_s)
33     end
34   end
35   db_contents.instance_variable_set :@db_name, db_name
36   return db_contents
37 end
mark_db_dirty(db_name) click to toggle source

called when a database is dirty

   # File lib/rails_pwnerer/config/repository.rb
14 def self.mark_db_dirty(db_name)
15   @@db_dirty[db_name] = true
16 end
path_to(what = :prod, app_name = nil) click to toggle source

the path to something important (e.g. :apps –> path to all production applications)

   # File lib/rails_pwnerer/config/paths.rb
 5 def self.path_to(what = :prod, app_name = nil)
 6   # need to hardcode path to config to avoid endless recursion
 7   if what == :config
 8     return '/prod/config/'
 9   end
10       
11   # first try the paths in the database
12   return self[:paths][what] if self[:paths] and self[:paths].has_key? what
13 
14   # then try the global paths
15   static_path = static_path_to what
16   return static_path unless static_path.nil?  
17 end
static_path_to(what) click to toggle source

hardcoded paths

   # File lib/rails_pwnerer/config/paths.rb
20 def self.static_path_to(what)
21   case what
22   when :config
23     # the directory containing the config files
24     '/prod/config'
25   when :prod
26     # the directory containing all the production data
27     '/prod'
28   when :apps
29     # the directory containing the production apps
30     '/prod/apps'
31   when :backups
32     '/prod/backups'
33   else
34     return
35   end
36 end