compute/api/create_instance.py (133 lines of code) (raw):

#!/usr/bin/env python # Copyright 2015 Google Inc. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. """Example of using the Compute Engine API to create and delete instances. Creates a new compute engine instance and uses it to apply a caption to an image. https://cloud.google.com/compute/docs/tutorials/python-guide For more information, see the README.md under /compute. """ import argparse import os import time import googleapiclient.discovery def list_instances( compute: object, project: str, zone: str, ) -> list: """Lists all instances in the specified zone. Args: compute: an initialized compute service object. project: the Google Cloud project ID. zone: the name of the zone in which the instances should be listed. Returns: A list of instances. """ result = compute.instances().list(project=project, zone=zone).execute() return result["items"] if "items" in result else None # [START compute_create_instance] def create_instance( compute: object, project: str, zone: str, name: str, bucket: str, ) -> str: """Creates an instance in the specified zone. Args: compute: an initialized compute service object. project: the Google Cloud project ID. zone: the name of the zone in which the instances should be created. name: the name of the instance. bucket: the name of the bucket in which the image should be written. Returns: The instance object. """ # Get the latest Debian Jessie image. image_response = ( compute.images() .getFromFamily(project="debian-cloud", family="debian-11") .execute() ) source_disk_image = image_response["selfLink"] # Configure the machine machine_type = "zones/%s/machineTypes/n1-standard-1" % zone startup_script = open( os.path.join(os.path.dirname(__file__), "startup-script.sh") ).read() image_url = "http://storage.googleapis.com/gce-demo-input/photo.jpg" image_caption = "Ready for dessert?" config = { "name": name, "machineType": machine_type, # Specify the boot disk and the image to use as a source. "disks": [ { "boot": True, "autoDelete": True, "initializeParams": { "sourceImage": source_disk_image, }, } ], # Specify a network interface with NAT to access the public # internet. "networkInterfaces": [ { "network": "global/networks/default", "accessConfigs": [{"type": "ONE_TO_ONE_NAT", "name": "External NAT"}], } ], # Allow the instance to access cloud storage and logging. "serviceAccounts": [ { "email": "default", "scopes": [ "https://www.googleapis.com/auth/devstorage.read_write", "https://www.googleapis.com/auth/logging.write", ], } ], # Metadata is readable from the instance and allows you to # pass configuration from deployment scripts to instances. "metadata": { "items": [ { # Startup script is automatically executed by the # instance upon startup. "key": "startup-script", "value": startup_script, }, {"key": "url", "value": image_url}, {"key": "text", "value": image_caption}, {"key": "bucket", "value": bucket}, ] }, } return compute.instances().insert(project=project, zone=zone, body=config).execute() # [END compute_create_instance] def delete_instance( compute: object, project: str, zone: str, name: str, ) -> str: """Deletes an instance. Args: compute: An initialized compute service object. project: The Google Cloud project ID. zone: The name of the zone in which the instances should be deleted. name: The name of the instance. Returns: Execute to delete the instance object. """ return ( compute.instances().delete(project=project, zone=zone, instance=name).execute() ) # [START compute_wait_for_operation] def wait_for_operation( compute: object, project: str, zone: str, operation: str, ) -> dict: """Waits for the given operation to complete. Args: compute: an initialized compute service object. project: the Google Cloud project ID. zone: the name of the zone in which the operation should be executed. operation: the operation ID. Returns: The result of the 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.") if "error" in result: raise Exception(result["error"]) return result time.sleep(1) # [END compute_wait_for_operation] def main( project: str, bucket: str, zone: str, instance_name: str, wait=True, ) -> None: """Runs the demo. Args: project: the Google Cloud project ID. bucket: the name of the bucket in which the image should be written. instance_name: the name of the instance. wait: whether to wait for the operation to complete. Returns: None. """ compute = googleapiclient.discovery.build("compute", "v1") print("Creating instance.") operation = create_instance(compute, project, zone, instance_name, bucket) wait_for_operation(compute, project, zone, operation["name"]) instances = list_instances(compute, project, zone) print(f"Instances in project {project} and zone {zone}:") for instance in instances: print(f' - {instance["name"]}') print( f""" Instance created. It will take a minute or two for the instance to complete work. Check this URL: http://storage.googleapis.com/{bucket}/output.png Once the image is uploaded press enter to delete the instance. """ ) if wait: input() print("Deleting instance.") operation = delete_instance(compute, project, zone, instance_name) wait_for_operation(compute, project, zone, operation["name"]) if __name__ == "__main__": parser = argparse.ArgumentParser( description=__doc__, formatter_class=argparse.RawDescriptionHelpFormatter ) parser.add_argument("project_id", help="Your Google Cloud project ID.") parser.add_argument("bucket_name", help="Your Google Cloud Storage bucket name.") parser.add_argument( "--zone", default="us-central1-f", help="Compute Engine zone to deploy to." ) parser.add_argument("--name", default="demo-instance", help="New instance name.") args = parser.parse_args() main(args.project_id, args.bucket_name, args.zone, args.name)