= Tim

== Summary

Tim is a Rails Engine responsible for Cloud image management.  It
allows clients to create, delete and upload images to a multitude of
Cloud providers.  Tim builds on top of Imagefactory’s cloud
abstraction layer.

Adding the ability for clients to store meta-data (used for searching
and sorting) as well as versioning and support for access control.
Tim wraps all this up in a clean, simply RESTful API.

You can read the full presentation
here[http://www.aeolusproject.org/docs/presentations/2012-nov-conference/tim.odp].

== Configuration

=== Securing Image Factory requests

It is possible to secure Image Factory requests using 2 Legged OAuth.  To use 2
Legged OAuth you must set the OAuth consumer key, consumer secret and url in the
Tim::ImageFactory::Base.config.

Example:

  oauth_config = {:consumer_key => "mock-key",
                  :consumer_secret => "mock-secret",
                  :site => "http://localhost:8075/imagefactory/"}
  Tim::ImageFactory::Base.config = oauth_config

== Running Tests

{<img src="https://secure.travis-ci.org/aeolus-incubator/tim.png"
alt="Build Status" />}[http://travis-ci.org/aeolus-incubator/tim]

Tests are run from the project root directory.  But are run in the
context of the dummy app located under test/dummy.  In order to run
the tests you must first setup dummy app database.

rake db:setup; rake -f test/dummy/Rakefile test:prepare

Once you have done this cd to the project root and run the following:

rake spec

== Running the Dummy app

This will allow you to runn the commands below to test out the engine
in isolation (if mounted in another application, the main difference
will just be where the engine gets mounted, so adjust your url
accordingly).

cd test/dummy; rails s

== API Reference

=== Templates

==== Create Template

Request

  curl -X POST --header "Accept: application/xml" --header "Content-Type: application/xml" --data "
  <template>
     <name>mock</name>
     <os>
       <name>RHEL-6</name>
       <version>1</version>
       <arch>x86_64</arch>
       <install type=\"iso\">
         <iso>http://mockhost/RHELMock1-x86_64-DVD.iso</iso>
       </install>
       <rootpw>password</rootpw>
    </os>
    <description>Mock Template</description>
  </template>
  " http://localhost:3000/tim/templates
 
Response

  Code: 201

  Body:

  <template href='http://localhost:3000/tim/templates/34' id='34'>
    <name>mock</name><os>
        <name>RHEL-6</name>
        <version>1</version>
        <arch>x86_64</arch>
        <install type="iso">
          <iso>http://mockhost/RHELMock1-x86_64-DVD.iso</iso>
        </install>
        <rootpw>password</rootpw>
      </os><description>Mock Template</description>
    <base_images>
    </base_images>
    <custom_content>custom</custom_content>
  </template>


=== Show Template

Request

  curl --header "Accept:application/xml" http://localhost:3000/tim/templates/34

Response

  Code: 200

  Body:

  <template href='http://localhost:3000/tim/templates/34' id='34'>
    <name>mock</name><os>
        <name>RHEL-6</name>
        <version>1</version>
        <arch>x86_64</arch>
        <install type="iso">
          <iso>http://mockhost/RHELMock1-x86_64-DVD.iso</iso>
        </install>
        <rootpw>password</rootpw>
      </os><description>Mock Template</description>
    <base_images>
    </base_images>
    <custom_content>custom</custom_content>
  </template>

=== List Templates

Request

  curl --header "Accept:application/xml" http://localhost:3000/tim/templates

Response

  Code: 200

  Body:

  <templates>
    <template href='http://localhost:3000/tim/templates/33' id='33'></template>
    <template href='http://localhost:3000/tim/templates/35' id='35'></template>
    <template href='http://localhost:3000/tim/templates/36' id='36'></template>
  </templates>

=== Update Template - Not Allowed

=== Delete Template

Request

  curl -X DELETE --header "Accept: application/xml" http://localhost:3000/tim/templates/34

Response

  Code: 204

  Body:

=== Base Images

==== Create Base Image with Template

===== with Existing Template

Request

  curl -X POST --header "Accept: application/xml" --header "Content-Type: application/xml" --data "
  <base_image>
    <name>MyFirstBaseImage</name>
    <description>This is my very first base image</description>
    <template href='http://localhost:3000/tim/templates/3' id='3'></template>
  </base_image>
  " http://localhost:3000/tim/base_images

Response

  Code: 201

  Body:

  <base_image href='http://localhost:3000/tim/base_images/15' id='15'>
    <name>MyFirstBaseImage</name>
    <description>This is my very first base image</description>
    <template href='http://localhost:3000/tim/templates/36' id='36'></template>
    <image_versions>
    </image_versions>
  </base_image>

===== with New Template

Request

  curl -X POST --header "Accept: application/xml" --header "Content-Type: application/xml" --data "
  <base_image>
    <name>MyFirstBaseImage</name>
    <description>This is my very first base image</description>
    <template>
      <name>mock</name>
      <os>
        <name>RHEL-6</name>
        <version>1</version>
        <arch>x86_64</arch>
        <install type=\"iso\">
          <iso>http://mockhost/RHELMock1-x86_64-DVD.iso</iso>
        </install>
        <rootpw>password</rootpw>
      </os>
      <description>Mock Template</description>
    </template>
  </base_image>
  " http://localhost:3000/tim/base_images

Response

  Code: 201

  Body:

  <base_image href='http://localhost:3000/tim/base_images/15' id='15'>
    <name>MyFirstBaseImage</name>
    <description>This is my very first base image</description>
    <template href='http://localhost:3000/tim/templates/36' id='36'></template>
    <image_versions>
    </image_versions>
  </base_image>


==== Create Base Image with Template, a single Image Version with a Single Target Image

Request

  curl -X POST --header "Accept: application/xml" --header "Content-Type: application/xml" --data "
  <base_image>
    <name>MyFirstBaseImage</name>
    <description>ThisIsABaseImage</description>
    <template>
      <name>mock</name>
      <os>
        <name>RHEL-6</name>
        <version>1</version>
        <arch>x86_64</arch>
        <install type=\"iso\">
          <iso>http://mockhost/RHELMock1-x86_64-DVD.iso</iso>
        </install>
        <rootpw>password</rootpw>
      </os>
      <description>Mock Template</description>
    </template>
    <image_versions type='array'>
     <image_version>
        <target_images type='array'>
          <target_image>
            <target>MockSphere</target>
          </target_image>
        </target_images>
      </image_version>
    </image_versions>
  </base_image>
  " http://localhost:3000/tim/base_images

Response

  Code: 201

  Body:

  <base_image href='http://localhost:3000/tim/base_images/16' id='16'>
    <name>MyFirstBaseImage</name>
    <description>ThisIsABaseImage</description>
    <template href='http://localhost:3000/tim/templates/37' id='37'></template>
    <image_versions>
      <image_version href='http://localhost:3000/tim/image_versions/12' id='12'></image_version>
    </image_versions>
  </base_image>

==== Import Image

  curl -X POST --header "Accept: application/xml" --header "Content-Type: application/xml" --data "
  <base_image>
    <name>MyFirstBaseImage</name>
    <description>This is my very first base image</description>
    <template href='http://localhost:3000/tim/templates/3' id='3'></template>
    <import>true</import>
    <image_versions type='array'>
      <image_version>
        <target_images type='array'>
          <target_image>
            <target>ec2</target>
            <provider_images type='array'>
              <provider_image>
                <provider>Amazon EC2</provider>
                <external_image_id>ami-123456</external_image_id>
              </provider_image>
            </provider_images>
          </target_image>
        </target_images>
      </image_version>
    </image_versions>
  </base_image>
  " http://localhost:3000/tim/base_images

==== Show Base Image

Request

  curl --header "Accept: application/xml" http://localhost:3000/tim/base_images/1

Response

  Code: 200

  Body:

  <base_image href='http://localhost:3000/tim/base_images/1' id='1'>
    <name>MyFirstBaseImage</name>
    <description>This is my very first base image</description>
    <image_versions>
      <image_version href='http://localhost:3000/tim/image_versions/1' id='1'></image_version>
    </image_versions>
  </base_image>

==== List Base Images

Request

  curl --header "Accept: application/xml" http://localhost:3000/tim/base_images

Response

  Code: 200

  Body:

  <base_images>
    <base_image href='http://localhost:3000/tim/base_images/1' id='1'></base_image>
    <base_image href='http://localhost:3000/tim/base_images/2' id='2'></base_image>
    <base_image href='http://localhost:3000/tim/base_images/3' id='3'></base_image>
  </base_images>

==== Delete Base Image

Request

  curl -X DELETE --header "Accept: application/xml" http://localhost:3000/tim/base_images/1

Response

  Code: 204

  Body:

=== Image Versions

==== Create Image Version

Request

  curl -X POST --header "Accept: application/xml" --header \
  "Content-Type: application/xml" http://localhost:3000/tim/image_versions --data \
  "<image_version>
    <base_image id='3'></base_image>
  </image_version>"

Response

  Code: 201

  Body:

  <image_version href='http://localhost:3000/tim/image_versions/5' id='5'>
    <base_image href='http://localhost:3000/tim/base_images/1' id='1'></base_image>
    <target_images>
    </target_images>
  </image_version>

==== Show Image Version

Request

  curl --header "Accept: application/xml" http://localhost:3000/tim/image_versions/1

Response

  Code: 200

  Body:

  <image_version href='http://localhost:3000/tim/image_versions/1' id='1'>
    <base_image href='http://localhost:3000/tim/base_images/1' id='1'></base_image>
    <target_images>
    </target_images>
  </image_version>

==== List Image Versions

Request

  curl --header "Accept: application/xml" http://localhost:3000/tim/image_versions

Response

  Code: 200

  Body:

  <image_versions>
    <image_version href='http://localhost:3000/tim/image_versions/1' id='1'></image_version>
    <image_version href='http://localhost:3000/tim/image_versions/2' id='2'></image_version>
    <image_version href='http://localhost:3000/tim/image_versions/3' id='3'></image_version>
  </image_versions>

==== Delete Image Version

Request

  curl -X DELETE--header "Accept: application/xml" http://localhost:3000/tim/image_versions/1

Response

  Code: 204

  Body:

==== Update Image Version

Request

  curl -X PUT --header "Accept: application/xml" --header \
  "Content-Type: application/xml" http://localhost:3000/tim/image_versions/1 --data \
  "<image_version>
    <base_image id='2'></base_image>
  </image_version>"

Response

  Code: 200

  body:

  <image_version href='http://localhost:3000/tim/image_versions/1' id='1'>
    <base_image href='http://localhost:3000/tim/base_images/2' id='2'></base_image>
    <target_images>
    </target_images>
  </image_version>

==== Create Target Image

Request

  curl -X POST --header "Accept: application/xml" --header \
  "Content-Type: application/xml" http://localhost:3000/tim/target_images --data \
  "<target_image>
    <image_version id='2' />
  </target_image>"

Response

  Code: 201

  Body:

<target_image href='http://localhost:3000/tim/target_images/1' id='1'>
  <target>EC2</target>
  <status>BUILDING</status>
  <status_detail></status_detail>
  <progress>0</progress>
  <image_version href='http://localhost:3000/tim/image_versions/2' id='2'></image_version>
  <provider_images></provider_images>
</target_image>

==== Show Target Image

Request

  curl --header "Accept: application/xml" http://localhost:3000/tim/target_images/1

Response

  Code: 200

  Body:

  <target_image href='http://localhost:3000/tim/target_images/1' id='1'>
    <target>EC2</target>
    <status>COMPLETE</status>
    <status_detail></status_detail>
    <progress>100</progress>
    <image_version href='http://localhost:3000/tim/image_versions/2' id='2'></image_version>
    <provider_images></provider_images>
  </target_image>

==== List Target Image

Request

  curl --header "Accept: application/xml" http://localhost:3000/tim/target_images

Response

  Code: 200

  Body:

  <target_images>
    <target_image href='http://localhost:3000/tim/target_images/1' id='1'></target_image>
    <target_image href='http://localhost:3000/tim/target_images/2' id='2'></target_image>
    <target_image href='http://localhost:3000/tim/target_images/3' id='3'></target_image>
  </target_images>

==== Delete Target Image

Request

  curl -X DELETE --header "Accept: application/xml" http://localhost:3000/tim/target_images/1

Response

  Code: 204

  Body:

==== Update Target Image

Request

  curl -X PUT --header "Accept: application/xml" --header \
  "Content-Type: application/xml" http://localhost:3000/tim/target_images/2 --data \
  "<target_image>
    <image_version id='3'></image_version>
  </target_image>"

Response

  Code: 204

==== Create Provider Image

Request

  curl -X POST --header "Accept: application/xml" --header \
  "Content-Type: application/xml" http://localhost:3000/tim/provider_images --data \
  "<provider_image>
    <target_image id='1' />
  </provider_image>"

Response

  Code: 201

  Body:

  <provider_image href='http://localhost:3000/tim/provider_images/85' id='85'>
    <provider>Amazon EC2</provider>
    <external_image_id>ami-123456</external_image_id>
    <snapshot>false</snapshot>
    <status>NEW</status>
    <status_detail></status_detail>
    <progress>0</progress>
    <target_image href='http://localhost:3000/tim/target_images/1' id='1'></target_image>
  </provider_image>

==== Show Provider Image

Request

  curl --header "Accept: application/xml" http://localhost:3000/tim/provider_images/1

Response

  Code: 200

  Body:

  <provider_image href='http://localhost:3000/tim/provider_images/85' id='85'>
    <provider>Amazon EC2</provider>
    <external_image_id>ami-123456</external_image_id>
    <snapshot>false</snapshot>
    <status>NEW</status>
    <status_detail></status_detail>
    <progress>0</progress>
    <target_image href='http://localhost:3000/tim/target_images/1' id='1'></target_image>
  </provider_image>

==== List Provider Images

Request

  curl --header "Accept: application/xml" http://localhost:3000/tim/provider_images

Response

  Code: 200

  Body:

  <provider_images>
    <provider_image href='http://localhost:3000/tim/provider_images/1' id='1'></provider_image>
    <provider_image href='http://localhost:3000/tim/provider_images/2' id='2'></provider_image>
    <provider_image href='http://localhost:3000/tim/provider_images/3' id='3'></provider_image>
  </provider_image>

==== Delete Target Image

Request

  curl -X DELETE --header "Accept: application/xml" http://localhost:3000/tim/provider_images/1

Response

  Code: 204

  Body:

==== Update Target Image

Request

  curl -X PUT --header "Accept: application/xml" --header \
  "Content-Type: application/xml" http://localhost:3000/tim/provider_images/2 --data \
  "<provider_image>
    <target_image id='3'></target_image>
  </provider_image>"

Response

  Code: 204

  Body:

  <provider_image href='http://localhost:3000/tim/provider_images/84' id='84'>
    <provider></provider>
    <external_image_id></external_image_id>
    <snapshot></snapshot>
    <status></status>
    <status_detail></status_detail>
    <progress></progress>
    <target_image href='http://localhost:3000/tim/target_images/3' id='3'></target_image>
  </provider_image>

== License

Image Management Engine is released under the MIT license.