def snapshot(self, instance: GceInstance, clean=True, **kwargs): """Snapshot an instance and generate an image from it. Args: instance: Instance to snapshot clean: run instance clean method before taking snapshot Returns: An image id """ response = self.compute.disks().list(project=self.project, zone=self.zone).execute() instance_disks = [ disk for disk in response['items'] if disk['name'] == instance.name ] if len(instance_disks) > 1: raise Exception( "Snapshotting an image with multiple disks not supported") instance.shutdown() snapshot_name = '{}-image'.format(instance.name) operation = self.compute.images().insert( project=self.project, body={ 'name': snapshot_name, 'sourceDisk': instance_disks[0]['selfLink'], }).execute() raise_on_error(operation) self._wait_for_operation(operation) return 'projects/{}/global/images/{}'.format(self.project, snapshot_name)
def delete(self, wait=True): """Delete the instance. Args: wait: wait for instance to be deleted """ response = self.instance.delete(project=self.project, zone=self.zone, instance=self.instance_id).execute() raise_on_error(response) if wait: self.wait_for_delete()
def start(self, wait=True): """Start the instance. Args: wait: wait for the instance to start. """ response = self.instance.start(project=self.project, zone=self.zone, instance=self.instance_id).execute() raise_on_error(response) if wait: self.wait()
def shutdown(self, wait=True, **kwargs): """Shutdown the instance. Args: wait: wait for the instance to shutdown """ response = self.instance.stop(project=self.project, zone=self.zone, instance=self.instance_id).execute() raise_on_error(response) if wait: self.wait_for_stop()
def delete_image(self, image_id): """Delete an image. Args: image_id: string, id of the image to delete """ api_image_id = self.compute.images().get( project=self.project, image=os.path.basename(image_id)).execute()['id'] response = self.compute.images().delete( project=self.project, image=api_image_id, ).execute() raise_on_error(response)
def launch(self, image_id, instance_type='n1-standard-1', user_data=None, wait=True, **kwargs): """Launch instance on GCE and print the IP address. Args: image_id: string, image ID for instance to use instance_type: string, instance type to launch user_data: string, user-data to pass to instance wait: boolean, wait for instance to come up kwargs: other named arguments to add to instance JSON """ instance_name = 'i{}-{}'.format(next(self.instance_counter), self.tag) config = { 'name': instance_name, 'machineType': 'zones/%s/machineTypes/%s' % ( self.zone, instance_type ), 'disks': [{ 'boot': True, 'autoDelete': True, 'initializeParams': { 'sourceImage': image_id, } }], 'networkInterfaces': [{ 'network': 'global/networks/default', 'accessConfigs': [ {'type': 'ONE_TO_ONE_NAT', 'name': 'External NAT'} ] }], "metadata": { "items": [{ "key": "ssh-keys", "value": "admin:%s" % self.key_pair.public_key_content, }] }, } if user_data: user_metadata = { 'key': 'user-data', 'value': user_data } config['metadata']['items'].append(user_metadata) operation = self.compute.instances().insert( project=self.project, zone=self.zone, body=config ).execute() raise_on_error(operation) self._wait_for_operation(operation, operation_type='zone') result = self.compute.instances().get( project=self.project, zone=self.zone, instance=instance_name, ).execute() raise_on_error(result) self._log.info( result['networkInterfaces'][0]['accessConfigs'][0]['natIP'] ) return self.get_instance(result['id'], name=result['name'])