class Dopv::Infrastructure::Base
Constants
- MAX_RETRIES
Attributes
data_disks_db[R]
Public Class Methods
bootstrap_node(plan, state_store)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 31 def self.bootstrap_node(plan, state_store) new(plan, state_store).bootstrap_node end
destroy_node(plan, state_store, destroy_data_volumes=false)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 35 def self.destroy_node(plan, state_store, destroy_data_volumes=false) new(plan, state_store).destroy_node(destroy_data_volumes) end
new(plan, state_store)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 43 def initialize(plan, state_store) @compute_provider = nil @plan = plan @state_store = state_store @data_disks_db = Dopv::PersistentDisk::DB.new(state_store, nodename) end
refresh_node(plan, state_store)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 39 def self.refresh_node(plan, state_store) new(plan, state_store).refresh_node end
Public Instance Methods
bootstrap_node()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 50 def bootstrap_node begin unless get_node_instance execute_hook(:pre_create_vm, true) node_instance = create_node_instance add_node_nics(node_instance) add_node_data_volumes(node_instance) add_node_affinities(node_instance) start_node_instance(node_instance) execute_hook(:post_create_vm, true) record_node_instance(node_instance) refresh_node_instance(node_instance) else ::Dopv::log.warn("Node #{nodename}: Already exists.") # TODO: Ask Marcel what would be a purpose/use case of this execute_hook(:pre_create_vm, false) execute_hook(:post_create_vm, false) end rescue Exception => e ::Dopv::log.error("Node #{nodename}: #{e}") destroy_node_instance(node_instance) raise ProviderError, "Node #{nodename}: #{e}." end end
destroy_node(destroy_data_volumes=false)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 75 def destroy_node(destroy_data_volumes=false) node_instance = get_node_instance if node_instance execute_hook(:pre_destroy_vm, true) destroy_node_instance(node_instance, destroy_data_volumes) execute_hook(:post_destroy_vm, true) erase_node_instance(node_instance) else # TODO: Ask Marcel what would be a purpose/use case of this execute_hook(:pre_destroy_vm, false) execute_hook(:post_destroy_vm, false) end end
refresh_node()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 89 def refresh_node node_instance = get_node_instance if node_instance record_node_instance(node_instance) refresh_node_instance(node_instance) else erase_node_instance(node_instance) end end
Private Instance Methods
add_node_affinities(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 390 def add_node_affinities(node_instance) infrastructure_properties.affinity_groups.each { |a| add_node_affinity(node_instance, a) } end
add_node_affinity(node_instance, affinity)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 306 def add_node_affinity(node_instance, affinity) end
add_node_data_volumes(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 332 def add_node_data_volumes(node_instance) ::Dopv::log.info("Node #{nodename}: Adding data volumes.") ::Dopv::log.debug("Node #{nodename}: Loading data volumes DB.") data_volumes = data_disks_db.volumes # Check if persistent disks DB is consistent ::Dopv::log.debug("Node #{nodename}: Checking data volumes DB integrity.") data_volumes.each do |dv| # Disk exists in state DB but not in plan unless volumes_config.find { |cv| dv.name == cv.name } err_msg = "Inconsistent data volumes DB: Volume #{dv.name} exists in DB but not in plan" raise ProviderError, err_msg end end volumes_config.each do |cv| # Disk exists in a plan but it is not recorded in the state DB for a # given node if !data_volumes.empty? && !data_volumes.find { |dv| cv.name == dv.name } ::Dopv::log.warn("Node #{nodename}: Data volume #{cv.name} exists in plan but not in DB.") end end # Attach all persistent disks data_volumes.each do |dv| ::Dopv::log.debug("Node #{nodename}: Attaching data volume #{dv.name} [#{dv.id}].") begin attach_node_volume(node_instance, dv) rescue Exception => e err_msg = "An error occured while attaching data volume #{dv.name}: #{e}" raise ProviderError, err_msg end end # Create those disks that do not exist in peristent disks DB and # record them into DB volumes_config.each do |cv| unless data_disks_db.volumes.find { |v| v.name == cv.name } ::Dopv::log.debug("Node #{nodename}: Creating disk #{cv.name} [#{cv.size.g} G].") volume = add_node_volume(node_instance, cv) record_node_data_volume(volume) unless volume.nil? end end end
add_node_nic(node_instance, attrs)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 282 def add_node_nic(node_instance, attrs) nic = node_instance.interfaces.create(attrs) node_instance.interfaces.reload nic end
add_node_nics(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 293 def add_node_nics(node_instance) end
add_node_volume(node_instance, config)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 312 def add_node_volume(node_instance, config) node_instance.volumes.create(config) end
administrator_fullname()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 147 def administrator_fullname 'Administrator' end
administrator_password()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 141 def administrator_password cred = credentials.find { |c| c.type == :username_password && c.username == 'Administrator' } if @administrator_password.nil? @administrator_password ||= cred.nil? ? nil : cred.password end
attach_node_volume(node_instance, volume)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 326 def attach_node_volume(node_instance, volume) end
cluster(filters={})
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 174 def cluster(filters={}) @cluster ||= compute_provider.clusters(filters).find { |c| c.name == infrastructure_properties.cluster } raise ProviderError, "No such cluster #{infrastructure_properties.cluster}" unless @cluster @cluster end
compute_provider()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 155 def compute_provider Dopv::log.info("Node #{nodename}: Creating compute provider.") unless @compute_provider @compute_provider ||= @compute_connection_opts ? ::Fog::Compute.new(@compute_connection_opts) : nil end
create_node_instance()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 219 def create_node_instance Dopv::log.info("Node #{nodename}: Creating node instance.") node_instance = compute_provider.servers.create(@node_creation_opts) wait_for_task_completion(node_instance) node_instance end
customize_node_instance(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 259 def customize_node_instance(node_instance) end
datacenter(filters={})
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 160 def datacenter(filters={}) @datacenter ||= compute_provider.datacenters(filters).find do |d| if d.is_a?(Hash) && d.has_key?(:name) d[:name] == infrastructure_properties.datacenter elsif d.respond_to?(:name) d.name == infrastructure_properties.datacenter else raise ProviderError, "Unsupported datacenter class #{d.class}" end end raise ProviderError, "No such data center #{infrastructure_properties.datacenter}" unless @datacenter @datacenter end
destroy_node_instance(node_instance, destroy_data_volumes=false)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 226 def destroy_node_instance(node_instance, destroy_data_volumes=false) if node_instance stop_node_instance(node_instance, { 'force' => force_stop }) volumes = data_disks_db.volumes volumes.each do |v| if destroy_data_volumes ::Dopv::log.warn("Node #{nodename} Destroying data volume #{v.name}.") begin destroy_node_volume(node_instance, v) rescue ::Dopv::log.error("Could not destroy data volume #{v.name}. Please fix manually.") end erase_node_data_volume(v) else ::Dopv::log.debug("Node #{nodename} Detaching data volume #{v.name}.") begin detach_node_volume(node_instance, v) rescue ::Dopv::log.warn("Could not detach data volume #{v.name}.") end end end ::Dopv::log.warn("Node #{nodename}: Destroying node.") node_instance.destroy rescue nil end end
destroy_node_volume(node_instance, volume)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 323 def destroy_node_volume(node_instance, volume) end
detach_node_volume(node_instance, volume)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 329 def detach_node_volume(node_instance, volume) end
erase_node_data_volume(volume)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 382 def erase_node_data_volume(volume) ::Dopv::log.debug("Node #{nodename}: Erasing data volume #{volume.name} from data volumes DB.") data_disks_db.delete(volume) end
erase_node_instance(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 414 def erase_node_instance(node_instance) @state_store.transaction do if @state_store[:nodes] @state_store[:nodes].delete(nodename) end end end
execute_hook(hook_name, state_changed = false)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 394 def execute_hook(hook_name, state_changed = false) has_changes = state_changed ? 1 : 0 hooks.send(hook_name).each do |prog| prog_name = File.basename(prog) ::Dopv::log.info("Node #{nodename}: Executing #{hook_name}[#{prog_name}].") o, e, s = Open3.capture3(sanitize_env, "#{prog} #{nodename} #{has_changes}", :unsetenv_others => true) ::Dopv::log.debug("Node #{nodename}: #{hook_name}[#{prog_name}] standard output:\n#{o.chomp}") ::Dopv::log.warn("Node #{nodename}: #{hook_name}[#{prog_name}] non-zero exit status #{s.exitstatus}") unless s.success? ::Dopv::log.debug("Node #{nodename}: #{hook_name}[#{prog_name}] standard error:\n#{e.chomp}") unless e.chomp.empty? end end
get_node_instance(filters = {})
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 193 def get_node_instance(filters = {}) retries = 0 compute_provider.servers.all(filters).find { |n| n.name == nodename } rescue => e errmsg = "Node #{nodename}: An error occured while searching for a node: #{e}." retries += 1 if retries <= MAX_RETRIES Dopv.log.warn("#{errmsg} Retrying (##{retries}).") sleep 1 retry else raise ProviderError, "#{errmsg}. Bailing out" end end
get_node_ip_addresses(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 422 def get_node_ip_addresses(node_instance) [] end
keep_ha?()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 151 def keep_ha? @keep_ha ||= infrastructure_properties.keep_ha? end
node_instance_ready?(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 208 def node_instance_ready?(node_instance) node_instance.ready? end
node_instance_stopped?(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 212 def node_instance_stopped?(node_instance) node_instance.stopped? end
provider_host()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 113 def provider_host @provider_host ||= infrastructure.endpoint.host end
provider_password()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 105 def provider_password @provider_passowrd ||= infrastructure.credentials.password end
provider_port()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 117 def provider_port @provider_port ||= infrastructure.endpoint.port end
provider_scheme()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 121 def provider_scheme @provider_scheme ||= infrastructure.endpoint.scheme end
provider_ssl?()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 125 def provider_ssl? provider_scheme == 'https' end
provider_url()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 109 def provider_url @provider_url ||= infrastructure.endpoint.to_s end
provider_username()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 101 def provider_username @provider_username ||= infrastructure.credentials.username end
record_node_data_volume(volume)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 377 def record_node_data_volume(volume) ::Dopv::log.debug("Node #{nodename}: Recording data volume #{volume[:name]} into data volumes DB.") data_disks_db << volume.merge(:node => nodename) end
record_node_instance(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 406 def record_node_instance(node_instance) @state_store.transaction do @state_store[:nodes] ||= {} @state_store[:nodes][nodename] ||= {} @state_store[:nodes][nodename][:ip_addresses] = get_node_ip_addresses(node_instance) end end
refresh_node_instance(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 426 def refresh_node_instance(node_instance) end
reload_node_instance(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 255 def reload_node_instance(node_instance) node_instance.reload end
remove_node_affinity(node_instance, affinity)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 309 def remove_node_affinity(node_instance, affinity) end
remove_node_nics(node_instance) { |node_instance, nic| ... }
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 296 def remove_node_nics(node_instance) Dopv::log.debug("Node #{nodename}: Removing (possible) network interfaces defined by template.") if block_given? node_instance.interfaces.each { |nic| yield(node_instance, nic) } else node_instance.interfaces.each(&:destroy) rescue nil end node_instance.interfaces.reload end
root_password()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 129 def root_password cred = credentials.find { |c| c.type == :username_password && c.username == 'root' } if @root_password.nil? @root_password ||= cred.nil? ? nil : cred.password end
root_ssh_pubkeys()
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 135 def root_ssh_pubkeys cred = credentials.find_all { |c| c.type == :ssh_key && c.username == 'root' } if @root_ssh_pubkeys.nil? @root_ssh_pubkey ||= cred.empty? ? [] : cred.collect { |k| k.public_key }.uniq end
start_node_instance(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 262 def start_node_instance(node_instance) stop_node_instance(node_instance) ::Dopv::log.info("Node #{nodename}: Starting node.") customize_node_instance(node_instance) end
stop_node_instance(node_instance, options={})
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 268 def stop_node_instance(node_instance, options={}) reload_node_instance(node_instance) unless node_instance_stopped?(node_instance) ::Dopv::log.info("Node #{nodename}: Stopping node.") wait_for_task_completion(node_instance) begin node_instance.stop(options) rescue ArgumentError node_instance.stop end reload_node_instance(node_instance) end end
template(filters={})
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 180 def template(filters={}) raise ProviderError, "No template defined" unless image @template ||= if compute_provider.respond_to?(:templates) compute_provider.templates.all(filters).find { |t| t.name == image } elsif compute_provider.respond_to?(:images) compute_provider.images.all(filters).find { |t| t.name == image } else raise ProviderError, "The provider does not to have template/image collection" end raise ProviderError, "No such template #{image}" unless @template @template end
update_node_nic(node_instance, nic, attrs)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 288 def update_node_nic(node_instance, nic, attrs) nic.save(attrs) node_instance.interfaces.reload end
update_node_volume(node_instance, volume, attrs)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 316 def update_node_volume(node_instance, volume, attrs) node_instance.update_volume(attrs.merge(:id => volume.id)) wait_for_task_completion(node_instance) node_instance.volumes.reload volume end
wait_for_task_completion(node_instance)
click to toggle source
# File lib/dopv/infrastructure/providers/base.rb, line 216 def wait_for_task_completion(node_instance) end