class Bosh::Director::Config

We want to shift from class methods to instance methods here.

Attributes

base_dir[RW]
cloud_options[RW]
current_job[RW]
db[RW]
default_ssh_options[RW]
dns[RW]
dns_db[RW]
dns_domain_name[RW]
enable_post_deploy[RW]
enable_snapshots[RW]
enable_virtual_delete_vms[RW]
encryption[RW]
event_log[RW]
fix_stateful_nodes[RW]
flush_arp[RW]
generate_vm_passwords[RW]
keep_unreachable_vms[RW]
logger[RW]
max_tasks[RW]
max_threads[RW]
max_vm_create_tries[RW]
name[RW]
nats_uri[RW]
process_uuid[RW]
remove_dev_tools[RW]
result[RW]
revision[RW]
task_checkpoint_interval[RW]
trusted_certs[RW]
uuid[RW]
hash[R]

Public Class Methods

clear() click to toggle source
# File lib/bosh/director/config.rb, line 55
def clear
  self.instance_variables.each do |ivar|
    self.instance_variable_set(ivar, nil)
  end

  Thread.list.each do |thr|
    thr[:bosh] = nil
  end

  @blobstore = nil

  @compiled_package_cache = nil
  @compiled_package_blobstore = nil
  @compiled_package_cache_options = nil

  @nats = nil
  @nats_rpc = nil
  @cloud = nil
end
cloud() click to toggle source
# File lib/bosh/director/config.rb, line 243
def cloud
  @lock.synchronize do
    if @cloud.nil?
      @cloud = Bosh::Clouds::Provider.create(@cloud_options, @uuid)
    end
  end
  @cloud
end
cloud_options=(options) click to toggle source
# File lib/bosh/director/config.rb, line 266
def cloud_options=(options)
  @lock.synchronize do
    @cloud_options = options
    @cloud = nil
  end
end
cloud_type() click to toggle source
# File lib/bosh/director/config.rb, line 237
def cloud_type
  if @cloud_options
    @cloud_options['plugin'] || @cloud_options['provider']['name']
  end
end
compiled_package_cache_blobstore() click to toggle source
# File lib/bosh/director/config.rb, line 222
def compiled_package_cache_blobstore
  @lock.synchronize do
    if @compiled_package_cache_blobstore.nil? && use_compiled_package_cache?
      provider = @compiled_package_cache_options['provider']
      options = @compiled_package_cache_options['options']
      @compiled_package_cache_blobstore = Bosh::Blobstore::Client.safe_create(provider, options)
    end
  end
  @compiled_package_cache_blobstore
end
compiled_package_cache_provider() click to toggle source
# File lib/bosh/director/config.rb, line 233
def compiled_package_cache_provider
  use_compiled_package_cache? ? @compiled_package_cache_options['provider'] : nil
end
configure(config) click to toggle source
# File lib/bosh/director/config.rb, line 75
def configure(config)
  @max_vm_create_tries = Integer(config.fetch('max_vm_create_tries', 5))
  @flush_arp = config.fetch('flush_arp', false)

  @base_dir = config['dir']
  FileUtils.mkdir_p(@base_dir)

  # checkpoint task progress every 30 secs
  @task_checkpoint_interval = 30

  logging_config = config.fetch('logging', {})
  if logging_config.has_key?('file')
    @log_file_path = logging_config.fetch('file')
    shared_appender = Logging.appenders.file(
      'DirectorLogFile',
      filename: @log_file_path,
      layout: ThreadFormatter.layout
    )
  else
    shared_appender = Logging.appenders.io(
      'DirectorStdOut',
      STDOUT,
      layout: ThreadFormatter.layout
    )
  end

  @logger = Logging::Logger.new('Director')
  @logger.add_appenders(shared_appender)
  @logger.level = Logging.levelify(logging_config.fetch('level', 'debug'))

  # Event logger supposed to be overridden per task,
  # the default one does nothing
  @event_log = EventLog::Log.new

  # by default keep only last 100 tasks of each type in disk
  @max_tasks = config.fetch('max_tasks', 100).to_i

  @max_threads = config.fetch('max_threads', 32).to_i

  @revision = get_revision

  @logger.info("Starting BOSH Director: #{VERSION} (#{@revision})")

  @process_uuid = SecureRandom.uuid
  @nats_uri = config['mbus']

  @default_ssh_options = config['default_ssh_options']

  @cloud_options = config['cloud']
  @compiled_package_cache_options = config['compiled_package_cache']
  @name = config['name'] || ''

  @compiled_package_cache = nil

  @db_config = config['db']
  @db = configure_db(config['db'])
  @dns = config['dns']
  if @dns && @dns['db']
    @dns_db = configure_db(@dns['db'])
    if @dns_db
      # Load these constants early.
      # These constants are not 'require'd, they are 'autoload'ed
      # in models.rb. We're seeing that in 1.9.3 that sometimes
      # the constants loaded from one thread are not visible to other threads,
      # causing failures.
      # These constants cannot be required because they are Sequel model classes
      # that refer to database configuration that is only present when the (optional)
      # powerdns job is present and configured and points to a valid DB.
      # This is an attempt to make sure the constants are loaded
      # before forking off to other threads, hopefully eliminating the errors.
      Bosh::Director::Models::Dns::Record.class
      Bosh::Director::Models::Dns::Domain.class
    end
  end

  @dns_manager = DnsManagerProvider.create
  @uuid = override_uuid || Bosh::Director::Models::DirectorAttribute.find_or_create_uuid(@logger)
  @logger.info("Director UUID: #{@uuid}")

  @encryption = config['encryption']
  @fix_stateful_nodes = config.fetch('scan_and_fix', {})
    .fetch('auto_fix_stateful_nodes', false)
  @enable_snapshots = config.fetch('snapshots', {}).fetch('enabled', false)

  @trusted_certs = config['trusted_certs'] || ''
  @ignore_missing_gateway = config['ignore_missing_gateway']

  @keep_unreachable_vms = config.fetch('keep_unreachable_vms', false)
  @enable_post_deploy = config.fetch('enable_post_deploy', false)
  @generate_vm_passwords = config.fetch('generate_vm_passwords', false)
  @remove_dev_tools = config['remove_dev_tools']
  @record_events = config.fetch('record_events', false)

  @enable_virtual_delete_vms = config.fetch('enable_virtual_delete_vms', false)

  @director_ips = Socket.ip_address_list.reject { |addr| !addr.ip? || !addr.ipv4? || addr.ipv4_loopback? || addr.ipv6_loopback? }.map { |addr| addr.ip_address }


  @parse_config_values = config.fetch('parse_config_values', false)
  if @parse_config_values
    @config_server_url = config['config_server_url']
  end

  Bosh::Clouds::Config.configure(self)

  @lock = Monitor.new
