How to create VM from existing VM specification

As of version 2.6-RC1 of the EIS RESTful API, we introduced the /<vm_uiid>/spec resource to provide an interface to dump any virtual machine specification in JSON format. The idea behind this, is to deploy a new virtual machine based on a given VM shell or to deploy a new VM with almost the same configuration. You may wonder what might be the difference between taking this approach and requesting a VM clone and basically, deployment time and flexibility. A clone might take longer to deploy and already provisioned disks cannot be shrunken.

Step-by-step guide


  1. Make a request to /v2/vm/<vm_uuid>/spec where vm_uuid is the uuid of the VM you wish to get the specifications:

    http GET "https://vss-api.eis.utoronto.ca/v2/vm/5012ae29-6cfa-c7fd-3d40-46555cbefec0/spec" "Authorization: Bearer $TK"

    If you specify the "-d" flag in httpie, you'll be able to redirect the output to a file as follows:

    http GET "https://vss-api.eis.utoronto.ca/v2/vm/5012ae29-6cfa-c7fd-3d40-46555cbefec0/spec" "Authorization: Bearer $TK" -d 
    HTTP/1.1 200 OK
    Allow: HEAD, OPTIONS, GET
    Connection: keep-alive
    Content-Length: 815
    Content-Type: application/json
    Date: Mon, 03 Oct 2016 14:21:52 GMT
    Server: nginx
    Strict-Transport-Security: max-age=63072000
    X-Content-Type-Options: nosniff
    X-Frame-Options: DENY
    X-RateLimit-Limit: 5000
    X-RateLimit-Remaining: 4985
    X-RateLimit-Reset: 1475506800
    
    Downloading 815.00 B to "spec.json"
    Done. 815.00 B in 0.00056s (1.40 MB/s)
  2. The output file spec.json would look something like:

    {
      "data": {
        "domain": "domain-c5877",
        "description": "Testing python wrapper",
        "admin_phone": "416-577-7061",
        "admin_name": "VSS CI",
        "networks": [
          "dvportgroup-92"
        ],
        "name": "loving_colden",
        "client": "EIS",
        "disks": [
          40.0
        ],
        "inform": "vss-ci@eis.utoronto.ca",
        "built_from": "os_install",
        "memory": 2.0,
        "usage": "Test",
        "folder": "group-v7350",
        "admin_email": "vss-ci@eis.utoronto.ca",
        "os": "ubuntu64Guest",
        "cpu": 2
      },
      "meta": {
        "count": 16,
        "user": "jm",
        "time": "0.37097s"
      },
      "_links": {
        "self": "https://vss-api.eis.utoronto.ca/v2/vm/5012ae29-6cfa-c7fd-3d40-46555cbefec0/spec",
        "vm": "https://vss-api.eis.utoronto.ca/v2/vm/5012ae29-6cfa-c7fd-3d40-46555cbefec0"
      }
    }
  3. By removing the meta and links keys in the file and just leaving a plain JSON object you could use spec.json as your payload for the new vm deployment as follows:

    {
        "domain": "domain-c5877",
        "description": "Testing python wrapper",
        "admin_phone": "416-577-7061",
        "admin_name": "VSS CI",
        "networks": [
          "dvportgroup-92"
        ],
        "client": "EIS",
        "disks": [
          10.0,
          10.0
        ],
        "inform": "vss-ci@eis.utoronto.ca",
        "built_from": "os_install",
        "memory": 1.0,
        "usage": "QA",
        "folder": "group-v7350",
        "admin_email": "vss-ci@eis.utoronto.ca",
        "os": "ubuntu64Guest",
        "cpu": 2
    }
    

    In the previous code block, both keys have been already removed. Also, the specification has been modified by adding one 10G disk, reducing memory to 1GB, updating the usage to QA and removed its name to get a random name.

  4. Submitting a new VM request would be as simple as making a POST request to the /v2/vm resource having spec.json as input.

    http POST https://vss-api.eis.utoronto.ca/v2/vm "Authorization: Bearer $TK" < spec.json