class Kitchen::Driver::Gce

Google Compute Engine driver for Test Kitchen

@author Andrew Leonard <andy@hurricane-ridge.com>

Public Instance Methods

create(state) click to toggle source
# File lib/kitchen/driver/gce.rb, line 44
def create(state)
  return if state[:server_id]

  instance = create_instance
  state[:server_id] = instance.identity

  info("GCE instance <#{state[:server_id]}> created.")

  wait_for_up_instance(instance, state)

rescue Fog::Errors::Error, Excon::Errors::Error => ex
  raise ActionFailed, ex.message
end
destroy(state) click to toggle source
# File lib/kitchen/driver/gce.rb, line 58
def destroy(state)
  return if state[:server_id].nil?

  instance = connection.servers.get(state[:server_id])
  instance.destroy unless instance.nil?
  info("GCE instance <#{state[:server_id]}> destroyed.")
  state.delete(:server_id)
  state.delete(:hostname)
end

Private Instance Methods

connection() click to toggle source
# File lib/kitchen/driver/gce.rb, line 70
def connection
  Fog::Compute.new(
    provider: 'google',
    google_client_email: config[:google_client_email],
    google_key_location: config[:google_key_location],
    google_project: config[:google_project]
  )
end
create_disk() click to toggle source
# File lib/kitchen/driver/gce.rb, line 79
def create_disk
  disk = connection.disks.create(
    name: config[:inst_name],
    size_gb: config[:disk_size],
    zone_name: config[:zone_name],
    source_image: config[:image_name]
  )

  disk.wait_for { disk.ready? }
  disk
end
create_instance() click to toggle source
# File lib/kitchen/driver/gce.rb, line 91
def create_instance
  config[:region] ||= config[:area]

  config[:inst_name] ||= generate_inst_name
  config[:zone_name] ||= select_zone

  disk = create_disk
  create_server(disk)
end
create_server(disk) click to toggle source
# File lib/kitchen/driver/gce.rb, line 101
def create_server(disk)
  connection.servers.create(
    name: config[:inst_name],
    disks: [disk.get_as_boot_disk(true, config[:autodelete_disk])],
    machine_type: config[:machine_type],
    network: config[:network],
    tags: config[:tags],
    zone_name: config[:zone_name],
    public_key_path: config[:public_key_path],
    username: config[:username]
  )
end
generate_inst_name() click to toggle source
# File lib/kitchen/driver/gce.rb, line 114
def generate_inst_name
  # Inspired by generate_name from kitchen-rackspace
  name = instance.name.downcase
  name.gsub!(/([^-a-z0-9])/, '-')
  name = 't' + name unless name =~ /^[a-z]/
  base_name = name[0..25] # UUID is 36 chars, max name length 63
  gen_name = "#{base_name}-#{SecureRandom.uuid}"
  unless gen_name =~ /^[a-z]([-a-z0-9]*[a-z0-9])?$/
    fail "Invalid generated instance name: #{gen_name}"
  end
  gen_name
end
select_zone() click to toggle source
# File lib/kitchen/driver/gce.rb, line 127
def select_zone
  if config[:region] == 'any'
    zone_regexp = /^[a-z]+\-/
  else
    zone_regexp = /^#{config[:region]}\-/
  end
  zones = connection.zones.select do |z|
    z.status == 'UP' && z.name.match(zone_regexp)
  end
  fail 'No up zones in region' unless zones.length >= 1
  zones.sample.name
end
wait_for_up_instance(instance, state) click to toggle source
# File lib/kitchen/driver/gce.rb, line 140
def wait_for_up_instance(instance, state)
  instance.wait_for do
    print '.'
    ready?
  end
  print '(server ready)'
  state[:hostname] = instance.public_ip_address ||
    instance.private_ip_address
  wait_for_sshd(state[:hostname], config[:username])
  puts '(ssh ready)'
end