end
configure_db(db_config) click to toggle source
# File lib/bosh/director/config.rb, line 199
def configure_db(db_config)
  connection_config = db_config.dup
  connection_options = connection_config.delete('connection_options') {{}}
  connection_config.delete_if { |_, v| v.to_s.empty? }
  connection_config = connection_config.merge(connection_options)

  Sequel.default_timezone = :utc
  db = Sequel.connect(connection_config)

  Bosh::Common.retryable(sleep: 0.5, tries: 20, on: [Exception]) do
    db.extension :connection_validator
    true
  end

  db.pool.connection_validation_timeout = -1
  if logger
    db.logger = logger
    db.sql_log_level = :debug
  end

  db
end
cpi_task_log() click to toggle source
# File lib/bosh/director/config.rb, line 256
def cpi_task_log
  Config.cloud_options.fetch('properties', {}).fetch('cpi_log')
end
director_pool() click to toggle source
# File lib/bosh/director/config.rb, line 252
def director_pool
  @director_pool ||= Socket.gethostname
end
encryption?() click to toggle source
# File lib/bosh/director/config.rb, line 285
def encryption?
  @encryption
end
generate_temp_dir() click to toggle source
# File lib/bosh/director/config.rb, line 293
def generate_temp_dir
  temp_dir = Dir.mktmpdir
  ENV["TMPDIR"] = temp_dir
  FileUtils.mkdir_p(temp_dir)
  at_exit do
    begin
      if $!
        status = $!.is_a?(::SystemExit) ? $!.status : 1
      else
        status = 0
      end
      FileUtils.rm_rf(temp_dir)
    ensure
      exit status
    end
  end
  temp_dir
end
get_revision() click to toggle source
# File lib/bosh/director/config.rb, line 191
def get_revision
  Dir.chdir(File.expand_path('../../../../../..', __FILE__))
  revision_command = '(cat REVISION 2> /dev/null || ' +
      'git show-ref --head --hash=8 2> /dev/null || ' +
      'echo 00000000) | head -n1'
  `#{revision_command}`.strip
end
job_cancelled?() click to toggle source
# File lib/bosh/director/config.rb, line 260
def job_cancelled?
  @current_job.task_checkpoint if @current_job
end
Also aliased as: task_checkpoint
load_file(path) click to toggle source
# File lib/bosh/director/config.rb, line 347
def load_file(path)
  Config.new(Psych.load_file(path))
end
load_hash(hash) click to toggle source
# File lib/bosh/director/config.rb, line 351
def load_hash(hash)
  Config.new(hash)
end
log_dir() click to toggle source
# File lib/bosh/director/config.rb, line 183
def log_dir
  File.dirname(@log_file_path) if @log_file_path
