Class: Beaker::GoogleCompute

Inherits:
Hypervisor show all
Defined in:
lib/beaker/hypervisor/google_compute.rb

Overview

Beaker support for the Google Compute Engine.

Constant Summary collapse

SLEEPWAIT =
5
ZOMBIE =

number of hours before an instance is considered a zombie

3

Constants inherited from Hypervisor

Hypervisor::CHARMAP

Constants included from HostPrebuiltSteps

HostPrebuiltSteps::APT_CFG, HostPrebuiltSteps::CUMULUS_PACKAGES, HostPrebuiltSteps::DEBIAN_PACKAGES, HostPrebuiltSteps::ETC_HOSTS_PATH, HostPrebuiltSteps::ETC_HOSTS_PATH_SOLARIS, HostPrebuiltSteps::FREEBSD_PACKAGES, HostPrebuiltSteps::IPS_PKG_REPO, HostPrebuiltSteps::NTPSERVER, HostPrebuiltSteps::OPENBSD_PACKAGES, HostPrebuiltSteps::PSWINDOWS_PACKAGES, HostPrebuiltSteps::ROOT_KEYS_SCRIPT, HostPrebuiltSteps::ROOT_KEYS_SYNC_CMD, HostPrebuiltSteps::ROOT_KEYS_SYNC_CMD_AIX, HostPrebuiltSteps::SLES10_PACKAGES, HostPrebuiltSteps::SLES_PACKAGES, HostPrebuiltSteps::SOLARIS10_PACKAGES, HostPrebuiltSteps::TRIES, HostPrebuiltSteps::UNIX_PACKAGES, HostPrebuiltSteps::WINDOWS_PACKAGES

Instance Method Summary collapse

Methods inherited from Hypervisor

#configure, create, #generate_host_name, #proxy_package_manager, #validate

Methods included from HostPrebuiltSteps

#add_el_extras, #additive_hash_merge, #apt_get_update, #check_and_install_packages_if_needed, #construct_env, #copy_file_to_remote, #copy_ssh_to_root, #disable_iptables, #disable_se_linux, #disable_updates, #enable_root_login, #epel_info_for, #get_domain_name, #get_ip, #hack_etc_hosts, #package_proxy, #proxy_config, #set_env, #set_etc_hosts, #sync_root_keys, #timesync, #validate_host

Methods included from DSL::Patterns

#block_on

Constructor Details

#initialize(google_hosts, options) ⇒ GoogleCompute

Create a new instance of the Google Compute Engine hypervisor object

Parameters:

  • google_hosts (<Host>)

    The array of google hosts to provision, may ONLY be of platforms /centos-6-.*/ and /debian-7-.*/. We currently only support the Google Compute provided templates.

  • options (Hash{Symbol=>String})

    The options hash containing configuration values

Options Hash (options):

  • :gce_project (String)

    The Google Compute Project name to connect to

  • :gce_keyfile (String)

    The location of the Google Compute service account keyfile

  • :gce_password (String)

    The password for the Google Compute service account key

  • :gce_email (String)

    The email address for the Google Compute service account

  • :gce_machine_type (String)

    A Google Compute machine type used to create instances, defaults to n1-highmem-2

  • :timeout (Integer)

    The amount of time to attempt execution before quiting and exiting with failure



29
30
31
32
33
34
35
36
# File 'lib/beaker/hypervisor/google_compute.rb', line 29

def initialize(google_hosts, options)
  require 'beaker/hypervisor/google_compute_helper'
  @options = options
  @logger = options[:logger]
  @hosts = google_hosts
  @firewall = ''
  @gce_helper = GoogleComputeHelper.new(options)
end

Instance Method Details

#cleanupObject

Shutdown and destroy virtual machines in the Google Compute Engine, including their associated disks and firewall rules



98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/beaker/hypervisor/google_compute.rb', line 98

def cleanup()
  attempts = @options[:timeout].to_i / SLEEPWAIT
  start = Time.now

  @gce_helper.delete_firewall(@firewall, start, attempts)

  @hosts.each do |host|
    @gce_helper.delete_instance(host['vmhostname'], start, attempts)
    @logger.debug("Deleted Google Compute instance #{host['vmhostname']} for #{host.name}")
    @gce_helper.delete_disk(host['diskname'], start, attempts)
    @logger.debug("Deleted Google Compute disk #{host['diskname']} for #{host.name}")
  end

end

#format_metadataObject

