class Bosh::Director::DeploymentPlan::Instance

Represents a single job instance.

Attributes

availability_zone[R]
configuration_hash[RW]

@return [String] Checksum all of the configuration templates

existing_network_reservations[R]
index[R]

@return [Integer] Instance index

model[R]

@return [Models::Instance] Instance model

rendered_templates_archive[RW]

@return [Bosh::Director::Core::Templates::RenderedTemplatesArchive]

template_hashes[RW]

@return [Hash] A hash of template SHA1 hashes

uuid[R]
virtual_state[R]

@return [String] job state

Public Class Methods

create_from_job(job, index, virtual_state, deployment_model, instance_state, availability_zone, logger) click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 32
def self.create_from_job(job, index, virtual_state, deployment_model, instance_state, availability_zone, logger)
  new(
    job.name,
    index,
    virtual_state,
    job.vm_type,
    job.vm_extensions,
    job.stemcell,
    job.env,
    job.compilation?,
    deployment_model,
    instance_state,
    availability_zone,
    logger
  )
end
new( job_name, index, virtual_state, vm_type, vm_extensions, stemcell, env, compilation, deployment_model, instance_state, availability_zone, logger ) click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 49
def initialize(
  job_name,
  index,
  virtual_state,
  vm_type,
  vm_extensions,
  stemcell,
  env,
  compilation,
  deployment_model,
  instance_state,
  availability_zone,
  logger
)
  @index = index
  @availability_zone = availability_zone
  @logger = logger
  @deployment_model = deployment_model
  @job_name = job_name
  @vm_type = vm_type
  @vm_extensions = vm_extensions
  @stemcell = stemcell
  @env = env
  @compilation = compilation

  @configuration_hash = nil
  @template_hashes = nil
  @vm = nil

  # This state is coming from the agent, we
  # only need networks and job_state from it.
  @current_state = instance_state || {}

  # reservation generated from current state/DB
  @existing_network_reservations = InstanceNetworkReservations.new(logger)
  @dns_manager = DnsManagerProvider.create

  @virtual_state = virtual_state
end

Public Instance Methods

agent_client() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 193
def agent_client
  AgentClient.with_vm_credentials_and_agent_id(@model.credentials, @model.agent_id)
end
apply_initial_vm_state(spec) click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 166
def apply_initial_vm_state(spec)
  # Agent will return dynamic network settings, we need to update spec with it
  # so that we can render templates with new spec later.
  agent_spec_keys = ['networks', 'deployment', 'job', 'index', 'id']
  agent_partial_state = spec.as_apply_spec.select { |k, _| agent_spec_keys.include?(k) }
  agent_client.apply(agent_partial_state)

  instance_spec_keys = agent_spec_keys + ['stemcell', 'vm_type', 'env']
  instance_partial_state = spec.full_spec.select { |k, _| instance_spec_keys.include?(k) }
  @current_state.merge!(instance_partial_state)

  agent_state = agent_client.get_state
  unless agent_state.nil?
    @current_state['networks'] = agent_state['networks']
    @model.update(spec: @current_state)
  end
end
apply_vm_state(spec) click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 158
def apply_vm_state(spec)
  @logger.info('Applying VM state')

  @current_state = spec.full_spec
  agent_client.apply(spec.as_apply_spec)
  @model.update(spec: @current_state)
end
assign_availability_zone(availability_zone) click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 245
def assign_availability_zone(availability_zone)
  @availability_zone = availability_zone
  @model.update(availability_zone: availability_zone_name)
end
availability_zone_name() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 294
def availability_zone_name
  return nil if @availability_zone.nil?

  @availability_zone.name
end
bind_existing_instance_model(existing_instance_model) click to toggle source

Updates this domain object to reflect an existing instance running on an existing vm

# File lib/bosh/director/deployment_plan/instance.rb, line 148
def bind_existing_instance_model(existing_instance_model)
  @uuid = existing_instance_model.uuid
  check_model_not_bound
  @model = existing_instance_model
end
bind_existing_reservations(reservations) click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 154
def bind_existing_reservations(reservations)
  @existing_network_reservations = reservations
end
bind_new_instance_model() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 113
def bind_new_instance_model
  @model = Models::Instance.create({
      deployment_id: @deployment_model.id,
      job: @job_name,
      index: index,
      state: state,
      compilation: @compilation,
      uuid: SecureRandom.uuid,
      availability_zone: availability_zone_name,
      bootstrap: false
    })
  @uuid = @model.uuid
end
bootstrap?() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 89
def bootstrap?
  @model && @model.bootstrap
end
cloud_properties() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 278
def cloud_properties
  merged_cloud_properties = nil

  if !@availability_zone.nil?
    merged_cloud_properties = merge_cloud_properties(merged_cloud_properties, @availability_zone.cloud_properties)
  end

  merged_cloud_properties = merge_cloud_properties(merged_cloud_properties, vm_type.cloud_properties)

  Array(vm_extensions).each do |vm_extension|
    merged_cloud_properties = merge_cloud_properties(merged_cloud_properties, vm_extension.cloud_properties)
  end

  merged_cloud_properties
end
cloud_properties_changed?() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 203
def cloud_properties_changed?
  changed = cloud_properties != @model.cloud_properties_hash
  log_changes(__method__, @model.cloud_properties_hash, cloud_properties) if changed
  changed
