Class/Module Index [+]

Quicksearch

Ironfan::Provider::Ec2::Machine

Public Class Methods

block_device_mapping(computer) click to toggle source

An array of hashes with dorky-looking keys, just like Fog wants it.

# File lib/ironfan/provider/ec2/machine.rb, line 263
def self.block_device_mapping(computer)
  Ironfan.todo "CODE SMELL: Machine is too familiar with EbsVolume problems"
  computer.drives.values.map do |drive|
    next if drive.disk  # Don't create any disc already satisfied
    volume = drive.volume or next
    hsh = { 'DeviceName' => volume.device }
    if volume.attachable == 'ephemeral'
      hsh['VirtualName'] = drive.name
    # if set for creation at launch (and not already created)
    elsif drive.node[:volume_id].blank? && volume.create_at_launch
      if volume.snapshot_id.blank? && volume.size.blank?
        raise "Must specify a size or a snapshot ID for #{volume}"
      end
      hsh['Ebs.SnapshotId'] = volume.snapshot_id if volume.snapshot_id.present?
      hsh['Ebs.VolumeSize'] = volume.size.to_s   if volume.size.present?
      hsh['Ebs.DeleteOnTermination'] = (not volume.keep).to_s
    else next
    end
    hsh
  end.compact
end
create!(computer) click to toggle source

Manipulation

# File lib/ironfan/provider/ec2/machine.rb, line 147
def self.create!(computer)
  Ironfan.todo("CODE SMELL: overly large method: #{caller}")
  return if computer.machine? and computer.machine.created?
  Ironfan.step(computer.name,"creating cloud machine", :green)
  #
  errors = lint(computer)
  if errors.present? then raise ArgumentError, "Failed validation: #{errors.inspect}" ; end
  #
  launch_desc = launch_description(computer)
  Chef::Log.debug(JSON.pretty_generate(launch_desc))

  Ironfan.safely do
    fog_server = Ec2.connection.servers.create(launch_desc)
    machine = Machine.new(:adaptee => fog_server)
    computer.machine = machine
    remember machine, :id => computer.name

    fog_server.wait_for { ready? }
  end
  
  # tag the computer correctly
  tags = {
    'cluster' =>      computer.server.cluster_name,
    'facet' =>        computer.server.facet_name,
    'index' =>        computer.server.index,
    'name' =>         computer.name,
    'Name' =>         computer.name,
  }
  Ec2.ensure_tags(tags, computer.machine)

  # register the new volumes for later save!, and tag appropriately
  computer.machine.volumes.each do |v|
    Ironfan.todo "CODE SMELL: Machine is too familiar with EbsVolume problems"
    ebs_vol = Ec2::EbsVolume.register v
    drive = computer.drives.values.select do |drive|
      drive.volume.device == ebs_vol.device
    end.first
    drive.disk = ebs_vol

    vol_name = "#{computer.name}-#{drive.volume.name}"
    tags['server'] = computer.name
    tags['name'] = vol_name
    tags['Name'] = vol_name
    tags['mount_point'] = drive.volume.mount_point
    tags['device'] = drive.volume.device
    Ec2.ensure_tags(tags,ebs_vol)
  end
end
destroy!(computer) click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 285
def self.destroy!(computer)
  return unless computer.machine?
  forget computer.machine.name
  computer.machine.destroy
  computer.machine.reload            # show the node as shutting down
end
expected_ids(computer) click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 41
def self.expected_ids(computer) [computer.server.full_name];   end
launch_description(computer) click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 213
def self.launch_description(computer)
  cloud = computer.server.cloud(:ec2)
  user_data_hsh =               {
    :chef_server =>             Chef::Config[:chef_server_url],
    # :validation_client_name => Chef::Config[:validation_client_name],
    #
    :node_name =>               computer.name,
    :organization =>            Chef::Config[:organization],
    :cluster_name =>            computer.server.cluster_name,
    :facet_name =>              computer.server.facet_name,
    :facet_index =>             computer.server.index,
    :client_key =>              computer.private_key
  }

  # Fog does not actually create tags when it creates a server;
  #  they and permanence are applied during sync
  description = {
    :image_id             => cloud.image_id,
    :flavor_id            => cloud.flavor,
    :vpc_id               => cloud.vpc,
    :subnet_id            => cloud.subnet,
    :key_name             => cloud.ssh_key_name(computer),
    :user_data            => JSON.pretty_generate(user_data_hsh),
    :block_device_mapping => block_device_mapping(computer),
    :availability_zone    => cloud.default_availability_zone,
    :monitoring           => cloud.monitoring
  }

  # VPC security_groups can only be addressed by id (not name)
  description[:security_group_ids] = cloud.security_groups.keys.map do |g|
    group_name = cloud.vpc.nil? ? g.to_s : "#{cloud.vpc}:#{g}"
    SecurityGroup.recall(group_name).group_id
  end

  description[:iam_server_certificates] = cloud.iam_server_certificates.values.map do |cert|
    IamServerCertificate.recall(IamServerCertificate.full_name(computer, cert))
  end.compact.map(&:name)

  description[:elastic_load_balancers] = cloud.elastic_load_balancers.values.map do |elb|
    ElasticLoadBalancer.recall(ElasticLoadBalancer.full_name(computer, elb))
  end.compact.map(&:name)

  if cloud.flavor_info[:placement_groupable]
    ui.warn "1.3.1 and earlier versions of Fog don't correctly support placement groups, so your nodes will land willy-nilly. We're working on a fix"
    description[:placement] = { 'groupName' => cloud.placement_group.to_s }
  end
  description
