module Dopv

This is the DOPv disk state store

Constants

DEFAULT_MAX_IN_FLIGHT
VERSION

Public Class Methods

add(plan_file) click to toggle source
# File lib/dopv.rb, line 22
def self.add(plan_file)
  raise StandardError, 'Plan not valid; did not add' unless valid?(plan_file)
  plan_name = plan_store.add(plan_file)
  Dopv.update_state(plan_name)
  plan_name
end
deploy(plan_name, options = {}) click to toggle source
# File lib/dopv.rb, line 51
def self.deploy(plan_name, options = {})
  run(:deploy, plan_name, options)
end
export_state(plan_name) click to toggle source
# File lib/dopv.rb, line 63
def self.export_state(plan_name)
  ensure_plan_exists(plan_name)
  state_store = Dopv::StateStore.new(plan_name, plan_store)
  state_store.export
end
export_state_file(plan_name, state_file) click to toggle source
# File lib/dopv.rb, line 69
def self.export_state_file(plan_name, state_file)
  ensure_plan_exists(plan_name)
  File.open(state_file, 'w+') do |diskdb|
    diskdb << YAML.dump(Dopv.export_state(plan_name))
  end
end
import_state(plan_name, data_volumes_db) click to toggle source
# File lib/dopv.rb, line 76
def self.import_state(plan_name, data_volumes_db)
  ensure_plan_exists(plan_name)
  plan_store.run_lock(plan_name) do
    state_store = Dopv::StateStore.new(plan_name, plan_store)
    state_store.import(data_volumes_db)
  end
end
import_state_file(plan_name, state_file) click to toggle source
# File lib/dopv.rb, line 84
def self.import_state_file(plan_name, state_file)
  ensure_plan_exists(plan_name)
  Dopv.import_state(plan_name, YAML.load_file(state_file))
end
list() click to toggle source
# File lib/dopv.rb, line 47
def self.list
  plan_store.list
end
log() click to toggle source
# File lib/dopv/log.rb, line 5
def self.log
  @log ||= DopCommon.log
end
logger=(logger) click to toggle source
# File lib/dopv/log.rb, line 9
def self.logger=(logger)
  @log = logger
  DopCommon.logger = logger
end
refresh(plan_name, options = {}) click to toggle source
# File lib/dopv.rb, line 59
def self.refresh(plan_name, options = {})
  run(:refresh, plan_name, options)
end
remove(plan_name, remove_dopi_state = true, remove_dopv_state = false) click to toggle source
# File lib/dopv.rb, line 43
def self.remove(plan_name, remove_dopi_state = true, remove_dopv_state = false)
  plan_store.remove(plan_name, remove_dopi_state, remove_dopv_state)
end
undeploy(plan_name, options = {}) click to toggle source
# File lib/dopv.rb, line 55
def self.undeploy(plan_name, options = {})
  run(:undeploy, plan_name, options)
end
update_plan(plan_file, options = {}) click to toggle source
# File lib/dopv.rb, line 29
def self.update_plan(plan_file, options = {})
  raise StandardError, 'Plan not valid; did not add' unless valid?(plan_file)
  plan_name = plan_store.update(plan_file)
  update_state(plan_name, options)
  plan_name
end
update_state(plan_name, options = {}) click to toggle source
# File lib/dopv.rb, line 36
def self.update_state(plan_name, options = {})
  plan_store.run_lock(plan_name) do
    state_store = Dopv::StateStore.new(plan_name, plan_store)
    state_store.update(options)
  end
end
valid?(plan_file) click to toggle source
# File lib/dopv.rb, line 16
def self.valid?(plan_file)
  hash, _ = plan_store.read_plan_file(plan_file)
  plan = DopCommon::Plan.new(hash)
  plan.valid?
end

Private Class Methods

ensure_plan_exists(plan_name) click to toggle source
# File lib/dopv.rb, line 95
def self.ensure_plan_exists(plan_name)
  unless plan_store.list.include?(plan_name)
    raise StandardError, "The plan #{plan_name} does not exist in the plan store"
  end
end
get_plan(plan_name) click to toggle source
# File lib/dopv.rb, line 101
def self.get_plan(plan_name)
  raise StandardError, 'Please update the plan state, there are pending updates' if pending_updates?(plan_name)
  plan_parser = plan_store.get_plan(plan_name)
  Dopv::Plan.new(plan_parser)
end
in_parallel(plan, nodes) { |node| ... } click to toggle source
# File lib/dopv.rb, line 144
def self.in_parallel(plan, nodes)
  errors = false
  infras = nodes.group_by {|node| node.infrastructure}
  Parallel.each(infras.keys, :in_threads => infras.keys.length) do |infra|
    Dopv.log.debug("Spawning control thread for infra #{infra.name}")
    max_in_flight = infra.max_in_flight || plan.max_in_flight || DEFAULT_MAX_IN_FLIGHT
    Dopv.log.debug("Threads for infra #{infra.name}: #{max_in_flight}")
    Parallel.each(infras[infra], :in_threads => max_in_flight) do |node|
      Dopv.log.debug("Spawning thread for node #{node.name}.")
      begin
        Dopv.log.debug("Yielding node #{node.name}.")
        yield(node)
      rescue => e
        errors = true
        Dopv.log.error("There was an error while processing node #{node.name}: #{e}")
        raise Parallel::Break
      end
    end
  end
  raise "Errors detected during plan run" if errors
end
merge_default_options(options) click to toggle source
# File lib/dopv.rb, line 136
def self.merge_default_options(options)
  {
    :run_for_nodes => :all,
    :rmdisk        => false,
    :run_id        => Time.now.strftime('%Y%m%d-%H%M%S'),
  }.merge(options)
end
pending_updates?(plan_name) click to toggle source
# File lib/dopv.rb, line 107
def self.pending_updates?(plan_name)
  state_store = Dopv::StateStore.new(plan_name, plan_store)
  state_store.pending_updates?
end
plan_store() click to toggle source
# File lib/dopv.rb, line 91
def self.plan_store
  @plan_store ||= DopCommon::PlanStore.new(DopCommon.config.plan_store_dir)
end
run(operation, plan_name, options) click to toggle source
# File lib/dopv.rb, line 112
def self.run(operation, plan_name, options)
  ensure_plan_exists(plan_name)
  update_state(plan_name)
  plan = get_plan(plan_name)
  run_options = merge_default_options(options)
  nodes = filter_nodes(plan.nodes, run_options[:run_for_nodes])

  context_log_path = File.join(DopCommon.config.log_dir, "#{run_options[:run_id]}-#{plan_name}")
  node_names = nodes.map{|n| n.name}
  context_logger = DopCommon::ThreadContextLogger.new(context_log_path, node_names)

  plan_store.run_lock(plan_name) do
    state_store = Dopv::StateStore.new(plan_name, plan_store)
    in_parallel(plan, nodes) do |node|
      context_logger.log_context = node.name
      case operation
      when :deploy   then Dopv::Infrastructure::bootstrap_node(node, state_store)
      when :undeploy then Dopv::Infrastructure::destroy_node(node, state_store, run_options[:rmdisk])
      when :refresh  then Dopv::Infrastructure::refresh_node(node, state_store)
      end
    end
  end
end