Class: Google::Cloud::Env::ComputeMetadata

Inherits:
Object
  • Object
show all
Defined in:
lib/google/cloud/env/compute_metadata.rb

Overview

A client for the Google metadata service.

Defined Under Namespace

Classes: Overrides, Response

Constant Summary collapse

DEFAULT_HOST =

The default host for the metadata server

Returns:

  • (String)
"http://169.254.169.254"
DEFAULT_OPEN_TIMEOUT =

The default timeout in seconds for opening http connections

Returns:

  • (Numeric)
0.1
DEFAULT_REQUEST_TIMEOUT =

The default timeout in seconds for request responses

Returns:

  • (Numeric)
0.5
DEFAULT_RETRY_COUNT =

The default number of retries

Returns:

  • (Integer)
2
DEFAULT_RETRY_TIMEOUT =

The default timeout across retries

Returns:

  • (nil)
nil
DEFAULT_RETRY_INTERVAL =

The default interval between retries, in seconds

Returns:

  • (Numeric)
0.5
DEFAULT_WARMUP_TIME =

The default time in seconds to wait for environment warmup.

Returns:

  • (Numeric)
60

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(variables: nil, compute_smbios: nil) ⇒ ComputeMetadata

Create a compute metadata access object.

Parameters:



247
248
249
250
251
252
253
254
255
# File 'lib/google/cloud/env/compute_metadata.rb', line 247

def initialize variables: nil,
               compute_smbios: nil
  @variables = variables || Variables.new
  @compute_smbios = compute_smbios || ComputeSMBIOS.new
  # This mutex protects the overrides and existence settings.
  # Those values won't change within a synchronize block.
  @mutex = Thread::Mutex.new
  reset!
end

Instance Attribute Details

#hostString

The host URL for the metadata server, including http://.

Returns:

  • (String)


262
263
264
# File 'lib/google/cloud/env/compute_metadata.rb', line 262

def host
  @host
end

#overridesOverrides?

The overrides, or nil if overrides are not present. If present, overrides will answer all metadata queries, and actual calls to the metadata server will be blocked.

Returns:



554
555
556
# File 'lib/google/cloud/env/compute_metadata.rb', line 554

def overrides
  @overrides
end

#retry_countInteger?

The default maximum number of times to retry a query for a key. A value of 1 means 2 attempts (i.e. 1 retry). A value of nil means there is no limit to the number of retries, although there could be an overall timeout.

Defaults to DEFAULT_RETRY_COUNT.

Returns:

  • (Integer, nil)


285
286
287
# File 'lib/google/cloud/env/compute_metadata.rb', line 285

def retry_count
  @retry_count
end

#retry_intervalNumeric

The time in seconds between retries. This time includes the time spent by the previous attempt.

Defaults to DEFAULT_RETRY_INTERVAL.

Returns:

  • (Numeric)


306
307
308
# File 'lib/google/cloud/env/compute_metadata.rb', line 306

def retry_interval
  @retry_interval
end

#retry_timeoutNumeric?

The default overall timeout across all retries of a lookup, in seconds. A value of nil means there is no timeout, although there could be a limit to the number of retries.

Defaults to DEFAULT_RETRY_TIMEOUT.

Returns:

  • (Numeric, nil)


296
297
298
# File 'lib/google/cloud/env/compute_metadata.rb', line 296

def retry_timeout
  @retry_timeout
end

#warmup_timeNumeric?

A time in seconds allotted to environment warmup, during which retries will not be ended. This handles certain environments in which the Metadata Server might not be fully awake until some time after application startup. A value of nil disables this warmup period.

Defaults to DEFAULT_WARMUP_TIME.

Returns:

  • (Numeric, nil)


318
319
320
# File 'lib/google/cloud/env/compute_metadata.rb', line 318

def warmup_time
  @warmup_time
end

Instance Method Details

#check_existence(open_timeout: nil, request_timeout: nil, retry_count: :default, retry_timeout: :default) ⇒ :no, ...

Return detailed information about whether we think Metadata is available. If we have not previously confirmed existence one way or another, this could block while trying to contact the server through the given timeouts and retries.

Parameters:

  • open_timeout (Numeric) (defaults to: nil)

    Timeout for opening http connections. Defaults to #open_timeout.

  • request_timeout (Numeric) (defaults to: nil)

    Timeout for entire http requests. Defaults to #request_timeout.

  • retry_count (Integer, nil) (defaults to: :default)

    Number of times to retry. A value of 1 means 2 attempts (i.e. 1 retry). A value of nil indicates retries are limited only by the timeout. Defaults to #retry_count.

  • retry_timeout (Numeric, nil) (defaults to: :default)

    Total timeout for retries. A value of nil indicates no time limit, and retries are limited only by count. Defaults to #retry_timeout.