Create the array of metaData, each member being a hash with a :key and a :value. Sets :department, :project and :jenkins_build_url.



13
14
15
16
17
# File 'lib/beaker/hypervisor/google_compute.rb', line 13

def 
  [ {:key => :department, :value => @options[:department]},
    {:key => :project, :value => @options[:project]},
    {:key => :jenkins_build_url, :value => @options[:jenkins_build_url]} ].delete_if { |member| member[:value].nil? or member[:value].empty?}
end

#kill_zombies(max_age = ZOMBIE) ⇒ Object

Shutdown and destroy Google Compute instances (including their associated disks and firewall rules) that have been alive longer than ZOMBIE hours.



115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
# File 'lib/beaker/hypervisor/google_compute.rb', line 115

def kill_zombies(max_age = ZOMBIE)
  now = start = Time.now
  attempts = @options[:timeout].to_i / SLEEPWAIT

  #get rid of old instances
  instances = @gce_helper.list_instances(start, attempts)
  if instances
    instances.each do |instance|
      created = Time.parse(instance['creationTimestamp'])
      alive = (now - created ) /60 /60
      if alive >= max_age
        #kill it with fire!
        @logger.debug("Deleting zombie instance #{instance['name']}")
        @gce_helper.delete_instance( instance['name'], start, attempts )
      end
    end
  else
    @logger.debug("No zombie instances found")
  end
  #get rid of old disks
  disks = @gce_helper.list_disks(start, attempts)
  if disks
    disks.each do |disk|
      created = Time.parse(disk['creationTimestamp'])
      alive = (now - created ) /60 /60
      if alive >= max_age
        #kill it with fire!
        @logger.debug("Deleting zombie disk #{disk['name']}")
        @gce_helper.delete_disk( disk['name'], start, attempts )
      end
    end
  else
    @logger.debug("No zombie disks found")
  end
  #get rid of non-default firewalls
  firewalls = @gce_helper.list_firewalls( start, attempts)

  if firewalls and not firewalls.empty?
    firewalls.each do |firewall|
      @logger.debug("Deleting non-default firewall #{firewall['name']}")
      @gce_helper.delete_firewall( firewall['name'], start, attempts )
    end
  else
    @logger.debug("No zombie firewalls found")
  end

end

#provisionObject

Create and configure virtual machines in the Google Compute Engine, including their associated disks and firewall rules Currently ONLY supports Google Compute provided templates of CENTOS-6 and DEBIAN-7



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/beaker/hypervisor/google_compute.rb', line 40

def provision
  try = 1
  attempts = @options[:timeout].to_i / SLEEPWAIT
  start = Time.now

  #get machineType resource, used by all instances
  machineType = @gce_helper.get_machineType(start, attempts)

  #set firewall to open pe ports
  network = @gce_helper.get_network(start, attempts)
  @firewall = generate_host_name
  @gce_helper.create_firewall(@firewall, network, start, attempts)

  @logger.debug("Created Google Compute firewall #{@firewall}")


  @hosts.each do |host|
    gplatform = Platform.new(host[:image] || host[:platform])
    img = @gce_helper.get_latest_image(gplatform, start, attempts)
    host['diskname'] = generate_host_name
    disk = @gce_helper.create_disk(host['diskname'], img, start, attempts)
    @logger.debug("Created Google Compute disk for #{host.name}: #{host['diskname']}")

    #create new host name
    host['vmhostname'] = generate_host_name
    #add a new instance of the image
    instance = @gce_helper.create_instance(host['vmhostname'], img, machineType, disk, start, attempts)
    @logger.debug("Created Google Compute instance for #{host.name}: #{host['vmhostname']}")

    #add metadata to instance, if there is any to set
    mdata = 
    if not mdata.empty?
      @gce_helper.(host['vmhostname'], instance['metadata']['fingerprint'],
                                          mdata,
                                          start, attempts)
      @logger.debug("Added tags to Google Compute instance #{host.name}: #{host['vmhostname']}")
    end

    #get ip for this host
    host['ip'] = instance['networkInterfaces'][0]['accessConfigs'][0]['natIP']

    #configure ssh
    default_user = host['user']
    host['user'] = 'google_compute'

    disable_se_linux(host, @options)
    copy_ssh_to_root(host, @options)
    (host, @options)
    host['user'] = default_user

    #shut down connection, will reconnect on next exec
    host.close

    @logger.debug("Instance ready: #{host['vmhostname']} for #{host.name}}")
  end
end