end
compilation?() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 93
def compilation?
  @compilation
end
current_job_spec() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 209
def current_job_spec
  @model.spec_p('job')
end
current_job_state() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 217
def current_job_state
  @current_state['job_state']
end
current_networks() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 221
def current_networks
  @current_state['networks']
end
current_packages() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 213
def current_packages
  @model.spec_p('packages')
end
deployment_model() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 143
def deployment_model
  @deployment_model
end
dirty?() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 229
def dirty?
  !@model.update_completed
end
dns_record_name(hostname, network_name) click to toggle source

@return [String] dns record name

# File lib/bosh/director/deployment_plan/instance.rb, line 199
def dns_record_name(hostname, network_name)
  [hostname, job.canonical_name, Canonicalizer.canonicalize(network_name), Canonicalizer.canonicalize(@deployment_model.name), @dns_manager.dns_domain_name].join('.')
end
ensure_model_bound() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 109
def ensure_model_bound
  @model ||= find_or_create_model
end
env() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 139
def env
  @env.spec
end
job_name() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 97
def job_name
  @job_name
end
mark_as_bootstrap() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 237
def mark_as_bootstrap
  @model.update(bootstrap: true)
end
state() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 250
def state
  case @virtual_state
    when 'recreate'
      'started'
    when 'restart'
      'started'
    else
      @virtual_state
  end
end
stemcell() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 135
def stemcell
  @stemcell
end
to_s() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 101
def to_s
  if @uuid.nil?
    "#{@job_name}/#{@index}"
  else
    "#{@job_name}/#{@index} (#{@uuid})"
  end
end
trusted_certs_changed?() click to toggle source

Checks if the target VM already has the same set of trusted SSL certificates as the director currently wants to install on all managed VMs. This will differ for VMs that existed before the director's configuration changed.

@return [Boolean] true if the VM needs to be sent a new set of trusted certificates

# File lib/bosh/director/deployment_plan/instance.rb, line 267
def trusted_certs_changed?
  config_trusted_certs = Digest::SHA1.hexdigest(Bosh::Director::Config.trusted_certs)
  changed = config_trusted_certs != @model.trusted_certs_sha1
  log_changes(__method__, @model.trusted_certs_sha1, config_trusted_certs) if changed
  changed
end
unmark_as_bootstrap() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 241
def unmark_as_bootstrap
  @model.update(bootstrap: false)
end
update_cloud_properties!() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 189
def update_cloud_properties!
  @model.update(cloud_properties: JSON.dump(cloud_properties))
end
update_description() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 233
def update_description
  @model.update(job: job_name, index: index)
end
update_state() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 225
def update_state
  @model.update(state: state)
end
update_templates(templates) click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 300
def update_templates(templates)
  transactor = Transactor.new
  transactor.retryable_transaction(Bosh::Director::Config.db) do
    @model.remove_all_templates
    templates.map(&:model).each do |template_model|
      @model.add_template(template_model)
    end
  end
end
update_trusted_certs() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 184
def update_trusted_certs
  agent_client.update_settings(Config.trusted_certs)
  @model.update(:trusted_certs_sha1 => Digest::SHA1.hexdigest(Config.trusted_certs))
end
vm_created?() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 274
def vm_created?
  !@model.vm_cid.nil?
end
vm_extensions() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 131
def vm_extensions
  @vm_extensions
end
vm_type() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 127
def vm_type
  @vm_type
end

Private Instance Methods

check_model_bound() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 342
def check_model_bound
  if @model.nil?
    raise DirectorError, "Instance '#{self}' model is not bound"
  end
end
check_model_not_bound() click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 348
def check_model_not_bound
  raise DirectorError, "Instance '#{self}' model is already bound" if @model
end
find_or_create_model() click to toggle source

Looks up instance model in DB @return [Models::Instance]

# File lib/bosh/director/deployment_plan/instance.rb, line 318
def find_or_create_model
  if @deployment_model.nil?
    raise DirectorError, 'Deployment model is not bound'
  end

  conditions = {
    deployment_id: @deployment_model.id,
    job: @job_name,
    index: @index
  }

  Models::Instance.find_or_create(conditions) do |model|
    model.state = 'started'
    model.compilation = @compilation
    model.uuid = SecureRandom.uuid
  end
end
log_changes(method_sym, old_state, new_state) click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 352
def log_changes(method_sym, old_state, new_state)
  @logger.debug("#{method_sym} changed FROM: #{old_state} TO: #{new_state}")
end
merge_cloud_properties(merged_cloud_properties, new_cloud_properties) click to toggle source
# File lib/bosh/director/deployment_plan/instance.rb, line 312
def merge_cloud_properties(merged_cloud_properties, new_cloud_properties)
  merged_cloud_properties.nil? ? new_cloud_properties : merged_cloud_properties.merge(new_cloud_properties)
end
network_to_ip(network_settings) click to toggle source

@param [Hash] network_settings map of network name to settings @return [Hash] map of network name to IP address

# File lib/bosh/director/deployment_plan/instance.rb, line 338
def network_to_ip(network_settings)
  Hash[network_settings.map { |network_name, settings| [network_name, settings['ip']] }]
end