Class: Beaker::GoogleComputeHelper

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

Overview

Beaker helper module for doing API level Google Compute Engine interaction.

Defined Under Namespace

Classes: GoogleComputeError

Constant Summary collapse

SLEEPWAIT =
5
AUTH_URL =
'https://www.googleapis.com/auth/compute'
API_VERSION =
'v1'
BASE_URL =
"https://www.googleapis.com/compute/#{API_VERSION}/projects/"
CENTOS_PROJECT =
'centos-cloud'
DEBIAN_PROJECT =
'debian-cloud'
DEFAULT_ZONE_NAME =
'us-central1-a'
DEFAULT_MACHINE_TYPE =
'n1-highmem-2'
DEFAULT_DISK_SIZE =
25

Instance Method Summary collapse

Constructor Details

#initialize(options) ⇒ GoogleComputeHelper

Create a new instance of the Google Compute Engine helper object

Parameters:

  • 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



32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 32

def initialize(options)
  @options = options
  @logger = options[:logger]
  try = 1
  attempts = @options[:timeout].to_i / SLEEPWAIT
  start = Time.now

  set_client(Beaker::Version::STRING)
  set_compute_api(API_VERSION, start, attempts)

  raise 'You must specify a gce_project for Google Compute Engine instances!' unless @options[:gce_project]
  raise 'You must specify a gce_keyfile for Google Compute Engine instances!' unless @options[:gce_keyfile]
  raise 'You must specify a gce_password for Google Compute Engine instances!' unless @options[:gce_password]
  raise 'You must specify a gce_email for Google Compute Engine instances!' unless @options[:gce_email]

  authenticate(@options[:gce_keyfile], @options[:gce_password], @options[:gce_email], start, attempts)
end

Instance Method Details

#authenticate(keyfile, password, email, start, attempts) ⇒ Object

Creates an authenticated connection to the Google Compute Engine API

Parameters:

  • keyfile (String)

    The location of the Google Compute Service Account keyfile to use for authentication

  • password (String)

    The password for the provided Google Compute Service Account key

  • email (String)

    The email address of the Google Compute Service Account we are using to connect

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail to create an authenticated connection to the Google Compute API, either through errors or running out of attempts



113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 113

def authenticate(keyfile, password, email, start, attempts)
  # OAuth authentication, using the service account
  key = Google::APIClient::PKCS12.load_key(keyfile, password)
   = Google::APIClient::JWTAsserter.new(
      email,
      AUTH_URL,
      key)
  try = (Time.now - start) / SLEEPWAIT
  while try <= attempts
    begin
      @client.authorization = .authorize
      @logger.debug("Authorized to use Google Compute")
      return
    rescue => e
      @logger.debug("Failed to authorize to use Google Compute")
      if try >= attempts
        raise e
      end
    end
    try += 1
  end
end

#create_disk(name, img, start, attempts) ⇒ Object

Create a Google Compute disk on the current connection

Parameters:

  • name (String)

    The name of the disk to create

  • img (Hash)

    The Google Compute image to use for instance creation

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail create the disk, either through errors or running out of attempts



270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 270

def create_disk(name, img, start, attempts)
  #create a new boot disk for this instance
  disk = execute( disk_insert_req( name, img['selfLink'] ), start, attempts )

  status = ''
  try = (Time.now - start) / SLEEPWAIT
  while status !~ /READY/ and try <= attempts
    begin
      disk = execute( disk_get_req( name ), start, attempts )
      status = disk['status']
    rescue GoogleComputeError => e
      @logger.debug("Waiting for #{name} disk creation")
      sleep(SLEEPWAIT)
    end
    try += 1
  end
  if status == ''
    raise "Unable to create disk #{name}"
  end
  disk
end

#create_firewall(name, network, start, attempts) ⇒ Object

Create a Google Compute firewall on the current connection

Parameters:

  • name (String)

    The name of the firewall to create

  • network (Hash)

    The Google Compute network hash in which to create the firewall

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail create the firewall, either through errors or running out of attempts



259
260
261
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 259

def create_firewall(name, network, start, attempts)
  execute( firewall_insert_req( name, network['selfLink'] ), start, attempts )
end

#create_instance(name, img, machineType, disk, start, attempts) ⇒ Object

Create a Google Compute instance on the current connection