Returns:

  • (:no)

    if we know the metadata server is not present

  • (:unconfirmed)

    if we believe metadata should be present but we haven't gotten a confirmed response from it. This can happen if SMBIOS says we're on GCE but we can't contact the Metadata Server even through retries.

  • (:confirmed)

    if we have a confirmed response from metadata.



480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
# File 'lib/google/cloud/env/compute_metadata.rb', line 480

def check_existence open_timeout: nil,
                    request_timeout: nil,
                    retry_count: :default,
                    retry_timeout: :default
  current = @existence
  return current if [:no, :confirmed].include? @existence
  begin
    lookup nil,
           open_timeout: open_timeout,
           request_timeout: request_timeout,
           retry_count: retry_count,
           retry_timeout: retry_timeout
  rescue MetadataServerNotResponding
    # Do nothing
  end
  @existence
end

#ensure_existence(timeout: nil) ⇒ :confirmed

Assert that the Metadata Server should be present, and wait for a confirmed connection to ensure it is up. This will generally run at most #warmup_time seconds to wait out the expected maximum warmup time, but a shorter timeout can be provided.

Parameters:

  • timeout (Numeric, nil) (defaults to: nil)

    a timeout in seconds, or nil to wait until we have conclusively decided one way or the other.

Returns:

  • (:confirmed)

    if we were able to confirm connection.

Raises:

  • (MetadataServerNotResponding)

    if we were unable to confirm connection with the Metadata Server, either because the timeout expired or because the server seems to be down



525
526
527
528
529
530
531
# File 'lib/google/cloud/env/compute_metadata.rb', line 525

def ensure_existence timeout: nil
  timeout ||= @startup_time + warmup_time - Process.clock_gettime(Process::CLOCK_MONOTONIC)
  timeout = 1.0 if timeout < 1.0
  check_existence retry_count: nil, retry_timeout: timeout
  raise MetadataServerNotResponding unless @existence == :confirmed
  @existence
end

#existence_immediatenil, ...

The current detailed existence status, without blocking on any attempt to contact the metadata server.

Returns:

  • (nil)

    if we have no information at all yet

  • (:no)

    if we know the metadata server is not present

  • (:unconfirmed)

    if we believe metadata should be present but we haven't gotten a confirmed response from it.

  • (:confirmed)

    if we have a confirmed response from metadata.



508
509
510
# File 'lib/google/cloud/env/compute_metadata.rb', line 508

def existence_immediate
  @existence
end

#expiration_time_of(path, query: nil) ⇒ Numeric, ...

Get the expiration time for the given path. Returns the monotonic time if the data has been retrieved and has an expiration, nil if the data has been retrieved but has no expiration, or false if the data has not yet been retrieved.

Returns:

  • (Numeric, nil, false)


541
542
543
544
545
# File 'lib/google/cloud/env/compute_metadata.rb', line 541

def expiration_time_of path, query: nil
  state = @cache.internal_state [path, query]
  return false unless state[0] == :success
  state[2]
end

#lookup(path, query: nil, open_timeout: nil, request_timeout: nil, retry_count: :default, retry_timeout: :default) ⇒ String?

Look up a particular key from the metadata server and return the data as a string. Could return a cached value if the key has been queried before, otherwise this could block while trying to contact the server through the given timeouts and retries.

This returns the HTTP body as a string, only if the call succeeds. If the key is inaccessible or missing (i.e. the HTTP status was not 200) or does not have the correct Metadata-Flavor header, then nil is returned. If you need more detailed information, use #lookup_response.

Parameters:

  • path (String)

    The key path (e.g. project/project-id)

  • query (Hash{String => String}) (defaults to: nil)

    Any additional query parameters to send with the request.

  • open_timeout (Numeric) (defaults to: nil)

    Timeout for opening http connections. Defaults to #open_timeout.

  • request_timeout (Numeric) (defaults to: nil)

    Timeout for entire http requests. Defaults to #request_timeout.

  • retry_count (Integer, nil) (defaults to: :default)

    Number of times to retry. A value of 1 means 2 attempts (i.e. 1 retry). A value of nil indicates retries are limited only by the timeout. Defaults to #retry_count.

  • retry_timeout (Numeric, nil) (defaults to: :default)

    Total timeout for retries. A value of nil indicates no time limit, and retries are limited only by count. Defaults to #retry_timeout.

