My favorites | Sign in
Project Home Downloads Wiki Issues Source
Search
for
EC2_API_Documentation  
A description of the EC2 API in AppScale
Deprecated, APIs-Documentation, Advanced
Updated Jul 29, 2011 by ckri...@gmail.com

Introduction

While AppScale aims to provide full API compatibility with Google App Engine, there are features we wish to offer users that are not provided by Google App Engine directly. One of these features is the ability to write Google App Engine applications that interact with Amazon EC2 and Eucalyptus. Note that since this is an AppScale API, it does not work if you deploy the same application to Google's resources.

Requirements

The use of this API is recommended for users who have already set up AppScale and have deployed applications to it successfully. Furthermore, as this interface internally uses the Euca2ools, it works with both Amazon EC2 and Eucalytus. Users who are interested in controlling other cloud infrastructures can request that support for them be included in a future release, via the AppScale Community Group.

The API

The AppScale EC2 API mirrors a subset of those provided by Amazon's EC2 API. A sample application, ec2demo, is also included as a demonstration of the functions exhibited in the API.

  • ec2_run_instances(options): Spawns virtual machines with the specified options (interpreted as command-line arguments).
  • ec2_describe_instances(): Returns the status of all machines owned by the current user.
  • ec2_terminate_instances(options): Terminates virtual machines with the specified options (interpreted as command-line arguments).

  • ec2_add_keypair(options): Creates a new SSH key-pair that can be used to log in to virtual machines that are spawned with this key-pair's name.
  • ec2_delete_keypair(options): Deletes the named SSH key-pair from the underlying cloud infrastructure.
  • ec2_describe_availability_zones(options): In Eucalyptus, this returns information relating to the number of virtual machines available to be spawned by users.
  • ec2_describe_images(): Returns information about the virtual machine images, ramdisks, and kernels that are available for use in the system.
  • ec2_reboot_instances(options): Reboots virtual machines with the specified options (interpreted as command-line arguments).

Helper functions are also provided to store and retrieve the user's credentials:

  • write_ec2_creds(cert, pk, ec2_url, s3_url, ec2_access_key, ec2_secret_key): Store the user's cloud credentials for later use, binding them to the given user.
  • remove_ec2_creds(): Remove the user's cloud credentials so that they can no longer be used.

  • get_ec2_cert(): Retrieve the location on the filesystem where the user's EC2 certificate is stored.
  • get_ec2_pk(): Retrieve the location on the filesystem where the user's EC2 private key is stored.
  • get_ec2_url(): Retrieve the URL that should be used for sending EC2 API requests to.
  • get_s3_url(): Retrieve the URL that should be used for sending S3 API requests to.
  • get_ec2_access_key(): Retrieve the user's EC2 access key.
  • get_ec2_secret_key(): Retrieve the user's EC2 secret key.

How to Use the API

Since these functions have all been added to the Google App Engine Users API, users of AppScale 1.4 (which uses Google App Engine 1.3.2) can gain access to these functions with one simple import statement:

from google.appengine.api import users

Note that since we added the EC2 API to the Users API, pulling in the Users API pulls in support for both. Let's look at some examples, from our ec2demo sample application. This application puts a web interface around each of the AppScale EC2 API functions. Note that the API requires that the user be logged in before any API calls can succeed. Users begin by uploading their credentials - here, the application presents a form and saves that data for later use:

  def post(self):
    cert = self.request.get("ec2_cert")
    pk = self.request.get("ec2_pk")
    ec2_url = self.request.get("ec2_url")
    s3_url = self.request.get("s3_url")
    ec2_access_key = self.request.get("ec2_access_key")
    ec2_secret_key = self.request.get("ec2_secret_key")

    user = users.get_current_user()
    response = "Please log in and try again."
    if user:
      users.write_ec2_creds(cert, pk, ec2_url, s3_url, ec2_access_key, ec2_secret_key)
      response = "Your credentials were successfully uploaded."
    self.response.out.write(template.render('index.html',
                                            {'tool': 'Credentials uploaded',
                                             'result': response}))