Parameters:

  • name (String)

    The name of the instance to create

  • img (Hash)

    The Google Compute image to use for instance creation

  • machineType (Hash)

    The Google Compute machineType

  • disk (Hash)

    The Google Compute disk to attach to the newly created instance

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail create the instance, either through errors or running out of attempts



301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 301

def create_instance(name, img, machineType, disk, start, attempts)
  #add a new instance of the image
  instance = execute( instance_insert_req( name, img['selfLink'], machineType['selfLink'], disk['selfLink'] ), start, attempts)
  status = ''
  try = (Time.now - start) / SLEEPWAIT
  while status !~ /RUNNING/ and try <= attempts
    begin
      instance = execute( instance_get_req( name ), start, attempts )
      status = instance['status']
    rescue GoogleComputeError => e
      @logger.debug("Waiting for #{name} instance creation")
      sleep(SLEEPWAIT)
    end
    try += 1
  end
  if status == ''
    raise "Unable to create instance #{name}"
  end
  instance
end

#default_networkObject

Determines the default Google Compute network based upon defaults and options

Returns:

  • The full URL to the default network in which Google Compute instances will operate



58
59
60
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 58

def default_network
  BASE_URL + @options[:gce_project] + '/global/networks/default'
end

#default_zoneObject

Determines the default Google Compute zone based upon options and defaults

Returns:

  • The full URL to the default zone in which Google Compute requests will be sent



52
53
54
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 52

def default_zone
  BASE_URL + @options[:gce_project] + '/global/zones/' + DEFAULT_ZONE_NAME
end

#delete_disk(name, start, attempts) ⇒ Object

Delete a Google Compute disk on the current connection

Parameters:

  • name (String)

    The name of the disk to delete

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail delete the disk, either through errors or running out of attempts



380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 380

def delete_disk(name, start, attempts)
  result = execute( disk_delete_req( name ), start, attempts )
  #ensure deletion of disk
  try = (Time.now - start) / SLEEPWAIT
  while try <= attempts
    begin
      disk = execute( disk_get_req( name ), start, attempts )
      @logger.debug("Waiting for #{name} disk deletion")
      sleep(SLEEPWAIT)
    rescue GoogleComputeError => e
      @logger.debug("#{name} disk deleted!")
      return
    end
    try += 1
  end
  @logger.debug("#{name} disk was not removed before timeout, may still exist")
end

#delete_firewall(name, start, attempts) ⇒ Object

Delete a Google Compute firewall on the current connection

Parameters:

  • name (String)

    The name of the firewall to delete

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail delete the firewall, either through errors or running out of attempts



404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 404

def delete_firewall(name, start, attempts)
  result = execute( firewall_delete_req( name ), start, attempts )
  #ensure deletion of disk
  try = (Time.now - start) / SLEEPWAIT
  while try <= attempts
    begin
      firewall = execute( firewall_get_req( name ), start, attempts )
      @logger.debug("Waiting for #{name} firewall deletion")
      sleep(SLEEPWAIT)
    rescue GoogleComputeError => e
      @logger.debug("#{name} firewall deleted!")
      return
    end
    try += 1
  end
  @logger.debug("#{name} firewall was not removed before timeout, may still exist")
end

#delete_instance(name, start, attempts) ⇒ Object

Delete a Google Compute instance on the current connection

Parameters:

  • name (String)

    The name of the instance to delete

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail delete the instance, either through errors or running out of attempts



356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 356

def delete_instance(name, start, attempts)
  result = execute( instance_delete_req( name ), start, attempts )
  #ensure deletion of instance
  try = (Time.now - start) / SLEEPWAIT
  while try <= attempts
    begin
      result = execute( instance_get_req( name ), start, attempts )
      @logger.debug("Waiting for #{name} instance deletion")
      sleep(SLEEPWAIT)
    rescue GoogleComputeError => e
      @logger.debug("#{name} instance deleted!")
      return
    end
    try += 1
  end
  @logger.debug("#{name} instance was not removed before timeout, may still exist")
end

#disk_delete_req(name) ⇒ Hash

Create a Google Compute disk delete request

Parameters:

  • name (String)

    The name of the disk delete

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



449
450
451
452
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 449

def disk_delete_req(name)
  { :api_method  => @compute.disks.delete,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'disk' => name } }
end

#disk_get_req(name) ⇒ Hash

Create a Google Compute get disk request

Parameters:

  • name (String)

    The name of the disk to query for

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



441
442
443
444
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 441