Returns:

  • (String)

    the data from the metadata server

  • (nil)

    if the key is not present

Raises:



439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
# File 'lib/google/cloud/env/compute_metadata.rb', line 439

def lookup path,
           query: nil,
           open_timeout: nil,
           request_timeout: nil,
           retry_count: :default,
           retry_timeout: :default
  response = lookup_response path,
                             query: query,
                             open_timeout: open_timeout,
                             request_timeout: request_timeout,
                             retry_count: retry_count,
                             retry_timeout: retry_timeout
  return nil unless response.status == 200 && response.google_flavor?
  response.body
end

#lookup_response(path, query: nil, open_timeout: nil, request_timeout: nil, retry_count: :default, retry_timeout: :default) ⇒ Response

Look up a particular key from the metadata server, and return a full Response object. Could return a cached value if the key has been queried before, otherwise this could block while trying to contact the server through the given timeouts and retries.

This returns a Response object even if the HTTP status is 404, so be sure to check the status code to determine whether the key actually exists. Unlike #lookup, this method does not return nil.

Parameters:

  • path (String)

    The key path (e.g. project/project-id)

  • query (Hash{String => String}) (defaults to: nil)

    Any additional query parameters to send with the request.

  • open_timeout (Numeric) (defaults to: nil)

    Timeout for opening http connections. Defaults to #open_timeout.

  • request_timeout (Numeric) (defaults to: nil)

    Timeout for entire http requests. Defaults to #request_timeout.

  • retry_count (Integer, nil) (defaults to: :default)

    Number of times to retry. A value of 1 means 2 attempts (i.e. 1 retry). A value of nil indicates retries are limited only by the timeout. Defaults to #retry_count.

  • retry_timeout (Numeric, nil) (defaults to: :default)

    Total timeout for retries. A value of nil indicates no time limit, and retries are limited only by count. Defaults to #retry_timeout.

Returns:

  • (Response)

    the data from the metadata server

Raises:



385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
# File 'lib/google/cloud/env/compute_metadata.rb', line 385

def lookup_response path,
                    query: nil,
                    open_timeout: nil,
                    request_timeout: nil,
                    retry_count: :default,
                    retry_timeout: :default
  query = canonicalize_query query
  if @overrides
    @mutex.synchronize do
      return lookup_override path, query if @overrides
    end
  end
  raise MetadataServerNotResponding unless gce_check
  retry_count = self.retry_count if retry_count == :default
  retry_count += 1 if retry_count
  retry_timeout = self.retry_timeout if retry_timeout == :default
  @cache.await [path, query], open_timeout, request_timeout,
               transient_errors: [MetadataServerNotResponding],
               max_tries: retry_count,
               max_time: retry_timeout
end

#open_timeoutNumeric

The timeout for opening http connections in seconds.

Returns:

  • (Numeric)


325
326
327
# File 'lib/google/cloud/env/compute_metadata.rb', line 325

def open_timeout
  connection.options.open_timeout
end

#open_timeout=(timeout) ⇒ Object

The timeout for opening http connections in seconds.

Parameters:

  • timeout (Numeric)


334
335
336
# File 'lib/google/cloud/env/compute_metadata.rb', line 334

def open_timeout= timeout
  connection.options[:open_timeout] = timeout
end

#request_timeoutNumeric

The total timeout for an HTTP request in seconds.

Returns:

  • (Numeric)


343
344
345
# File 'lib/google/cloud/env/compute_metadata.rb', line 343

def request_timeout
  connection.options.timeout
end

#request_timeout=(timeout) ⇒ Object

The total timeout for an HTTP request in seconds.

Parameters:

  • timeout (Numeric)


352
353
354
# File 'lib/google/cloud/env/compute_metadata.rb', line 352

def request_timeout= timeout
  connection.options[:timeout] = timeout
end

#with_overrides(temp_overrides) ⇒ Object

Run the given block with the overrides replaced with the given set (or nil to disable overrides in the block). The original overrides setting is restored at the end of the block. This is used for debugging/testing/mocking.

Parameters:



578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
# File 'lib/google/cloud/env/compute_metadata.rb', line 578

def with_overrides temp_overrides
  old_overrides, old_existence = @mutex.synchronize do
    [@overrides, @existence]
  end
  begin
    @mutex.synchronize do
      @existence = nil
      @overrides = temp_overrides
    end
    yield
  ensure
    @mutex.synchronize do
      @existence = old_existence
      @overrides = old_overrides
    end
  end
end