end
nats_rpc() click to toggle source
# File lib/bosh/director/config.rb, line 273
def nats_rpc
  # double-check locking to reduce synchronization
  if @nats_rpc.nil?
    @lock.synchronize do
      if @nats_rpc.nil?
        @nats_rpc = NatsRpc.new(@nats_uri)
      end
    end
  end
  @nats_rpc
end
new(hash) click to toggle source
# File lib/bosh/director/config.rb, line 441
def initialize(hash)
  @hash = hash
end
override_uuid() click to toggle source
# File lib/bosh/director/config.rb, line 312
def override_uuid
  new_uuid = nil
  state_file = File.join(base_dir, 'state.json')

  begin
    open(state_file, 'r+') do |file|

      # Lock before read to avoid director/worker race condition
      file.flock(File::LOCK_EX)
      state = JSON.parse(file.read) || {}

      # Empty state file to prevent blocked processes from attempting to set UUID
      file.truncate(0)

      if state['uuid']
        Bosh::Director::Models::DirectorAttribute.update_or_create_uuid(state['uuid'], @logger)
        @logger.info("Using director UUID #{state['uuid']} from #{state_file}")
        new_uuid = state['uuid']
      end

      # Unlock after storing UUID
      file.flock(File::LOCK_UN)
    end

    FileUtils.rm_f(state_file)

  rescue Errno::ENOENT
    # Catch race condition since another process (director/worker) might migrated the state
  end

  new_uuid
end
task_checkpoint()
Alias for: job_cancelled?
threaded() click to toggle source
# File lib/bosh/director/config.rb, line 289
def threaded
  Thread.current[:bosh] ||= {}
end
use_compiled_package_cache?() click to toggle source
# File lib/bosh/director/config.rb, line 187
def use_compiled_package_cache?
  !@compiled_package_cache_options.nil?
end

Public Instance Methods

backup_blobstore_config() click to toggle source
# File lib/bosh/director/config.rb, line 413
def backup_blobstore_config
  hash['backup_destination']
end
blobstore_config() click to toggle source
# File lib/bosh/director/config.rb, line 409
def blobstore_config
  hash.fetch('blobstore')
end
configure_evil_config_singleton!() click to toggle source
# File lib/bosh/director/config.rb, line 425
def configure_evil_config_singleton!
  Config.configure(hash)
end
db() click to toggle source
# File lib/bosh/director/config.rb, line 405
def db
  Config.configure_db(hash['db'])
end
director_pool() click to toggle source
# File lib/bosh/director/config.rb, line 421
def director_pool
  Config.director_pool
end
get_uuid_provider() click to toggle source
# File lib/bosh/director/config.rb, line 429
def get_uuid_provider
  Bosh::Director::Api::DirectorUUIDProvider.new(Config)
end
identity_provider() click to toggle source
# File lib/bosh/director/config.rb, line 368
def identity_provider
  @identity_provider ||= begin
    # no fetching w defaults?
    user_management = hash['user_management']
    user_management ||= {'provider' => 'local'}
    provider_name = user_management['provider']

    providers = {
      'uaa' => Bosh::Director::Api::UAAIdentityProvider,
      'local' => Bosh::Director::Api::LocalIdentityProvider,
    }
    provider_class = providers[provider_name]

    if provider_class.nil?
      raise ArgumentError,
        "Unknown user management provider '#{provider_name}', " +
          "available providers are: #{providers.keys.join(", ")}"
    end

    Config.logger.debug("Director configured with '#{provider_name}' user management provider")
    provider_class.new(user_management[provider_name] || {})
  end
end
log_access_events_to_syslog() click to toggle source
# File lib/bosh/director/config.rb, line 417
def log_access_events_to_syslog
  hash['log_access_events_to_syslog']
end
name() click to toggle source
# File lib/bosh/director/config.rb, line 356
def name
  hash['name']
end
port() click to toggle source
# File lib/bosh/director/config.rb, line 360
def port
  hash['port']
end
record_events() click to toggle source
# File lib/bosh/director/config.rb, line 433
def record_events
  hash.fetch('record_events', false)
end
scheduled_jobs() click to toggle source
# File lib/bosh/director/config.rb, line 364
def scheduled_jobs
  hash['scheduled_jobs'] || []
end
worker_logger() click to toggle source
# File lib/bosh/director/config.rb, line 392
def worker_logger
  logger = Logging::Logger.new('DirectorWorker')
  logging_config = hash.fetch('logging', {})
  worker_logging = hash.fetch('delayed_job', {}).fetch('logging', {})
  if worker_logging.has_key?('file')
    logger.add_appenders(Logging.appenders.file('DirectorWorkerFile', filename: worker_logging.fetch('file'), layout: ThreadFormatter.layout))
  else
    logger.add_appenders(Logging.appenders.stdout('DirectorWorkerIO', layout: ThreadFormatter.layout))
  end
  logger.level = Logging.levelify(logging_config.fetch('level', 'debug'))
  logger
end