def disk_get_req(name)
  { :api_method  => @compute.disks.get,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'disk' => name } }
end

#disk_insert_req(name, source) ⇒ Hash

Create a Google Compute disk create request

Parameters:

  • name (String)

    The name of the disk to create

  • source (String)

    The link to a Google Compute image to base the disk creation on

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



458
459
460
461
462
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 458

def disk_insert_req(name, source)
  { :api_method  => @compute.disks.insert,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'sourceImage' => source },
    :body_object => { 'name' => name, 'sizeGb' => DEFAULT_DISK_SIZE } }
end

#disk_list_reqHash

Create a Google Compute list all disks request

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



433
434
435
436
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 433

def disk_list_req
  { :api_method  => @compute.disks.list,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME } }
end

#execute(req, start, attempts) ⇒ Object

Executes a provided Google Compute request using a previously configured and authenticated Google Compute client connection

Parameters:

  • req (Hash)

    A correctly formatted Google Compute request object

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail to execute the request, either through errors or running out of attempts



142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 142

def execute req, start, attempts
  last_error = parsed = nil
  try = (Time.now - start) / SLEEPWAIT
  while try <= attempts
    begin
      result = @client.execute(req)
      parsed = JSON.parse(result.body)
      if not result.success?
        error_code = parsed["error"] ? parsed["error"]["code"] : 0
        if error_code == 404
          raise GoogleComputeError, "Resource Not Found: #{result.body}"
        elsif error_code == 400
          raise GoogleComputeError, "Bad Request: #{result.body}"
        else
          raise GoogleComputeError, "Error attempting Google Compute API execute: #{result.body}"
        end
      end
      return parsed
    #retry errors
    rescue Faraday::Error::ConnectionFailed => e
      @logger.debug "ConnectionFailed attempting Google Compute execute command"
      try += 1
      last_error = e
    end
  end
  #we only get down here if we've used up all our tries
  raise last_error
end

#firewall_delete_req(name) ⇒ Hash

Create a Google Compute delete firewall request

Parameters:

  • name (String)

    The name of the firewall to delete

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



488
489
490
491
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 488

def firewall_delete_req(name)
  { :api_method  => @compute.firewalls.delete,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'firewall' => name } }
end

#firewall_get_req(name) ⇒ Hash

Create a Google Compute get firewall request

Parameters:

  • name (String)

    The name of the firewall to query fo

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



467
468
469
470
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 467

def firewall_get_req(name)
  { :api_method  => @compute.firewalls.get,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'firewall' => name } }
end

#firewall_insert_req(name, network) ⇒ Hash

Create a Google Compute insert firewall request, open ports 443, 8140 and 61613

Parameters:

  • name (String)

    The name of the firewall to create

  • network (String)

    The link to the Google Compute network to attach this firewall to

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



476
477
478
479
480
481
482
483
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 476

def firewall_insert_req(name, network)
  { :api_method  => @compute.firewalls.insert,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME },
    :body_object => { 'name' => name,
                      'allowed'=> [ { 'IPProtocol' => 'tcp', "ports" =>  [ '443', '8140', '61613', '8080', '8081' ]} ],
                      'network'=> network,
                      'sourceRanges' => [ "0.0.0.0/0" ] } }
end

#firewall_list_reqHash

Create a Google Compute list firewall request

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



495
496
497
498
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 495

def firewall_list_req()
  { :api_method  => @compute.firewalls.list,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME } }
end

#get_latest_image(platform, start, attempts) ⇒ Hash

Determines the latest image available for the provided platform name. We currently only support debian-7 and centos-6 platforms.

Parameters:

  • platform (String)

    The platform type to search for an instance of, must be one of /debian-7-.*/ or /centos-6-.*/

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Returns:

  • (Hash)

    The image hash of the latest, non-deprecated image for the provided platform

Raises:

  • (Exception)

    Raised if we fail to execute the request, either through errors or running out of attempts



178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 178