end
lint(computer) click to toggle source

@returns [Hash{String, Array}] of ‘what you did wrong’ => [relevant, info]

# File lib/ironfan/provider/ec2/machine.rb, line 197
def self.lint(computer)
  cloud = computer.server.cloud(:ec2)
  info  = [computer.name, cloud.inspect]
  errors = {}
  server_errors = computer.server.lint
  errors["Unhappy Server"] = server_errors if server_errors.present?
  errors["No AMI found"] = info if cloud.image_id.blank?
  errors['Missing client']      = info            unless computer.client?
  errors['Missing private_key'] = computer.client unless computer.private_key
  #
  all_asserted_regions = [Ec2.connection.region, cloud.region, Chef::Config[:knife][:region], Ironfan.chef_config[:region]].compact.uniq
  errors["mismatched region"] = all_asserted_regions unless all_asserted_regions.count == 1
  #
  errors
end
load!(cluster=nil) click to toggle source

Discovery

# File lib/ironfan/provider/ec2/machine.rb, line 104
def self.load!(cluster=nil)
  Ec2.connection.servers.each do |fs|
    machine = new(:adaptee => fs)
    if (not machine.created?)
      next unless Ironfan.chef_config[:include_terminated]
      remember machine, :append_id => "terminated:#{machine.id}"
    elsif recall? machine.name
      machine.bogus <<                 :duplicate_machines
      recall(machine.name).bogus <<    :duplicate_machines
      remember machine, :append_id => "duplicate:#{machine.id}"
    else # never seen it
      remember machine
    end
    Chef::Log.debug("Loaded #{machine}")
  end
end
multiple?() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 38
def self.multiple?()    false;  end
resource_type() click to toggle source

def self.resource_type() Ironfan::IaasProvider::Machine; end

# File lib/ironfan/provider/ec2/machine.rb, line 40
def self.resource_type()        :machine;   end
save!(computer) click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 292
def self.save!(computer)
  return unless computer.machine?
  # the EC2 API does not surface disable_api_termination as a value, so we
  # have to set it every time.
  permanent = computer.server.cloud(:ec2).permanent
  return unless computer.created?
  Ironfan.step(computer.name, "setting termination flag #{permanent}", :blue)
  Ironfan.unless_dry_run do
    Ironfan.safely do
      Ec2.connection.modify_instance_attribute( computer.machine.id,
        {'DisableApiTermination.Value' => computer.permanent?, })
    end
  end
end
shared?() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 37
def self.shared?()      false;  end
validate_resources!(computers) click to toggle source

Find active machines that haven’t matched, but should have,

make sure all bogus machines have a computer to attach to
for display purposes
# File lib/ironfan/provider/ec2/machine.rb, line 129
def self.validate_resources!(computers)
  recall.each_value do |machine|
    next unless machine.users.empty? and machine.name
    if machine.name.match("^#{computers.cluster.name}-")
      machine.bogus << :unexpected_machine
    end
    next unless machine.bogus?
    fake           = Ironfan::Broker::Computer.new
    fake[:machine] = machine
    fake.name      = machine.name
    machine.users << fake
    computers     << fake
  end
end

Public Instance Methods

created?() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 51
def created?
  not ['terminated', 'shutting-down'].include? state
end
keypair() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 49
def keypair          ; key_pair ; end
name() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 43
def name
  return id if tags.empty?
  tags["Name"] || tags["name"] || id
end
public_hostname() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 48
def public_hostname  ; dns_name ; end
receive_adaptee(obj) click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 121
def receive_adaptee(obj)
  obj = Ec2.connection.servers.new(obj) if obj.is_a?(Hash)
  super
end
running?() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 54
def running?
  state == "running"
end
ssh_key() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 92
def ssh_key
  keypair = cloud.keypair || computer.server.cluster_name
end
start() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 61
def start
  adaptee.start
  adaptee.wait_for{ state == 'pending' }
end
stop() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 66
def stop
  adaptee.stop
  adaptee.wait_for{ state == 'stopping' }
end
stopped?() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 57
def stopped?
  state == "stopped"
end
to_display(style,values={}) click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 71
def to_display(style,values={})
  # style == :minimal
  values["State"] =             state.to_sym
  values["MachineID"] =         id
  values["Public IP"] =         public_ip_address 
  values["Private IP"] =        private_ip_address
  values["Created On"] =        created_at.to_date
  return values if style == :minimal

  # style == :default
  values["Flavor"] =            flavor_id
  values["AZ"] =                availability_zone
  return values if style == :default

  # style == :expanded
  values["Image"] =             image_id
  values["Volumes"] =           volumes.map(&:id).join(', ')
  values["SSH Key"] =           key_name
  values
end
to_s() click to toggle source
# File lib/ironfan/provider/ec2/machine.rb, line 96
def to_s
  "<%-15s %-12s %-25s %-25s %-15s %-15s %-12s %-12s %s:%s>" % [
    self.class.handle, id, created_at, tags['name'], private_ip_address, public_ip_address, flavor_id, availability_zone, key_name, groups.join(',') ]
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.