Now that the user is logged in and has uploaded their credentials, we can call any of the EC2 API's functions. Let's begin by seeing how to show which instances are running for the given user (equivalent to ec2-describe-instances):

class DescribeInstances(webapp.RequestHandler):
  def get(self):
    response = users.ec2_describe_instances().replace("\n", "<br /><br />")
    if response == "":
      response = "No instances are currently running."
    self.response.out.write(template.render('index.html',
                                            {'tool': 'EC2 Describe Instances',
                                             'result': response}))

Let's continue by seeing how a user can run a single machine under a known emi with the instance type m1.large (this example assumes we know the emi, but in your apps you can ask the user or use describe-images). This would be equivalent to ec2-run-instances:

class RunInstances(webapp.RequestHandler):
  def get(self):
    opts = {"machine":"emi-2DA1127F", "t":"m1.large"}
    response = users.ec2_run_instances(opts).replace("\n", "<br /><br />")
    self.response.out.write(template.render('index.html',
                                            {'tool': 'EC2 Run Instances',
                                             'result': response}))

Next, let's terminate the instance we spawned up (assuming we know the instance id of the machine we spawned, which could have been saved from the ec2_run_instances function or retrieved via the ec2_describe_instances function). This would be equivalent to ec2-terminate-instances:

class TerminateInstances(webapp.RequestHandler):
  def get(self):
    opts = {"ids":["i-54EA0A7A"]}
    response = users.ec2_terminate_instances(opts).replace("\n", "<br /><br />")
    self.response.out.write(template.render('index.html',
                                            {'tool': 'EC2 Terminate Instances',
                                             'result': response}))

If you want to allow the user to log in to virtual machines your application is spawning, you'll need to create SSH key-pairs and give it to them for their own use. Let's see how our API does this (equivalent to ec2-add-keypair):

class AddKeypair(webapp.RequestHandler):
  def get(self):
    opts = {"key":"barbar"}
    response = users.ec2_add_keypair(opts).replace("\n", "<br /><br />")
    self.response.out.write(template.render('index.html',
                                            {'tool': 'EC2 Add Keypair',
                                             'result': response}))

Conversely, if you want to remove a key-pair in the system, you can do so via the ec2_delete_keypair function (equivalent to ec2-delete-keypair):

class DeleteKeypair(webapp.RequestHandler):
  def get(self):
    opts = {"key":"barbar"}
    response = users.ec2_delete_keypair(opts).replace("\n", "<br /><br />")
    self.response.out.write(template.render('index.html',
                                            {'tool': 'EC2 Delete Keypair',
                                             'result': response}))

In Eucalyptus, users can determine how many nodes of each instance type are free to be spawned in the system. This can be done in this API as follows (equivalent to ec2-describe-availability-zones verbose):

class DescribeAvailabilityZones(webapp.RequestHandler):
  def get(self):
    opts = {"euca":"verbose"} # for euca, to get the max boxen available
    response = users.ec2_describe_availability_zones(opts).replace("\n", "<br /><br />")
    self.response.out.write(template.render('index.html',
                                            {'tool': 'EC2 Describe Availability Zones',
                                             'result': response}))

Users can also find out all the different virtual machine images, ramdisks, and kernels available to them via the ec2_describe_images function (equivalent to ec2-describe-images):

class DescribeImages(webapp.RequestHandler):
  def get(self):
    response = users.ec2_describe_images().replace("\n", "<br /><br />")
    self.response.out.write(template.render('index.html',
                                            {'tool': 'EC2 Describe Images',
                                             'result': response}))

Finally, if your application needs to reboot an instance for some reason, here's how it can be done (equivalent to ec2-reboot-instances):

class RebootInstances(webapp.RequestHandler):
  def get(self):
    opts = {"ids":["i-558E0968"]}
    response = users.ec2_reboot_instances(opts).replace("\n", "<br /><br />")
    self.response.out.write(template.render('index.html',
                                            {'tool': 'EC2 Reboot Instances',
                                             'result': response}))

This introduction covers the basics of the AppScale EC2 API - feel free to examine and use the ec2demo application bundled with the AppScale Tools for a more complete explanation.


Sign in to add a comment
Powered by Google Project Hosting