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'
RHEL_PROJECT =
'rhel-cloud'
SLES_PROJECT =
'sles-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

configuration values

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:

  • options (Hash{Symbol=>String})

    The options hash containing

Options Hash (options):

  • :gce_project (String)

    The Google Compute Project name to

  • :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



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
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 48

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)

  @options[:gce_project] = ENV['BEAKER_gce_project'] if ENV['BEAKER_gce_project']
  @options[:gce_keyfile] = ENV['BEAKER_gce_keyfile'] if ENV['BEAKER_gce_keyfile']

  unless (@options[:gce_keyfile] && File.exist?(@options[:gce_keyfile]))
    @options[:gce_keyfile] = File.join(ENV['HOME'], '.beaker', 'gce', %(#{@options[:gce_project]}.p12))
  end

  @options[:gce_password] = ENV['BEAKER_gce_password'] if ENV['BEAKER_gce_password']
  # This is the GCE default so there's usually not a reason to specify it
  @options[:gce_password] = 'notasecret' unless @options[:gce_password]

  @options[:gce_email] = ENV['BEAKER_gce_email'] if ENV['BEAKER_gce_email']

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

  raise "Could not find gce_keyfile for Google Compute Engine at '#{@options[:gce_keyfile]}'!" unless File.exist?(@options[:gce_keyfile])

  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

Account keyfile to use for authentication

Service Account key

Account we are using to connect

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

connection to the Google Compute API, either through errors or running out of attempts

Parameters:

  • keyfile (String)

    The location of the Google Compute Service

  • password (String)

    The password for the provided Google Compute

  • email (String)

    The email address of the Google Compute Service

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail to create an authenticated



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

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

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

errors or running out of attempts

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

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail create the disk, either through



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

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

the firewall

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

errors or running out of attempts

Parameters:

  • name (String)

    The name of the firewall to create

  • network (Hash)

    The Google Compute network hash in which to create

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail create the firewall, either through



386
387
388
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 386

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

instance

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

errors or running out of attempts

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

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail create the instance, either through



447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 447

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

instances will operate

Returns:

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



94
95
96
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 94

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

will be sent

Returns:

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



85
86
87
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 85

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

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

errors or running out of attempts

Parameters:

  • name (String)

    The name of the disk to delete

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail delete the disk, either through



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

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

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

errors or running out of attempts

Parameters:

  • name (String)

    The name of the firewall to delete

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail delete the firewall, either through



585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 585

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

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

errors or running out of attempts

Parameters:

  • name (String)

    The name of the instance to delete

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail delete the instance, either through



521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 521

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



636
637
638
639
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 636

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



626
627
628
629
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 626

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

disk creation on

Parameters:

  • name (String)

    The name of the disk to create

  • source (String)

    The link to a Google Compute image to base the

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



650
651
652
653
654
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 650

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



616
617
618
619
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 616

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

compared to Time.now to determine how many further code execution attempts remain are willing to allow

through errors or running out of attempts

Parameters:

  • req (Hash)

    A correctly formatted Google Compute request object

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail to execute the request, either



215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 215

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



689
690
691
692
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 689

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 for

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



661
662
663
664
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 661

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

this firewall to

Parameters:

  • name (String)

    The name of the firewall to create

  • network (String)

    The link to the Google Compute network to attach

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



675
676
677
678
679
680
681
682
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 675

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



697
698
699
700
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 697

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.

Only images of the form (platform)-(version)-(version) are currently supported

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

provided platform

through errors or running out of attempts

Parameters:

  • platform (String)

    The platform type to search for an instance of.

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Returns:

  • (Hash)

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

Raises:

  • (Exception)

    Raised if we fail to execute the request, either



262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 262

def get_latest_image(platform, start, attempts)
  #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

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

errors or running out of attempts

Parameters:

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Returns:

  • (Hash)

    The machineType hash

Raises:

  • (Exception)

    Raised if we fail get the machineType, either through



294
295
296
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 294

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 compared to Time.now to determine how many further code execution attempts remain

are willing to allow

errors or running out of attempts

Parameters:

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Returns:

  • (Hash)

    The network hash

Raises:

  • (Exception)

    Raised if we fail get the network, either through



310
311
312
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 310

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



106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 106

def get_platform_project(name)
  if name =~ /debian/
    return DEBIAN_PROJECT
  elsif name =~ /centos/
    return CENTOS_PROJECT
  elsif name =~ /rhel/
    return RHEL_PROJECT
  elsif name =~ /sles/
    return SLES_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



608
609
610
611
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 608

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



758
759
760
761
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 758

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



748
749
750
751
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 748

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

instance to create (indicates cpus and memory size)

instance

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

  • disk (String)

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

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



776
777
778
779
780
781
782
783
784
785
786
787
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 776

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



738
739
740
741
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 738

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



726
727
728
729
730
731
732
733
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 726

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

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

disks, either through errors or running out of attempts

Parameters:

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Returns:

  • (Array[Hash])

    The disks array of hashes

Raises:

  • (Exception)

    Raised if we fail determine the list of existing



345
346
347
348
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 345

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

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

firewalls, either through errors or running out of attempts

Parameters:

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Returns:

  • (Array[Hash])

    The firewalls array of hashes

Raises:

  • (Exception)

    Raised if we fail determine the list of existing



363
364
365
366
367
368
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 363

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

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

instances, either through errors or running out of attempts

Parameters:

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Returns:

  • (Array[Hash])

    The instances array of hashes

Raises:

  • (Exception)

    Raised if we fail determine the list of existing



327
328
329
330
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 327

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



792
793
794
795
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 792

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

information about

Parameters:

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

    (default) The name of the network to access

Returns:

  • (Hash)

    A correctly formatted Google Compute request hash



708
709
710
711
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 708

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



716
717
718
719
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 716

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



124
125
126
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 124

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

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

either through errors or running out of attempts

Parameters:

  • version (String)

    The version of the Google Compute API to discover

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail to discover the Google Compute API,



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

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

given instance

key and a value.

compared to Time.now to determine how many further code execution attempts remain

are willing to allow

errors or running out of attempts

Parameters:

  • name (String)

    The name of the instance to add metadata to

  • fingerprint (String)

    A hash of the metadata’s contents of the

  • data (Array<Hash>)

    An array of hashes. Each hash should have a

  • start (Integer)

    The time when we started code execution, it is

  • attempts (Integer)

    The total amount of attempts to execute that we

Raises:

  • (Exception)

    Raised if we fail to add metadata, either through



488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
# File 'lib/beaker/hypervisor/google_compute_helper.rb', line 488

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