class Hubcap::Hub

Attributes

applications[R]
cap_sets[R]
filters[R]
groups[R]
servers[R]

Public Class Methods

new(filter_string) click to toggle source
Calls superclass method Hubcap::Group::new
# File lib/hubcap/hub.rb, line 8
def initialize(filter_string)
  @filters = filter_string.split(',').collect { |fltr| fltr.split('.') }
  @filters = [[]]  if @filters.empty?
  @cap_sets = {}
  @cap_set_clashes = []
  @applications = []
  @servers = []
  @groups = []
  super(nil, '∞')
end

Public Instance Methods

cap_set(hash) click to toggle source
# File lib/hubcap/hub.rb, line 20
def cap_set(hash)
  hash.each_pair { |k, v|
    if @cap_sets[k] && @cap_sets[k] != v
      @cap_set_clashes << { k => v }
    else
      @cap_sets[k] = v
    end
  }
end
capistrano_is_agnostic?(cap) click to toggle source

In agnostic mode, Capistrano recipes for specific applications are not loaded, and cap_set collisions are ignored.

# File lib/hubcap/hub.rb, line 72
def capistrano_is_agnostic?(cap)
  return cap.fetch(:hubcap_agnostic)  if cap.exists?(:hubcap_agnostic)
  ag = true
  options = cap.logger.instance_variable_get(:@options)
  if options && options[:actions] && options[:actions].any?
    tasks = options[:actions].clone
    while tasks.any?
      ag = false  unless cap.find_task(tasks.shift)
    end
  end
  cap.set(:hubcap_agnostic, ag)
  ag
end
configure_capistrano(cap) click to toggle source

Does a few things:

If we are in “agnostic mode” - executing a default task - that's all we do. If we are in “application mode” - executing at least one non-standard task - then we do a few more things:

  • Load all the recipes for the application into the Capistrano instance.

  • Set all the @cap_set variables in the Capistrano instance.

# File lib/hubcap/hub.rb, line 44
def configure_capistrano(cap)
  raise(Hubcap::CapistranoAlreadyConfigured)  if cap.exists?(:hubcap)
  cap.set(:hubcap, self)

  cap.instance_eval {
    require('hubcap/recipes/servers')
    require('hubcap/recipes/ssh')
    require('hubcap/recipes/puppet')
  }

  # Declare the servers.
  servers.each { |svr|
    # Raises an error if we cannot resolve the resulting address with DNS.
    resolv(svr.address)  unless svr.address.match(Hubcap::Group::IP_PATTERN)
    opts = {
      :name => svr.name,
      :full_name => svr.history.join('.')
    }.merge(svr.cap_attributes)
    cap.server(svr.address, *(svr.cap_roles + [opts]))
  }

  configure_application_mode(cap)  unless capistrano_is_agnostic?(cap)
end

Private Instance Methods

configure_application_mode(cap) click to toggle source
# File lib/hubcap/hub.rb, line 89
def configure_application_mode(cap)
  apps = servers.collect(&:application_parent).compact.uniq

  # A - there should be only one application for all the servers
  raise(
    Hubcap::ApplicationModeError::TooManyApplications,
    apps.collect(&:name).join(', ')
  )  if apps.size > 1

  # B - there should be no clash of cap sets
  raise(
    Hubcap::ApplicationModeError::DuplicateSets,
    @cap_set_clashes.inspect
  )  if @cap_set_clashes.any?

  # C - app-specific, but no applications
  raise(Hubcap::ApplicationModeError::NoApplications)  if !apps.any?

  # Otherwise, load all recipes...
  cap.set(:application, apps.first.name)
  apps.first.recipe_paths.each { |rp| cap.load(rp) }

  # ..and declare all cap sets.
  @cap_sets.each_pair { |key, val|
    val.kind_of?(Proc) ? cap.set(key, &val) : cap.set(key, val)
  }
end