def get_latest_image(platform, start, attempts)
  #use the platform version numbers instead of codenames
  platform = platform.with_version_number
  #break up my platform for information
  platform_name, platform_version, platform_extra_info = platform.split('-', 3)
  #find latest image to use
  result = execute( image_list_req(get_platform_project(platform_name)), start, attempts )
  images = result["items"]
  #reject images of the wrong version of the given platform
  images.delete_if { |image| image['name'] !~ /^#{platform_name}-#{platform_version}/}
  #reject deprecated images
  images.delete_if { |image| image['deprecated']}
  #find a match based upon platform type
  if images.length != 1
    raise "Unable to find a single matching image for #{platform}, found #{images}"
  end
  images[0]
end

#get_machineType(start, attempts) ⇒ Hash

Determines the Google Compute machineType object based upon the selected gce_machine_type option

Parameters:

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Returns:

  • (Hash)

    The machineType hash

Raises:

  • (Exception)

    Raised if we fail get the machineType, either through errors or running out of attempts



203
204
205
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 203

def get_machineType(start, attempts)
  execute( machineType_get_req, start, attempts )
end

#get_network(start, attempts) ⇒ Hash

Determines the Google Compute network object in use for the current connection

Parameters:

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Returns:

  • (Hash)

    The network hash

Raises:

  • (Exception)

    Raised if we fail get the network, either through errors or running out of attempts



213
214
215
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 213

def get_network(start, attempts)
  execute( network_get_req, start, attempts)
end

#get_platform_project(name) ⇒ Object

Determines the Google Compute project which contains bases instances of type name

Parameters:

  • name (String)

    The platform type to search for

Returns:

  • The Google Compute project name

Raises:

  • (Exception)

    If the provided platform type name is unsupported



66
67
68
69
70
71
72
73
74
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 66

def get_platform_project(name)
  if name =~ /debian/
    return DEBIAN_PROJECT
  elsif name =~ /centos/
    return CENTOS_PROJECT
  else
    raise "Unsupported platform for Google Compute Engine: #{name}"
  end
end

#image_list_req(name) ⇒ Hash

Create a Google Compute list all images request

Parameters:

  • name (String)

    The Google Compute project name to query

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



426
427
428
429
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 426

def image_list_req(name)
  { :api_method  => @compute.images.list,
    :parameters  => { 'project' => name } }
end

#instance_delete_req(name) ⇒ Hash

Create a Google Compute instance delete request

Parameters:

  • name (String)

    The name of the instance to delete

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



545
546
547
548
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 545

def instance_delete_req(name)
  { :api_method  => @compute.instances.delete,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'instance' => name } }
end

#instance_get_req(name) ⇒ Hash

Create a Google Compute get instance request

Parameters:

  • name (String)

    The name of the instance to query for

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



537
538
539
540
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 537

def instance_get_req(name)
  { :api_method  => @compute.instances.get,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'instance' => name } }
end

#instance_insert_req(name, image, machineType, disk) ⇒ Hash

Create a Google Compute instance create request

Parameters:

  • name (String)

    The name of the instance to create

  • image (String)

    The link to the image to use for instance create

  • machineType (String)

    The link to the type of Google Compute instance to create (indicates cpus and memory size)

  • disk (String)

    The link to the disk to be used by the newly created instance

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



556
557
558
559
560
561
562
563
564
565
566
567
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 556

def instance_insert_req(name, image, machineType, disk)
  { :api_method  => @compute.instances.insert,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME },
    :body_object => { 'name' => name,
                      'image' => image,
                      'zone' => default_zone,
                      'machineType' => machineType,
                      'disks' => [ { 'source' => disk,
                                     'type' => 'PERSISTENT', 'boot' => 'true'} ],
                                     'networkInterfaces' => [ { 'accessConfigs' => [{ 'type' => 'ONE_TO_ONE_NAT', 'name' => 'External NAT' }],
                                                                'network' => default_network } ] } }
end

#instance_list_reqHash

Create a Google Compute list instance request

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



529
530
531
532
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 529

def instance_list_req
  { :api_method  => @compute.instances.list,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME } }
end

#instance_setMetadata_req(name, fingerprint, data) ⇒ Hash

Set tags on a Google Compute instance

Parameters:

  • data (Array<String>)

    An array of tags to be added to an instance

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



518
519
520
521
522
523
524
525
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 518

def (name, fingerprint, data)
  { :api_method => @compute.instances.,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'instance' => name },
    :body_object => { 'kind' => 'compute#metadata',
                      'fingerprint'  => fingerprint,
                      'items' => data }
  }
end

#list_disks(start, attempts) ⇒ Array[Hash]

Determines a list of existing Google Compute disks

Parameters:

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Returns:

  • (Array[Hash])

    The disks array of hashes

Raises:

  • (Exception)

    Raised if we fail determine the list of existing disks, either through errors or running out of attempts



