Class: Beaker::GoogleCompute

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

Overview

Beaker support for the Google Compute Engine.

Direct Known Subclasses

Google

Constant Summary collapse

SLEEPWAIT =
5
ZOMBIE =

Hours before an instance is considered a zombie

3

Instance Method Summary collapse

Constructor Details

#initialize(google_hosts, options) ⇒ GoogleCompute

Create a new instance of the Google Compute Engine hypervisor object

ONLY be of platforms /centos-*/, /debian-*/, /rhel-*/, /suse-*/. Only supports the Google Compute provided templates.

configuration values @option options [String] :gce_project The Google Compute Project name to connect to

service account keyfile

service account key

Compute service account

used to create instances, defaults to n1-highmem-2

before quiting and exiting with failure

Parameters:

  • google_hosts (<Host>)

    The Array of google hosts to provision, may

  • options (Hash{Symbol=>String})

    The options hash containing

Options Hash (options):

  • :gce_keyfile (String)

    The location of the Google Compute

  • :gce_password (String)

    The password for the Google Compute

  • :gce_email (String)

    The email address for the Google

  • :gce_machine_type (String)

    A Google Compute machine type

  • :timeout (Integer)

    The amount of time to attempt execution



60
61
62
63
64
65
66
67
68
# File 'lib/beaker/hypervisor/google_compute.rb', line 60

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



141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/beaker/hypervisor/google_compute.rb', line 141

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

#find_google_ssh_public_keyObject

Do some reasonable sleuthing on the SSH public key for GCE



14
15
16
17
18
19
20
21
22
23
24
# File 'lib/beaker/hypervisor/google_compute.rb', line 14

def find_google_ssh_public_key
  keyfile = ENV.fetch('BEAKER_gce_ssh_public_key', File.join(ENV['HOME'], '.ssh', 'google_compute_engine.pub'))

  if @options[:gce_ssh_public_key] && !File.exist?(keyfile)
    keyfile = @options[:gce_ssh_public_key]
  end

  raise("Could not find GCE Public SSH Key at '#{keyfile}'") unless File.exist?(keyfile)

  return keyfile
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.



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

def 
  [ {:key => :department, :value => @options[:department]},
    {:key => :project, :value => @options[:project]},
    {:key => :jenkins_build_url, :value => @options[:jenkins_build_url]},
    {:key => :sshKeys, :value => "google_compute:#{File.read(find_google_ssh_public_key).strip}" }
  ].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.



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
# File 'lib/beaker/hypervisor/google_compute.rb', line 158

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 && !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



72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/beaker/hypervisor/google_compute.rb', line 72

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

  test_group_identifier = "beaker-#{start.to_i}-"

  # 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 = test_group_identifier + generate_host_name
  @gce_helper.create_firewall(@firewall, network, start, attempts)

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


  @hosts.each do |host|
    if host[:image]
      gplatform = host[:image]
    elsif host[:platform]
      gplatform = Platform.new(host[:platform])
    else
      raise('You must specify either :image or :platform, or both as necessary')
    end

    img = @gce_helper.get_latest_image(gplatform, start, attempts)

    unique_host_id = test_group_identifier + generate_host_name

    host['diskname'] = unique_host_id
    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'] = unique_host_id
    #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 = 
    unless 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'

    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