4

I am messing with the example code Google provides and I am looking to determine when an instance is ready to do work. They have an operation 'DONE' status and they have an instance 'RUNNING' status, but there is still a delay until I can actually use the instance. What is the best way to wait for this without waiting for a set time period (because that is a waste for time if the instance is ready sooner)?

I modified their wait_for_operation function so it uses isUp:

# [START wait_for_operation]
def wait_for_operation(compute, project, zone, operation):
    print('Waiting for operation to finish...')
    while True:
        result = compute.zoneOperations().get(
            project=project,
            zone=zone,
            operation=operation).execute()

        if result['status'] == 'DONE':
            print("done.")
            print("result:")
            print(result)
            if 'error' in result:
                raise Exception(result['error'])

            print("before ex")
            instStatus = compute.instances().get(
                project=project,
                zone=zone,
                instance='inst-test1').execute()
            print("after ex")
            if instStatus['status'] == 'RUNNING':

                if isUp("10.xxx.xx.xx"):
                    print("instStatus = ")
                    print(instStatus)
                    return result
                else:
                    print("wasn't replying to ping")
        time.sleep(1)
# [END wait_for_operation]

def isUp(hostname):

    giveFeedback = False

    if platform.system() == "Windows":
        response = os.system("ping "+hostname+" -n 1")
    else:
        response = os.system("ping -c 1 " + hostname)

    isUpBool = False
    if response == 0:
        if giveFeedback:
            print( hostname + 'is up!')
        isUpBool = True
    else:
        if giveFeedback:
            print( hostname + 'is down!')

    return isUpBool

See Matthew's answer for original isUp code: Pinging servers in Python

Most of the other code originated here: https://github.com/GoogleCloudPlatform/python-docs-samples/blob/master/compute/api/create_instance.py

GCP status link: https://cloud.google.com/compute/docs/instances/checking-instance-status

My code works, but is there a better way using instance status or something and avoiding the entire isUp/ping stuff? Seems like my method is a needless workaround.

Obviously I am using Python and this is just messing around code with needless prints etc.

I have a Windows 7 workstation and I don't want to have to require admin rights and a Linux instance.

Edit 1: "by ready to do work", I mean I can send commands to it and it will respond.

mountainclimber11
  • 1,339
  • 1
  • 28
  • 51
  • 1
    This is a great question. It doesn't appear that there's a better way to do it at this point, I mean they even acknowledge in their docs that "RUNNING" doesn't mean it's practically available, but don't offer any sort of workaround. Kudos to you for your creative problem solving. – ingernet Jan 09 '18 at 19:28

2 Answers2

2

Hi I would suggest you to use global operations. https://cloud.google.com/compute/docs/reference/rest/beta/globalOperations/get

from googleapiclient import discovery
from oauth2client.client import GoogleCredentials

credentials = GoogleCredentials.get_application_default()

service = discovery.build('compute', 'beta', credentials=credentials)

# Project ID for this request.
project = 'my-project'  # TODO: Update placeholder value.

# Name of the Operations resource to return.
operation = 'my-operation'  # TODO: Update placeholder value.

request = service.globalOperations().get(project=project, operation=operation)
response = request.execute()

# TODO: Change code below to process the `response` dict:
pprint(response)
khushbu
  • 158
  • 11
  • For anyone still struggling, [this link](https://cloud.google.com/compute/docs/api/how-tos/api-requests-responses#handling_api_responses) is helpful. One can use `global`, `regional` or `zonal` operation's requests to keep a tab on their operation to create a compute instance, stop an existing instance etc. – Yash Nag Apr 03 '21 at 14:16
2

One approach I have used is having a startup script create a field in the instance metadata. You can then check the instance status using your code about and see if the new metadata has been added. You can then avoid pinging the server. An added benefit is if there is not an external ip for the instance, this method still works.

instStatus = compute.instances().get(
                 project=project,
                 zone=zone,
                 instance='inst-test1').execute()
drj
  • 146
  • 2
  • 8