234
235
236
237
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 234

def list_disks(start, attempts)
  disks = execute( disk_list_req(), start, attempts )
  disks["items"]
end

#list_firewalls(start, attempts) ⇒ Array[Hash]

Determines a list of existing Google Compute firewalls

Parameters:

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Returns:

  • (Array[Hash])

    The firewalls array of hashes

Raises:

  • (Exception)

    Raised if we fail determine the list of existing firewalls, either through errors or running out of attempts



245
246
247
248
249
250
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 245

def list_firewalls(start, attempts)
  result = execute( firewall_list_req(), start, attempts )
  firewalls = result["items"]
  firewalls.delete_if{|f| f['name'] =~ /default-allow-internal|default-ssh/}
  firewalls
end

#list_instances(start, attempts) ⇒ Array[Hash]

Determines a list of existing Google Compute instances

Parameters:

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Returns:

  • (Array[Hash])

    The instances array of hashes

Raises:

  • (Exception)

    Raised if we fail determine the list of existing instances, either through errors or running out of attempts



223
224
225
226
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 223

def list_instances(start, attempts)
  instances = execute( instance_list_req(), start, attempts )
  instances["items"]
end

#machineType_get_reqHash

Create a Google Compute machineType get request

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



571
572
573
574
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 571

def machineType_get_req()
  { :api_method => @compute.machine_types.get,
    :parameters => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'machineType' => @options[:gce_machine_type] || DEFAULT_MACHINE_TYPE } }
end

#network_get_req(name = 'default') ⇒ Hash

Create a Google Compute get network request

Parameters:

  • name (String) (defaults to: 'default')

    (default) The name of the network to access information about

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



503
504
505
506
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 503

def network_get_req(name = 'default')
  { :api_method  => @compute.networks.get,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'network' => name } }
end

#operation_get_req(name) ⇒ Hash

Create a Google Compute zone operation request

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



510
511
512
513
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 510

def operation_get_req(name)
  { :api_method  => @compute.zone_operations.get,
    :parameters  => { 'project' => @options[:gce_project], 'zone' => DEFAULT_ZONE_NAME, 'operation' => name } }
end

#set_client(version) ⇒ Object

Create the Google APIClient object which will be used for accessing the Google Compute API

Parameters:

  • version

    The version number of Beaker currently running



78
79
80
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 78

def set_client(version)
  @client = Google::APIClient.new({:application_name => "Beaker", :application_version => version})
end

#set_compute_api(version, start, attempts) ⇒ Object

Discover the currently active Google Compute API

Parameters:

  • version (String)

    The version of the Google Compute API to discover

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail to discover the Google Compute API, either through errors or running out of attempts



88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 88

def set_compute_api version, start, attempts
  try = (Time.now - start) / SLEEPWAIT
  while try <= attempts
    begin
      @compute = @client.discovered_api('compute', version)
      @logger.debug("Google Compute API discovered")
      return
    rescue => e
      @logger.debug("Failed to discover Google Compute API")
      if try >= attempts
        raise e
      end
    end
    try += 1
  end
end

#setMetadata_on_instance(name, fingerprint, data, start, attempts) ⇒ Object

Add key/value pairs to a Google Compute instance on the current connection

Parameters:

  • name (String)

    The name of the instance to add metadata to

  • fingerprint (String)

    A hash of the metadata’s contents of the given instance

  • data (Array<Hash>)

    An array of hashes. Each hash should have a key and a value.

  • start (Integer)

    The time when we started code execution, it is compared to Time.now to determine how many further code execution attempts remain

  • attempts (Integer)

    The total amount of attempts to execute that we are willing to allow

Raises:

  • (Exception)

    Raised if we fail to add metadata, either through errors or running out of attempts



330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 330

def (name, fingerprint, data, start, attempts)
  zone_operation = execute( ( name, fingerprint, data), start, attempts )
  status = ''
  try = (Time.now - start) / SLEEPWAIT
  while status !~ /DONE/ and try <= attempts
    begin
      operation = execute( operation_get_req( zone_operation['name'] ), start, attempts )
      status = operation['status']
    rescue GoogleComputeError => e
      @logger.debug("Waiting for tags to be added to #{name}")
      sleep(SLEEPWAIT)
    end
    try += 1
  end
  if status == ''
    raise "Unable to set metaData (#{tags.to_s}) on #{name}"
  end
  zone_operation
end