API tutorial: Difference between revisions

From Grid5000
Jump to navigation Jump to search
No edit summary
 
(7 intermediate revisions by 2 users not shown)
Line 11: Line 11:
Other aspects (how to access, versioning, content negotiating, authentication, …) of the API are mentioned in the [[API|general page about the Grid'5000 API]].
Other aspects (how to access, versioning, content negotiating, authentication, …) of the API are mentioned in the [[API|general page about the Grid'5000 API]].


The goal of this tutorial is not to present all the possibilities of the API, a specification of the API (which is more precise and complete) is available for each variant (''stable'' and ''sid'') here: https://api.grid5000.fr/doc/
The goal of this tutorial is not to present all the possibilities of the API, a specification of the API (which is more precise and complete) is available at https://api.grid5000.fr/doc/


{{Note|text=In this tutorial <code class=command>curl</code> will be launched without requiring credentials (as if we were on a Grid'5000 ''frontend''). Credentials are not needed from within Grid'5000, but are required from outside, as described [[API#Authentication|here]].}}
{{Note|text=In this tutorial <code class=command>curl</code> will be launched without requiring credentials (as if we were on a Grid'5000 ''frontend''). Credentials are not needed from within Grid'5000, but are required from outside, as described [[API#Authentication|here]].}}
Line 19: Line 19:
The ''Reference API'' exposes Grid'5000's reference-repository: the single source of truth about sites, clusters, nodes, and network topology (the platform inventory on steroids).
The ''Reference API'' exposes Grid'5000's reference-repository: the single source of truth about sites, clusters, nodes, and network topology (the platform inventory on steroids).


For instance, <code class=path>/sites/rennes</code> is a resource exposed by the ''Reference API''. If you would like to get the representation of this resource as it is returned by the <code>3.0</code> version of the Grid'5000 API, the URL to enter in your HTTP client would be:
For instance, <code class=path>/sites/rennes</code> is a resource exposed by the ''Reference API''. If you would like to get the representation of this resource as it is returned by the <code>stable</code> version of the Grid'5000 API, the URL to enter in your HTTP client would be:


  curl https://api.grid5000.fr/3.0/sites/rennes
  curl https://api.grid5000.fr/stable/sites/rennes


As another example, to get the list of sites, the URL will be:
As another example, to get the list of sites, the URL will be:


  curl https://api.grid5000.fr/3.0/sites
  curl https://api.grid5000.fr/stable/sites


For a particular cluster:
For a particular cluster:


  curl https://api.grid5000.fr/3.0/sites/rennes/clusters/paravance/
  curl https://api.grid5000.fr/stable/sites/rennes/clusters/paravance/


=== Versioning ===
=== Versioning ===
Line 39: Line 39:
; List versions
; List versions


Each URL resources can be suffixed with <code class=path>/versions</code> to get a list of versions (Git commit). For example:
Each URL resources can be suffixed with <code class=path>/versions</code> to get a list of versions. For example:


  $ curl https://api.grid5000.fr/3.0/sites/rennes/clusters/versions?pretty
  $ curl https://api.grid5000.fr/stable/sites/rennes/clusters/versions?pretty
   "total": 392,
   "total": 392,
   "offset": 0,
   "offset": 0,
Line 54: Line 54:
         {
         {
           "rel": "self",
           "rel": "self",
           "href": "/3.0/sites/rennes/clusters/versions/68fdd053e6767ba2da1edf5105f57ff7b963f91f",
           "href": "/stable/sites/rennes/clusters/versions/68fdd053e6767ba2da1edf5105f57ff7b963f91f",
           "type": "application/vnd.grid5000.item+json"
           "type": "application/vnd.grid5000.item+json"
         },
         },
         {
         {
           "rel": "parent",
           "rel": "parent",
           "href": "/3.0/sites/rennes/clusters",
           "href": "/stable/sites/rennes/clusters",
           "type": "application/vnd.grid5000.item+json"
           "type": "application/vnd.grid5000.item+json"
         }
         }
Line 71: Line 71:
       "type": "version",
       "type": "version",


And following the logic behind the API, each item can be accessed, like <code class=path>https://api.grid5000.fr/3.0/sites/rennes/clusters/versions/68fdd053e6767ba2da1edf5105f57ff7b963f91f</code>
And following the logic behind the API, each item can be accessed, like <code class=path>https://api.grid5000.fr/stable/sites/rennes/clusters/versions/68fdd053e6767ba2da1edf5105f57ff7b963f91f</code>


Git commits can be referenced with there ''uid'', also known as SHA id.
; Get resources for a version
; Get resources for a version


To get a resource description for specific version of the ''reference-repository'', the <code class=path>version</code> *GET* parameter can be added to the request. For example, to get on old description of the node ''dahu-29'' of Grenoble:
To get a resource description for specific version of the ''reference-repository'', the GET parameter <code class=path>version</code> can be added to the request with the desired SHA id. For example, to get on previous description of the node ''dahu-29'' of Grenoble corresponding the a version referenced with the ''0c1396da414cca75faadd7b52fbb4fea11667213'' SHA id, run:


  $ curl "https://api.grid5000.fr/3.0/sites/grenoble/clusters/dahu/nodes/dahu-29?pretty&version=0c1396da414cca75faadd7b52fbb4fea11667213"
  $ curl "https://api.grid5000.fr/stable/sites/grenoble/clusters/dahu/nodes/dahu-29?pretty&version=0c1396da414cca75faadd7b52fbb4fea11667213"


; Get resources at a given time
; Get resources at a given time
Line 84: Line 85:
With a UNIX timestamp:
With a UNIX timestamp:


  $ curl "https://api.grid5000.fr/3.0/sites/grenoble/clusters/dahu/nodes/dahu-29.json?pretty&timestamp=1606400407"
  $ curl "https://api.grid5000.fr/stable/sites/grenoble/clusters/dahu/nodes/dahu-29.json?pretty&timestamp=1606400407"


=== Platform state and reproducibility ===
=== Platform state and reproducibility ===
Line 92: Line 93:
At the moment, there is no automatic association between an experiment and the state of used nodes.
At the moment, there is no automatic association between an experiment and the state of used nodes.


The latest commit of the reference repository is exposed as the version returned by the Grid'5000 API. You are advised to retrieve it and keep it for later references to insure traceability and help reproducibility.
The current state (latest git commit identified by its SHA id) of the reference repository is exposed as the version returned by the Grid'5000 API. You are advised to retrieve it and keep it for later references to insure traceability and help reproducibility.


To do so, you can retrieve the version value provided by  
To do so, you can retrieve the version value provided by  
  curl  https://api.grid5000.fr/3.0/
  curl  https://api.grid5000.fr/stable/
Eg.
Eg.
  {
  {
Line 105: Line 106:
     {
     {
       "rel": "network_equipments",
       "rel": "network_equipments",
       "href": "/3.0/network_equipments",
       "href": "/stable/network_equipments",
       "type": "application/vnd.grid5000.collection+json"
       "type": "application/vnd.grid5000.collection+json"
     },
     },
     {
     {
       "rel": "sites",
       "rel": "sites",
       "href": "/3.0/sites",
       "href": "/stable/sites",
       "type": "application/vnd.grid5000.collection+json"
       "type": "application/vnd.grid5000.collection+json"
     },
     },
Line 116: Line 117:
       "rel": "self",
       "rel": "self",
       "type": "application/vnd.grid5000.item+json",
       "type": "application/vnd.grid5000.item+json",
       "href": "/3.0/"
       "href": "/stable/"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "type": "application/vnd.grid5000.item+json",
       "type": "application/vnd.grid5000.item+json",
       "href": "/3.0/"
       "href": "/stable/"
     },
     },
     {
     {
       "rel": "version",
       "rel": "version",
       "type": "application/vnd.grid5000.item+json",
       "type": "application/vnd.grid5000.item+json",
       "href": "/3.0/versions/8eefb84931378cb1bed16b99675516ca5dd0536c"
       "href": "/stable/versions/8eefb84931378cb1bed16b99675516ca5dd0536c"
     },
     },
     {
     {
       "rel": "versions",
       "rel": "versions",
       "type": "application/vnd.grid5000.collection+json",
       "type": "application/vnd.grid5000.collection+json",
       "href": "/3.0/versions"
       "href": "/stable/versions"
     },
     },
     {
     {
       "rel": "users",
       "rel": "users",
       "type": "application/vnd.grid5000.collection+json",
       "type": "application/vnd.grid5000.collection+json",
       "href": "/3.0/users"
       "href": "/stable/users"
     }
     }
   ]
   ]
  }
  }


And save the "sha" property.
And save the SHA id of the version property.


Or just retrieve it with  
Or just retrieve it with  
  curl -s  https://api.grid5000.fr/3.0/ | jq ".version"
  curl -s  https://api.grid5000.fr/stable/ | jq ".version"
  "8eefb84931378cb1bed16b99675516ca5dd0536c"
  "8eefb84931378cb1bed16b99675516ca5dd0536c"


That "sha" can be used later to retrieve the information about the former state of the platform, as explained in the previous section.
That SHA id can be later used to retrieve the information about the former state of the platform, as explained in the previous section.


== Jobs API ==
== Jobs API ==
Line 159: Line 160:
For instance, let's submit a job with 2 nodes of the ''grenoble'' site, for 2 hours. And let's say we want to launch a useless script that just sleeps forever when the job starts:
For instance, let's submit a job with 2 nodes of the ''grenoble'' site, for 2 hours. And let's say we want to launch a useless script that just sleeps forever when the job starts:


  $ curl -i https://api.grid5000.fr/3.0/sites/grenoble/jobs?pretty -X POST -H'Content-Type: application/json' -d '{"resources": "nodes=2,walltime=02:00", "command": "while(true); do sleep 5; echo \"awake\"; done"}'
  $ curl -i https://api.grid5000.fr/stable/sites/grenoble/jobs?pretty -X POST -H'Content-Type: application/json' -d '{"resources": "nodes=2,walltime=02:00", "command": "while(true); do sleep 5; echo \"awake\"; done"}'
  HTTP/1.1 201 Created
  HTTP/1.1 201 Created
  Date: Thu, 03 Dec 2020 14:47:57 GMT
  Date: Thu, 03 Dec 2020 14:47:57 GMT
  Server: thin
  Server: thin
  Content-Type: application/json; charset=utf-8
  Content-Type: application/json; charset=utf-8
  Location: https://api.grid5000.fr/3.0/sites/grenoble/jobs/1965464
  Location: https://api.grid5000.fr/stable/sites/grenoble/jobs/1965464
  Content-Length: 818
  Content-Length: 818
  ETag: W/"40668ba7ef11e54db1ef39adc09bddcf"
  ETag: W/"40668ba7ef11e54db1ef39adc09bddcf"
Line 200: Line 201:
     {
     {
       "rel": "self",
       "rel": "self",
       "href": "/3.0/sites/grenoble/jobs/1965464",
       "href": "/stable/sites/grenoble/jobs/1965464",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "href": "/3.0/sites/grenoble",
       "href": "/stable/sites/grenoble",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     }
     }
Line 216: Line 217:
  }
  }


Status code is <code>201 Created</code>, which means a new job resource has been created. You can find the URI of that new job resource in the Location HTTP header: https://api.grid5000.fr/3.0/sites/grenoble/jobs/1965464
Status code is <code>201 Created</code>, which means a new job resource has been created. You can find the URI of that new job resource in the Location HTTP header: https://api.grid5000.fr/stable/sites/grenoble/jobs/1965464
The job is in the ''waiting'' state at first, but then will go to the ''running'' state.
The job is in the ''waiting'' state at first, but then will go to the ''running'' state.


Line 244: Line 245:
     {
     {
       "rel": "self",
       "rel": "self",
       "href": "/3.0/sites/grenoble/jobs/1965464",
       "href": "/stable/sites/grenoble/jobs/1965464",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "href": "/3.0/sites/grenoble",
       "href": "/stable/sites/grenoble",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     }
     }
Line 337: Line 338:
Since the previous job is doing nothing, we can delete it to free the nodes for other users. To do this, just send a http request with the <code>DELETE</code> method on the job URI:  
Since the previous job is doing nothing, we can delete it to free the nodes for other users. To do this, just send a http request with the <code>DELETE</code> method on the job URI:  


  $ curl  -i -X DELETE https://api.grid5000.fr/3.0/sites/grenoble/jobs/1965464
  $ curl  -i -X DELETE https://api.grid5000.fr/stable/sites/grenoble/jobs/1965464
  HTTP/1.1 202 Accepted
  HTTP/1.1 202 Accepted
  Date: Thu, 03 Dec 2020 15:17:18 GMT
  Date: Thu, 03 Dec 2020 15:17:18 GMT
Line 348: Line 349:
  Referrer-Policy: strict-origin-when-cross-origin
  Referrer-Policy: strict-origin-when-cross-origin
  X-Oar-Info: Deleting the job = 1965464 ...REGISTERED. The job(s) [ 1965464 ] will be deleted in the near future.
  X-Oar-Info: Deleting the job = 1965464 ...REGISTERED. The job(s) [ 1965464 ] will be deleted in the near future.
  Location: https://api.grid5000.fr/3.0/sites/grenoble/jobs/1965464
  Location: https://api.grid5000.fr/stable/sites/grenoble/jobs/1965464
  Content-Type: text/plain; charset=utf-8
  Content-Type: text/plain; charset=utf-8
  Cache-Control: no-cache
  Cache-Control: no-cache
Line 370: Line 371:
An OAR job of type deploy is required to perform a deployment. The following creates the job:
An OAR job of type deploy is required to perform a deployment. The following creates the job:


  $ curl https://api.grid5000.fr/3.0/sites/grenoble/jobs -X POST -H 'Content-Type: application/json' -d '{"resources": "nodes=2", "types": ["deploy"], "command": "sleep 3600"}'
  $ curl https://api.grid5000.fr/stable/sites/grenoble/jobs -X POST -H 'Content-Type: application/json' -d '{"resources": "nodes=2", "types": ["deploy"], "command": "sleep 3600"}'


If everything goes well, you’ll receive a <code>201 created</code>:
If everything goes well, you’ll receive a <code>201 created</code>:
Line 378: Line 379:
  Server: thin
  Server: thin
  Content-Type: application/json; charset=utf-8
  Content-Type: application/json; charset=utf-8
  Location: https://api.grid5000.fr/3.0/sites/grenoble/jobs/1965452
  Location: https://api.grid5000.fr/stable/sites/grenoble/jobs/1965452
  Content-Length: 625
  Content-Length: 625
  X-Info: Use `?pretty=yes` or add the HTTP header `X-Rack-PrettyJSON: yes` if you want pretty output.
  X-Info: Use `?pretty=yes` or add the HTTP header `X-Rack-PrettyJSON: yes` if you want pretty output.
Line 412: Line 413:
     {
     {
       "rel": "self",
       "rel": "self",
       "href": "/3.0/sites/grenoble/jobs/1965460",
       "href": "/stable/sites/grenoble/jobs/1965460",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "href": "/3.0/sites/grenoble",
       "href": "/stable/sites/grenoble",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     }
     }
Line 427: Line 428:
Using the job URI given in the '''Location''' header. We have to wait for the job to be running: It is possible to poll the Jobs API until the job is in ''running'' state:
Using the job URI given in the '''Location''' header. We have to wait for the job to be running: It is possible to poll the Jobs API until the job is in ''running'' state:


  $ curl -s https://api.grid5000.fr/3.0/sites/grenoble/jobs/1965460 | jq '.assigned_nodes,.state'
  $ curl -s https://api.grid5000.fr/stable/sites/grenoble/jobs/1965460 | jq '.assigned_nodes,.state'
  [
  [
   "dahu-13.grenoble.grid5000.fr",
   "dahu-13.grenoble.grid5000.fr",
Line 441: Line 442:


  $ export SSH_PUBLIC_KEY=`cat ~/.ssh/id_rsa.pub` # replace with your Grid'5000 public key.
  $ export SSH_PUBLIC_KEY=`cat ~/.ssh/id_rsa.pub` # replace with your Grid'5000 public key.
  $ curl -i https://api.grid5000.fr/3.0/sites/grenoble/deployments -H'Content-Type: application/json' -d \
  $ curl -i https://api.grid5000.fr/stable/sites/grenoble/deployments -H'Content-Type: application/json' -d \
  '{"nodes": ["dahu-13.grenoble.grid5000.fr", "dahu-17.grenoble.grid5000.fr"], "environment": "debian10-x64-min", "key": "$SSH_PUBLIC_KEY"}'
  '{"nodes": ["dahu-13.grenoble.grid5000.fr", "dahu-17.grenoble.grid5000.fr"], "environment": "debian11-min", "key": "$SSH_PUBLIC_KEY"}'


A 201 created response should be returned:
A 201 created response should be returned:
Line 450: Line 451:
  Server: thin
  Server: thin
  Content-Type: application/json; charset=utf-8
  Content-Type: application/json; charset=utf-8
  Location: https://api.grid5000.fr/3.0/sites/grenoble/deployments/D-d54fca72-ef30-47cc-bf6a-54b6223fd7e4
  Location: https://api.grid5000.fr/stable/sites/grenoble/deployments/D-d54fca72-ef30-47cc-bf6a-54b6223fd7e4
  Content-Length: 612
  Content-Length: 612
  X-Info: Use `?pretty=yes` or add the HTTP header `X-Rack-PrettyJSON: yes` if you want pretty output.
  X-Info: Use `?pretty=yes` or add the HTTP header `X-Rack-PrettyJSON: yes` if you want pretty output.
Line 467: Line 468:
   "site_uid": "grenoble",
   "site_uid": "grenoble",
   "user_uid": "auser",
   "user_uid": "auser",
   "environment": "debian10-x64-min",
   "environment": "debian11-min",
   "status": "processing",
   "status": "processing",
   "key": "https://api.grid5000.fr/3.0/sites/grenoble/files/auser-key-c213083a4ce7e58bc2052f03c144a06afdf6cc4a",
   "key": "https://api.grid5000.fr/stable/sites/grenoble/files/auser-key-c213083a4ce7e58bc2052f03c144a06afdf6cc4a",
   "nodes": [
   "nodes": [
     "dahu-13.grenoble.grid5000.fr",
     "dahu-13.grenoble.grid5000.fr",
Line 479: Line 480:
     {
     {
       "rel": "self",
       "rel": "self",
       "href": "/3.0/sites/grenoble/deployments/D-9bd9e783-41fb-4b09-87e0-38522df086d8",
       "href": "/stable/sites/grenoble/deployments/D-9bd9e783-41fb-4b09-87e0-38522df086d8",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "href": "/3.0/sites/grenoble",
       "href": "/stable/sites/grenoble",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     }
     }
Line 492: Line 493:
Again, we can use the URI given in the '''Location''' header to poll the deployment status :
Again, we can use the URI given in the '''Location''' header to poll the deployment status :


  $ curl -s https://api.grid5000.fr/3.0/sites/grenoble/deployments/D-9bd9e783-41fb-4b09-87e0-38522df086d8 | jq .status
  $ curl -s https://api.grid5000.fr/stable/sites/grenoble/deployments/D-9bd9e783-41fb-4b09-87e0-38522df086d8 | jq .status
  "processing"
  "processing"


Later:
Later:


  $ curl -s https://api.grid5000.fr/3.0/sites/grenoble/deployments/D-9bd9e783-41fb-4b09-87e0-38522df086d8 | jq .status
  $ curl -s https://api.grid5000.fr/stable/sites/grenoble/deployments/D-9bd9e783-41fb-4b09-87e0-38522df086d8 | jq .status
  "processing"
  "processing"


Line 510: Line 511:
We start by reserving two nodes and a local kavlan (VLAN of type ''local'') on the Grenoble site, using the ''Jobs API'':
We start by reserving two nodes and a local kavlan (VLAN of type ''local'') on the Grenoble site, using the ''Jobs API'':


  $ curl -i https://api.grid5000.fr/3.0/sites/grenoble/jobs?pretty -X POST -H 'Content-Type: application/json' -d "{\"resources\":\"{type='kavlan-local'}/vlan=1,nodes=2\", \"types\": [\"deploy\"], \"command\": \"sleep 3600\"}"
  $ curl -i https://api.grid5000.fr/stable/sites/grenoble/jobs?pretty -X POST -H 'Content-Type: application/json' -d "{\"resources\":\"{type='kavlan-local'}/vlan=1,nodes=2\", \"types\": [\"deploy\"], \"command\": \"sleep 3600\"}"


  HTTP/1.1 201 Created
  HTTP/1.1 201 Created
Line 522: Line 523:
  Referrer-Policy: strict-origin-when-cross-origin
  Referrer-Policy: strict-origin-when-cross-origin
  Content-Type: application/json; charset=utf-8
  Content-Type: application/json; charset=utf-8
  Location: https://api.grid5000.fr/3.0/sites/grenoble/jobs/1967224
  Location: https://api.grid5000.fr/stable/sites/grenoble/jobs/1967224
  Content-Length: 791
  Content-Length: 791
  ETag: W/"eda5d6c6671165250f54b1d3aa933601"
  ETag: W/"eda5d6c6671165250f54b1d3aa933601"
Line 558: Line 559:
     {
     {
       "rel": "self",
       "rel": "self",
       "href": "/3.0/sites/grenoble/jobs/1967227",
       "href": "/stable/sites/grenoble/jobs/1967227",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "href": "/3.0/sites/grenoble",
       "href": "/stable/sites/grenoble",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     }
     }
Line 575: Line 576:
We can then look at the job state (is it running?), the assigned nodes, and VLAN number:
We can then look at the job state (is it running?), the assigned nodes, and VLAN number:


  $ curl -s https://api.grid5000.fr/3.0/sites/grenoble/jobs/1967224 | jq '.state,.assigned_nodes,.resources_by_type.vlans'
  $ curl -s https://api.grid5000.fr/stable/sites/grenoble/jobs/1967224 | jq '.state,.assigned_nodes,.resources_by_type.vlans'
  "running"
  "running"
  [
  [
Line 589: Line 590:
The VLAN we reserved can also be found using the ''Vlans API'' (in addition to with the ''Jobs API''):
The VLAN we reserved can also be found using the ''Vlans API'' (in addition to with the ''Jobs API''):


  $ curl https://api.grid5000.fr/3.0/sites/grenoble/vlans/users/auser?pretty
  $ curl https://api.grid5000.fr/stable/sites/grenoble/vlans/users/auser?pretty
  {
  {
   "uid": "auser",
   "uid": "auser",
Line 599: Line 600:
     {
     {
       "rel": "self",
       "rel": "self",
       "href": "/3.0/sites/grenoble/vlans/users/auser",
       "href": "/stable/sites/grenoble/vlans/users/auser",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "href": "/3.0/sites/grenoble/vlans/users",
       "href": "/stable/sites/grenoble/vlans/users",
       "type": "application/vnd.grid5000.collection+json"
       "type": "application/vnd.grid5000.collection+json"
     }
     }
Line 614: Line 615:
The status of a given user for a specific VLAN can be found with this query:
The status of a given user for a specific VLAN can be found with this query:


$ curl https://api.grid5000.fr/3.0/sites/grenoble/vlans/2/users/auser?pretty
$ curl https://api.grid5000.fr/stable/sites/grenoble/vlans/2/users/auser?pretty
  {
  {
   "uid": "auser",
   "uid": "auser",
Line 621: Line 622:
     {
     {
       "rel": "self",
       "rel": "self",
       "href": "/3.0/sites/grenoble/vlans/2/users/auser",
       "href": "/stable/sites/grenoble/vlans/2/users/auser",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "href": "/3.0/sites/grenoble/vlans/2/users",
       "href": "/stable/sites/grenoble/vlans/2/users",
       "type": "application/vnd.grid5000.collection+json"
       "type": "application/vnd.grid5000.collection+json"
     }
     }
Line 633: Line 634:


And a list of users with rights on a VLAN is given by the following query:
And a list of users with rights on a VLAN is given by the following query:
  curl https://api.grid5000.fr/3.0/sites/grenoble/vlans/2/users</code>
  curl https://api.grid5000.fr/stable/sites/grenoble/vlans/2/users</code>
(in fact with the current configuration on Grid'5000 only one user can have rights on a VLAN).
(in fact with the current configuration on Grid'5000 only one user can have rights on a VLAN).


Line 640: Line 641:
To add our nodes to the reserved VLAN, we have to make a POST request to the API:
To add our nodes to the reserved VLAN, we have to make a POST request to the API:


  $ curl -X POST https://api.grid5000.fr/3.0/sites/grenoble/vlans/2/nodes?pretty -H "Content-Type: application/json" -d '["dahu-5.grenoble.grid5000.fr","dahu-6.grenoble.grid5000.fr"]'
  $ curl -X POST https://api.grid5000.fr/stable/sites/grenoble/vlans/2/nodes?pretty -H "Content-Type: application/json" -d '["dahu-5.grenoble.grid5000.fr","dahu-6.grenoble.grid5000.fr"]'
  {
  {
   "dahu-5.grenoble.grid5000.fr": {
   "dahu-5.grenoble.grid5000.fr": {
Line 654: Line 655:
We can see them by listing nodes in the VLAN:
We can see them by listing nodes in the VLAN:


  $ curl https://api.grid5000.fr/3.0/sites/grenoble/vlans/2/nodes?pretty
  $ curl https://api.grid5000.fr/stable/sites/grenoble/vlans/2/nodes?pretty
  {
  {
   "total": 2,
   "total": 2,
Line 665: Line 666:
         {
         {
           "rel": "self",
           "rel": "self",
           "href": "/3.0/sites/grenoble/vlans/nodes/dahu-5.grenoble.grid5000.fr",
           "href": "/stable/sites/grenoble/vlans/nodes/dahu-5.grenoble.grid5000.fr",
           "type": "application/vnd.grid5000.item+json"
           "type": "application/vnd.grid5000.item+json"
         },
         },
         {
         {
           "rel": "parent",
           "rel": "parent",
           "href": "/3.0/sites/grenoble/vlans/nodes",
           "href": "/stable/sites/grenoble/vlans/nodes",
           "type": "application/vnd.grid5000.collection+json"
           "type": "application/vnd.grid5000.collection+json"
         }
         }
Line 681: Line 682:
         {
         {
           "rel": "self",
           "rel": "self",
           "href": "/3.0/sites/grenoble/vlans/nodes/dahu-6.grenoble.grid5000.fr",
           "href": "/stable/sites/grenoble/vlans/nodes/dahu-6.grenoble.grid5000.fr",
           "type": "application/vnd.grid5000.item+json"
           "type": "application/vnd.grid5000.item+json"
         },
         },
         {
         {
           "rel": "parent",
           "rel": "parent",
           "href": "/3.0/sites/grenoble/vlans/nodes",
           "href": "/stable/sites/grenoble/vlans/nodes",
           "type": "application/vnd.grid5000.collection+json"
           "type": "application/vnd.grid5000.collection+json"
         }
         }
Line 695: Line 696:
     {
     {
       "rel": "self",
       "rel": "self",
       "href": "/3.0/sites/grenoble/vlans/2/nodes",
       "href": "/stable/sites/grenoble/vlans/2/nodes",
       "type": "application/vnd.grid5000.collection+json"
       "type": "application/vnd.grid5000.collection+json"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "href": "/3.0/sites/grenoble/vlans/2",
       "href": "/stable/sites/grenoble/vlans/2",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     }
     }
Line 708: Line 709:
A list of all the known nodes in Kavlan and their current VLAN assignation is also available, with the following query:
A list of all the known nodes in Kavlan and their current VLAN assignation is also available, with the following query:


  $ curl https://api.grid5000.fr/3.0/sites/grenoble/vlans/nodes?pretty
  $ curl https://api.grid5000.fr/stable/sites/grenoble/vlans/nodes?pretty
  {
  {
   "total": 52,
   "total": 52,
Line 719: Line 720:
         {
         {
           "rel": "self",
           "rel": "self",
           "href": "/3.0/sites/grenoble/vlans/nodes/dahu-1.grenoble.grid5000.fr",
           "href": "/stable/sites/grenoble/vlans/nodes/dahu-1.grenoble.grid5000.fr",
           "type": "application/vnd.grid5000.item+json"
           "type": "application/vnd.grid5000.item+json"
         },
         },
         {
         {
           "rel": "parent",
           "rel": "parent",
           "href": "/3.0/sites/grenoble/vlans/nodes",
           "href": "/stable/sites/grenoble/vlans/nodes",
           "type": "application/vnd.grid5000.collection+json"
           "type": "application/vnd.grid5000.collection+json"
         }
         }
Line 735: Line 736:
         {
         {
           "rel": "self",
           "rel": "self",
           "href": "/3.0/sites/grenoble/vlans/nodes/dahu-10.grenoble.grid5000.fr",
           "href": "/stable/sites/grenoble/vlans/nodes/dahu-10.grenoble.grid5000.fr",
           "type": "application/vnd.grid5000.item+json"
           "type": "application/vnd.grid5000.item+json"
         },
         },
         {
         {
           "rel": "parent",
           "rel": "parent",
           "href": "/3.0/sites/grenoble/vlans/nodes",
           "href": "/stable/sites/grenoble/vlans/nodes",
           "type": "application/vnd.grid5000.collection+json"
           "type": "application/vnd.grid5000.collection+json"
         }
         }
Line 753: Line 754:
If we don't want to use it, we can stop it with a simple PUT query:
If we don't want to use it, we can stop it with a simple PUT query:


  curl -X PUT https://api.grid5000.fr/3.0/sites/grenoble/vlans/2/dhcpd -H "Content-Type: application/json" -d '{"action":"stop"}'
  curl -X PUT https://api.grid5000.fr/stable/sites/grenoble/vlans/2/dhcpd -H "Content-Type: application/json" -d '{"action":"stop"}'


== Metrics APIs ==
== Metrics APIs ==
Line 765: Line 766:
=== Cluster status ===
=== Cluster status ===


  $ curl https://api.grid5000.fr/3.0/sites/grenoble/clusters/yeti/status?pretty
  $ curl https://api.grid5000.fr/stable/sites/grenoble/clusters/yeti/status?pretty
   "uid": 1607009770,
   "uid": 1607009770,
   "links": [
   "links": [
     {
     {
       "rel": "self",
       "rel": "self",
       "href": "/3.0/sites/grenoble/clusters/yeti/status",
       "href": "/stable/sites/grenoble/clusters/yeti/status",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     },
     },
     {
     {
       "rel": "parent",
       "rel": "parent",
       "href": "/3.0/sites/grenoble/clusters/yeti",
       "href": "/stable/sites/grenoble/clusters/yeti",
       "type": "application/vnd.grid5000.item+json"
       "type": "application/vnd.grid5000.item+json"
     }
     }
Line 815: Line 816:
=== Site status ===
=== Site status ===


  $ curl https://api.grid5000.fr/3.0/sites/grenoble/clusters/status?pretty
  $ curl https://api.grid5000.fr/stable/sites/grenoble/clusters/status?pretty


On the site level, the ''Status API'' gives the status of the nodes, disks, vlans, and subnets OAR resources.
On the site level, the ''Status API'' gives the status of the nodes, disks, vlans, and subnets OAR resources.

Latest revision as of 14:50, 12 October 2022

Note.png Note

This page is actively maintained by the Grid'5000 team. If you encounter problems, please report them (see the Support page). Additionally, as it is a wiki page, you are free to make minor corrections yourself if needed. If you would like to suggest a more fundamental change, please contact the Grid'5000 team.

Introduction

This tutorial will help you learning how to interact with Grid'5000's API, using simple example (with the curl tool to interact with the API, and sometimes jq to parse the JSON result). We target people who want a remote and programmatic access to the Grid'5000 tools in order to monitor nodes, submit jobs, and deploy environments.

Other aspects (how to access, versioning, content negotiating, authentication, …) of the API are mentioned in the general page about the Grid'5000 API.

The goal of this tutorial is not to present all the possibilities of the API, a specification of the API (which is more precise and complete) is available at https://api.grid5000.fr/doc/

Note.png Note

In this tutorial curl will be launched without requiring credentials (as if we were on a Grid'5000 frontend). Credentials are not needed from within Grid'5000, but are required from outside, as described here.

Reference API

The Reference API exposes Grid'5000's reference-repository: the single source of truth about sites, clusters, nodes, and network topology (the platform inventory on steroids).

For instance, /sites/rennes is a resource exposed by the Reference API. If you would like to get the representation of this resource as it is returned by the stable version of the Grid'5000 API, the URL to enter in your HTTP client would be:

curl https://api.grid5000.fr/stable/sites/rennes

As another example, to get the list of sites, the URL will be:

curl https://api.grid5000.fr/stable/sites

For a particular cluster:

curl https://api.grid5000.fr/stable/sites/rennes/clusters/paravance/

Versioning

Grid'5000's reference-repository (platform state/description) is stored in a central Grid5000 Git repository hosted at https://gitlab.inria.fr/grid5000/reference-repository and mirrored at https://github.com/grid5000/reference-repository.

The API offers the possibility to list the latest changes in the Grid'5000 infrastructure or to fetch resources description for a specific version or at a specific time.

List versions

Each URL resources can be suffixed with /versions to get a list of versions. For example:

$ curl https://api.grid5000.fr/stable/sites/rennes/clusters/versions?pretty
 "total": 392,
 "offset": 0,
 "items": [
   {
     "uid": "68fdd053e6767ba2da1edf5105f57ff7b963f91f",
     "date": "Thu, 03 Dec 2020 09:56:38 GMT",
     "message": "[all] upgrade postinstall",
     "author": "Author",
     "type": "version",
     "links": [
       {
         "rel": "self",
         "href": "/stable/sites/rennes/clusters/versions/68fdd053e6767ba2da1edf5105f57ff7b963f91f",
         "type": "application/vnd.grid5000.item+json"
       },
       {
         "rel": "parent",
         "href": "/stable/sites/rennes/clusters",
         "type": "application/vnd.grid5000.item+json"
       }
     ]
   },
   {
     "uid": "5d9b32e3f6f0eb63608274d028994e99ea4c0698",
     "date": "Fri, 20 Nov 2020 17:20:33 GMT",
     "message": "[all] Add prometheus metrics to all clusters",
     "author": "Author",
     "type": "version",

And following the logic behind the API, each item can be accessed, like https://api.grid5000.fr/stable/sites/rennes/clusters/versions/68fdd053e6767ba2da1edf5105f57ff7b963f91f

Git commits can be referenced with there uid, also known as SHA id.

Get resources for a version

To get a resource description for specific version of the reference-repository, the GET parameter version can be added to the request with the desired SHA id. For example, to get on previous description of the node dahu-29 of Grenoble corresponding the a version referenced with the 0c1396da414cca75faadd7b52fbb4fea11667213 SHA id, run:

$ curl "https://api.grid5000.fr/stable/sites/grenoble/clusters/dahu/nodes/dahu-29?pretty&version=0c1396da414cca75faadd7b52fbb4fea11667213"
Get resources at a given time

It is also possible to Get the reference-repository at a specific time, using the date or timestamp *GET* parameters. With a UNIX timestamp:

$ curl "https://api.grid5000.fr/stable/sites/grenoble/clusters/dahu/nodes/dahu-29.json?pretty&timestamp=1606400407"

Platform state and reproducibility

The platform characteristics can change over time and affect performances or other sensible elements, thus it is important to keep a reference of the state of the nodes you used at the time of an experiment.

At the moment, there is no automatic association between an experiment and the state of used nodes.

The current state (latest git commit identified by its SHA id) of the reference repository is exposed as the version returned by the Grid'5000 API. You are advised to retrieve it and keep it for later references to insure traceability and help reproducibility.

To do so, you can retrieve the version value provided by

curl  https://api.grid5000.fr/stable/

Eg.

{
  "type": "grid",
  "uid": "grid5000",
  "version": "8eefb84931378cb1bed16b99675516ca5dd0536c",
  "timestamp": 1631889100,
  "links": [
    {
      "rel": "network_equipments",
      "href": "/stable/network_equipments",
      "type": "application/vnd.grid5000.collection+json"
    },
    {
      "rel": "sites",
      "href": "/stable/sites",
      "type": "application/vnd.grid5000.collection+json"
    },
    {
      "rel": "self",
      "type": "application/vnd.grid5000.item+json",
      "href": "/stable/"
    },
    {
      "rel": "parent",
      "type": "application/vnd.grid5000.item+json",
      "href": "/stable/"
    },
    {
      "rel": "version",
      "type": "application/vnd.grid5000.item+json",
      "href": "/stable/versions/8eefb84931378cb1bed16b99675516ca5dd0536c"
    },
    {
      "rel": "versions",
      "type": "application/vnd.grid5000.collection+json",
      "href": "/stable/versions"
    },
    {
      "rel": "users",
      "type": "application/vnd.grid5000.collection+json",
      "href": "/stable/users"
    }
  ]
}

And save the SHA id of the version property.

Or just retrieve it with

curl -s  https://api.grid5000.fr/stable/ | jq ".version"
"8eefb84931378cb1bed16b99675516ca5dd0536c"

That SHA id can be later used to retrieve the information about the former state of the platform, as explained in the previous section.

Jobs API

The Jobs API allows to reserve resources of the testbed, using OAR underneath. You can find more about OAR on the Advanced OAR page.

Job submission

This API is a thin wrapper on top of the OAR tool, therefore most of the oarsub options are supported.

For instance, let's submit a job with 2 nodes of the grenoble site, for 2 hours. And let's say we want to launch a useless script that just sleeps forever when the job starts:

$ curl -i https://api.grid5000.fr/stable/sites/grenoble/jobs?pretty -X POST -H'Content-Type: application/json' -d '{"resources": "nodes=2,walltime=02:00", "command": "while(true); do sleep 5; echo \"awake\"; done"}'
HTTP/1.1 201 Created
Date: Thu, 03 Dec 2020 14:47:57 GMT
Server: thin
Content-Type: application/json; charset=utf-8
Location: https://api.grid5000.fr/stable/sites/grenoble/jobs/1965464
Content-Length: 818
ETag: W/"40668ba7ef11e54db1ef39adc09bddcf"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: f705fc66-bfbf-459b-954d-cc722ff1914f
X-Runtime: 0.642098
Via: 1.1 api-server-v3.grenoble.grid5000.fr:4444
X-Api-Auth-Type: IDENT
X-Api-User-CN: auser
X-Remote-Ident: auser
X-Kadeploy-User: auser
{
 "uid": 1965464,
 "user_uid": "auser",
 "user": "auser",
 "walltime": 7200,
 "queue": "default",
 "state": "waiting",
 "project": "g5k-staff",
 "types": [
   "monitor=prom_.*default_metrics"
 ],
 "mode": "PASSIVE",
 "command": "./oarapi.subscript.IEtz0",
 "submitted_at": 1607006878,
 "started_at": 0,
 "message": "R=64,W=2:0:0,J=B,P=g5k-staff,T=monitor=prom_.*default_metrics",
 "properties": "maintenance = 'NO'",
 "directory": "/home/auser",
 "events": [
  
 ],
 "links": [
   {
     "rel": "self",
     "href": "/stable/sites/grenoble/jobs/1965464",
     "type": "application/vnd.grid5000.item+json"
   },
   {
     "rel": "parent",
     "href": "/stable/sites/grenoble",
     "type": "application/vnd.grid5000.item+json"
   }
 ],
 "resources_by_type": {
 },
 "assigned_nodes": [
 
 ]
}

Status code is 201 Created, which means a new job resource has been created. You can find the URI of that new job resource in the Location HTTP header: https://api.grid5000.fr/stable/sites/grenoble/jobs/1965464 The job is in the waiting state at first, but then will go to the running state.

{
 "uid": 1965464,
 "user_uid": "auser",
 "user": "auser",
 "walltime": 7200,
 "queue": "default",
 "state": "running",
 "project": "g5k-staff",
 "types": [
   "monitor=prom_.*default_metrics"
 ],
 "mode": "PASSIVE",
 "command": "./oarapi.subscript.IEtz0",
 "submitted_at": 1607006878,
 "scheduled_at": 1607006880,
 "started_at": 1607006880,
 "message": "FIFO scheduling OK",
 "properties": "maintenance = 'NO'",
 "directory": "/home/auser",
 "events": [
 
 ],
 "links": [
   {
     "rel": "self",
     "href": "/stable/sites/grenoble/jobs/1965464",
     "type": "application/vnd.grid5000.item+json"
   },
   {
     "rel": "parent",
     "href": "/stable/sites/grenoble",
     "type": "application/vnd.grid5000.item+json"
   }
 ],
 "resources_by_type": {
   "cores": [
     "dahu-3.grenoble.grid5000.fr/0",
     "dahu-3.grenoble.grid5000.fr/1",
     "dahu-3.grenoble.grid5000.fr/2",
     "dahu-3.grenoble.grid5000.fr/3",
     "dahu-3.grenoble.grid5000.fr/4",
     "dahu-3.grenoble.grid5000.fr/5",
     "dahu-3.grenoble.grid5000.fr/6",
     "dahu-3.grenoble.grid5000.fr/7",
     "dahu-3.grenoble.grid5000.fr/8",
     "dahu-3.grenoble.grid5000.fr/9",
     "dahu-3.grenoble.grid5000.fr/10",
     "dahu-3.grenoble.grid5000.fr/11",
     "dahu-3.grenoble.grid5000.fr/12",
     "dahu-3.grenoble.grid5000.fr/13",
     "dahu-3.grenoble.grid5000.fr/14",
     "dahu-3.grenoble.grid5000.fr/15",
     "dahu-3.grenoble.grid5000.fr/16",
     "dahu-3.grenoble.grid5000.fr/17",
     "dahu-3.grenoble.grid5000.fr/18",
     "dahu-3.grenoble.grid5000.fr/19",
     "dahu-3.grenoble.grid5000.fr/20",
     "dahu-3.grenoble.grid5000.fr/21",
     "dahu-3.grenoble.grid5000.fr/22",
     "dahu-3.grenoble.grid5000.fr/23",
     "dahu-3.grenoble.grid5000.fr/24",
     "dahu-3.grenoble.grid5000.fr/25",
     "dahu-3.grenoble.grid5000.fr/26",
     "dahu-3.grenoble.grid5000.fr/27",
     "dahu-3.grenoble.grid5000.fr/28",
     "dahu-3.grenoble.grid5000.fr/29",
     "dahu-3.grenoble.grid5000.fr/30",
     "dahu-3.grenoble.grid5000.fr/31",
     "dahu-32.grenoble.grid5000.fr/0",
     "dahu-32.grenoble.grid5000.fr/1",
     "dahu-32.grenoble.grid5000.fr/2",
     "dahu-32.grenoble.grid5000.fr/3",
     "dahu-32.grenoble.grid5000.fr/4",
     "dahu-32.grenoble.grid5000.fr/5",
     "dahu-32.grenoble.grid5000.fr/6",
     "dahu-32.grenoble.grid5000.fr/7",
     "dahu-32.grenoble.grid5000.fr/8",
     "dahu-32.grenoble.grid5000.fr/9",
     "dahu-32.grenoble.grid5000.fr/10",
     "dahu-32.grenoble.grid5000.fr/11",
     "dahu-32.grenoble.grid5000.fr/12",
     "dahu-32.grenoble.grid5000.fr/13",
     "dahu-32.grenoble.grid5000.fr/14",
     "dahu-32.grenoble.grid5000.fr/15",
     "dahu-32.grenoble.grid5000.fr/16",
     "dahu-32.grenoble.grid5000.fr/17",
     "dahu-32.grenoble.grid5000.fr/18",
     "dahu-32.grenoble.grid5000.fr/19",
     "dahu-32.grenoble.grid5000.fr/20",
     "dahu-32.grenoble.grid5000.fr/21",
     "dahu-32.grenoble.grid5000.fr/22",
     "dahu-32.grenoble.grid5000.fr/23",
     "dahu-32.grenoble.grid5000.fr/24",
     "dahu-32.grenoble.grid5000.fr/25",
     "dahu-32.grenoble.grid5000.fr/26",
     "dahu-32.grenoble.grid5000.fr/27",
     "dahu-32.grenoble.grid5000.fr/28",
     "dahu-32.grenoble.grid5000.fr/29",
     "dahu-32.grenoble.grid5000.fr/30",
     "dahu-32.grenoble.grid5000.fr/31"
   ]
 },
 "assigned_nodes": [
   "dahu-3.grenoble.grid5000.fr",
   "dahu-32.grenoble.grid5000.fr"
 ]
}

Now the job is now in the running state, and you can find the list of nodes (independently of how many cores you reserved on each node) assigned to your job in the assigned_nodes property. Also note the resources_by_type property, which lists all the resources by type (nodes, vlans, subnets, disks). For nodes type, there is an entry per core reserved on the node.

Note.png Note

API resources (i.e. objects managed by the API) are not to be confused with OAR resources (i.e. compute nodes, CPUs, cores, GPUs, disks, or VLANs, or subnets).

You should now be able to connect to your nodes using the job uid and the oarsub tool (see the Advanced OAR page).

Job deletion

Since the previous job is doing nothing, we can delete it to free the nodes for other users. To do this, just send a http request with the DELETE method on the job URI:

$ curl  -i -X DELETE https://api.grid5000.fr/stable/sites/grenoble/jobs/1965464
HTTP/1.1 202 Accepted
Date: Thu, 03 Dec 2020 15:17:18 GMT
Server: thin
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
X-Oar-Info: Deleting the job = 1965464 ...REGISTERED. The job(s) [ 1965464 ] will be deleted in the near future.
Location: https://api.grid5000.fr/stable/sites/grenoble/jobs/1965464
Content-Type: text/plain; charset=utf-8
Cache-Control: no-cache
X-Request-Id: 2c256e0f-c623-4522-9df2-c11ea200a32f
X-Runtime: 0.230989
Via: 1.1 api-server-v3.grenoble.grid5000.fr:4444
X-Api-Auth-Type: IDENT
X-Api-User-CN: auser
X-Remote-Ident: auser
X-Kadeploy-User: auser
Transfer-Encoding: chunked

Deletion is not immediate, that's why you receive a 202 Accepted status code, which means that the request will be handled shortly thereafter.

Deployments API

Deployments API allows deploying an environment on nodes, using Kadeploy. You can find more about Kadeploy on the Advanced Kadeploy page.

Reserve nodes

An OAR job of type deploy is required to perform a deployment. The following creates the job:

$ curl https://api.grid5000.fr/stable/sites/grenoble/jobs -X POST -H 'Content-Type: application/json' -d '{"resources": "nodes=2", "types": ["deploy"], "command": "sleep 3600"}'

If everything goes well, you’ll receive a 201 created:

HTTP/1.1 201 Created
Date: Thu, 03 Dec 2020 13:34:22 GMT
Server: thin
Content-Type: application/json; charset=utf-8
Location: https://api.grid5000.fr/stable/sites/grenoble/jobs/1965452
Content-Length: 625
X-Info: Use `?pretty=yes` or add the HTTP header `X-Rack-PrettyJSON: yes` if you want pretty output.
ETag: W/"bca9a34873d997ae8e0da4a829daae9d"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 64bc2472-459d-4e29-a46d-50d893f75e47
X-Runtime: 0.648162
X-Api-Auth-Type: IDENT
X-Api-User-CN: auser
X-Remote-Ident: auser
X-Kadeploy-User: auser
 {
 "uid": 1965460,
 "user_uid": "auser",
 "user": "auser",
 "walltime": 3600,
 "queue": "default",
 "state": "waiting",
 "project": "g5k-staff",
 "types": [
   "deploy"
 ],
 "mode": "PASSIVE",
 "command": "./oarapi.subscript._o1nf",
 "submitted_at": 1607005232,
 "started_at": 0,
 "message": "R=64,W=1:0:0,J=B,P=g5k-staff,T=deploy",
 "properties": "(deploy = 'YES') AND maintenance = 'NO'",
 "directory": "/home/auser",
 "events": [],
 "links": [
   {
     "rel": "self",
     "href": "/stable/sites/grenoble/jobs/1965460",
     "type": "application/vnd.grid5000.item+json"
   },
   {
     "rel": "parent",
     "href": "/stable/sites/grenoble",
     "type": "application/vnd.grid5000.item+json"
   }
 ],
 "resources_by_type": {},
 "assigned_nodes": []
}

Using the job URI given in the Location header. We have to wait for the job to be running: It is possible to poll the Jobs API until the job is in running state:

$ curl -s https://api.grid5000.fr/stable/sites/grenoble/jobs/1965460 | jq '.assigned_nodes,.state'
[
  "dahu-13.grenoble.grid5000.fr",
  "dahu-17.grenoble.grid5000.fr"
]
"running"

We also extract the assigned_nodes to use them later.

Deploy

Now, we use the nodes list provided by our OAR reservation, and launch a deployment:

$ export SSH_PUBLIC_KEY=`cat ~/.ssh/id_rsa.pub` # replace with your Grid'5000 public key.
$ curl -i https://api.grid5000.fr/stable/sites/grenoble/deployments -H'Content-Type: application/json' -d \
'{"nodes": ["dahu-13.grenoble.grid5000.fr", "dahu-17.grenoble.grid5000.fr"], "environment": "debian11-min", "key": "$SSH_PUBLIC_KEY"}'

A 201 created response should be returned:

HTTP/1.1 201 Created
Date: Thu, 03 Dec 2020 14:25:05 GMT
Server: thin
Content-Type: application/json; charset=utf-8
Location: https://api.grid5000.fr/stable/sites/grenoble/deployments/D-d54fca72-ef30-47cc-bf6a-54b6223fd7e4
Content-Length: 612
X-Info: Use `?pretty=yes` or add the HTTP header `X-Rack-PrettyJSON: yes` if you want pretty output.
ETag: W/"6ab81705feaa1155d086378912a20230"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 9b052b75-a444-4641-8cd5-bc6c187dbb09
X-Runtime: 0.092125
Via: 1.1 api-server-v3.grenoble.grid5000.fr:4444
X-Api-Auth-Type: IDENT
X-Api-User-CN: auser
X-Remote-Ident: auser
X-Kadeploy-User: auser
{
 "uid": "D-9bd9e783-41fb-4b09-87e0-38522df086d8",
 "site_uid": "grenoble",
 "user_uid": "auser",
 "environment": "debian11-min",
 "status": "processing",
 "key": "https://api.grid5000.fr/stable/sites/grenoble/files/auser-key-c213083a4ce7e58bc2052f03c144a06afdf6cc4a",
 "nodes": [
   "dahu-13.grenoble.grid5000.fr",
   "dahu-17.grenoble.grid5000.fr"
 ],
 "created_at": 1607005453,
 "updated_at": 1607005453,
 "links": [
   {
     "rel": "self",
     "href": "/stable/sites/grenoble/deployments/D-9bd9e783-41fb-4b09-87e0-38522df086d8",
     "type": "application/vnd.grid5000.item+json"
   },
   {
     "rel": "parent",
     "href": "/stable/sites/grenoble",
     "type": "application/vnd.grid5000.item+json"
   }
 ]
}

Again, we can use the URI given in the Location header to poll the deployment status :

$ curl -s https://api.grid5000.fr/stable/sites/grenoble/deployments/D-9bd9e783-41fb-4b09-87e0-38522df086d8 | jq .status
"processing"

Later:

$ curl -s https://api.grid5000.fr/stable/sites/grenoble/deployments/D-9bd9e783-41fb-4b09-87e0-38522df086d8 | jq .status
"processing"

Once the deployment is over, the nodes are available and running the deployed environment as OS.

Vlans API

The Vlans API allows to manage or to get information about resources bounded to VLAN management: like Grid'5000 different types of VLANs, nodes interfaces or allowed users on a particular VLAN. This API interacts with the KaVLAN tool. More information about KaVLAN can be found on the Advanced_KaVLAN page.

Reserve VLAN and nodes

We start by reserving two nodes and a local kavlan (VLAN of type local) on the Grenoble site, using the Jobs API:

$ curl -i https://api.grid5000.fr/stable/sites/grenoble/jobs?pretty -X POST -H 'Content-Type: application/json' -d "{\"resources\":\"{type='kavlan-local'}/vlan=1,nodes=2\", \"types\": [\"deploy\"], \"command\": \"sleep 3600\"}"
HTTP/1.1 201 Created
Date: Thu, 10 Dec 2020 09:29:24 GMT
Server: thin
X-Frame-Options: SAMEORIGIN
X-XSS-Protection: 1; mode=block
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Permitted-Cross-Domain-Policies: none
Referrer-Policy: strict-origin-when-cross-origin
Content-Type: application/json; charset=utf-8
Location: https://api.grid5000.fr/stable/sites/grenoble/jobs/1967224
Content-Length: 791
ETag: W/"eda5d6c6671165250f54b1d3aa933601"
Cache-Control: max-age=0, private, must-revalidate
X-Request-Id: 5888554a-e244-4825-b0e7-93fa468a3123
X-Runtime: 0.602346
Via: 1.1 api-server-v3.grenoble.grid5000.fr:4444
X-Api-Auth-Type: IDENT
X-Api-User-CN: auser
X-Remote-Ident: auser
X-Kadeploy-User: auser
  
{
 "uid": 1967227,
 "user_uid": "auser",
 "user": "auser",
 "walltime": 3600,
 "queue": "default",
 "state": "waiting",
 "project": "g5k-staff",
 "types": [
   "deploy"
 ],
 "mode": "PASSIVE",
 "command": "./oarapi.subscript.NZnb2",
 "submitted_at": 1607592564,
 "started_at": 0,
 "message": "R=65,W=1:0:0,J=B,P=g5k-staff,T=deploy",
 "properties": "(deploy = 'YES') AND maintenance = 'NO'",
 "directory": "/home/auser",
 "events": [
   
 ],
 "links": [
   {
     "rel": "self",
     "href": "/stable/sites/grenoble/jobs/1967227",
     "type": "application/vnd.grid5000.item+json"
   },
   {
     "rel": "parent",
     "href": "/stable/sites/grenoble",
     "type": "application/vnd.grid5000.item+json"
   }
 ],
 "resources_by_type": {
 },
 "assigned_nodes": [
  
 ]

We can then look at the job state (is it running?), the assigned nodes, and VLAN number:

$ curl -s https://api.grid5000.fr/stable/sites/grenoble/jobs/1967224 | jq '.state,.assigned_nodes,.resources_by_type.vlans'
"running"
[
 "dahu-6.grenoble.grid5000.fr",
 "dahu-7.grenoble.grid5000.fr"
]
[
 "2"
]

In a normal workflow, an image should be deployed on the nodes. We will skip this part to go directly to the VLAN management.

The VLAN we reserved can also be found using the Vlans API (in addition to with the Jobs API):

$ curl https://api.grid5000.fr/stable/sites/grenoble/vlans/users/auser?pretty
{
 "uid": "auser",
 "vlans": [
   "2",
   "1"
 ],
 "links": [
   {
     "rel": "self",
     "href": "/stable/sites/grenoble/vlans/users/auser",
     "type": "application/vnd.grid5000.item+json"
   },
   {
     "rel": "parent",
     "href": "/stable/sites/grenoble/vlans/users",
     "type": "application/vnd.grid5000.collection+json"
   }
 ]
}

In this response, we also have the VLAN number 1, which is part of another reservation we made.

The status of a given user for a specific VLAN can be found with this query:

$ curl https://api.grid5000.fr/stable/sites/grenoble/vlans/2/users/auser?pretty

{
 "uid": "auser",
 "status": "authorized",
 "links": [
   {
     "rel": "self",
     "href": "/stable/sites/grenoble/vlans/2/users/auser",
     "type": "application/vnd.grid5000.item+json"
   },
   {
     "rel": "parent",
     "href": "/stable/sites/grenoble/vlans/2/users",
     "type": "application/vnd.grid5000.collection+json"
   }
 ]
}

And a list of users with rights on a VLAN is given by the following query:

curl https://api.grid5000.fr/stable/sites/grenoble/vlans/2/users

(in fact with the current configuration on Grid'5000 only one user can have rights on a VLAN).

Manage nodes

To add our nodes to the reserved VLAN, we have to make a POST request to the API:

$ curl -X POST https://api.grid5000.fr/stable/sites/grenoble/vlans/2/nodes?pretty -H "Content-Type: application/json" -d '["dahu-5.grenoble.grid5000.fr","dahu-6.grenoble.grid5000.fr"]'
{
 "dahu-5.grenoble.grid5000.fr": {
   "status": "success",
   "message": "Successfully added to vlan"
 },
 "dahu-6.grenoble.grid5000.fr": {
   "status": "success",
   "message": "Successfully added to vlan"
 }
}

We can see them by listing nodes in the VLAN:

$ curl https://api.grid5000.fr/stable/sites/grenoble/vlans/2/nodes?pretty
{
 "total": 2,
 "offset": 0,
 "items": [
   {
     "uid": "dahu-5.grenoble.grid5000.fr",
     "vlan": "2",
     "links": [
       {
         "rel": "self",
         "href": "/stable/sites/grenoble/vlans/nodes/dahu-5.grenoble.grid5000.fr",
         "type": "application/vnd.grid5000.item+json"
       },
       {
         "rel": "parent",
         "href": "/stable/sites/grenoble/vlans/nodes",
         "type": "application/vnd.grid5000.collection+json"
       }
     ]
   },
   {
     "uid": "dahu-6.grenoble.grid5000.fr",
     "vlan": "2",
     "links": [
       {
         "rel": "self",
         "href": "/stable/sites/grenoble/vlans/nodes/dahu-6.grenoble.grid5000.fr",
         "type": "application/vnd.grid5000.item+json"
       },
       {
         "rel": "parent",
         "href": "/stable/sites/grenoble/vlans/nodes",
         "type": "application/vnd.grid5000.collection+json"
       }
     ]
   }
 ],
 "links": [
   {
     "rel": "self",
     "href": "/stable/sites/grenoble/vlans/2/nodes",
     "type": "application/vnd.grid5000.collection+json"
   },
   {
     "rel": "parent",
     "href": "/stable/sites/grenoble/vlans/2",
     "type": "application/vnd.grid5000.item+json"
   }
 ]
}

A list of all the known nodes in Kavlan and their current VLAN assignation is also available, with the following query:

$ curl https://api.grid5000.fr/stable/sites/grenoble/vlans/nodes?pretty
{
 "total": 52,
 "offset": 0,
 "items": [
   {
     "uid": "dahu-1.grenoble.grid5000.fr",
     "vlan": "DEFAULT",
     "links": [
       {
         "rel": "self",
         "href": "/stable/sites/grenoble/vlans/nodes/dahu-1.grenoble.grid5000.fr",
         "type": "application/vnd.grid5000.item+json"
       },
       {
         "rel": "parent",
         "href": "/stable/sites/grenoble/vlans/nodes",
         "type": "application/vnd.grid5000.collection+json"
       }
     ]
   },
   {
     "uid": "dahu-10.grenoble.grid5000.fr",
     "vlan": "DEFAULT",
     "links": [
       {
         "rel": "self",
         "href": "/stable/sites/grenoble/vlans/nodes/dahu-10.grenoble.grid5000.fr",
         "type": "application/vnd.grid5000.item+json"
       },
       {
         "rel": "parent",
         "href": "/stable/sites/grenoble/vlans/nodes",
         "type": "application/vnd.grid5000.collection+json"
       }
     ]
   },
  …

Manage dhcp server

Kavlan offers the possibility to have a dhcpd service running for a particular vlan.

If we don't want to use it, we can stop it with a simple PUT query:

curl -X PUT https://api.grid5000.fr/stable/sites/grenoble/vlans/2/dhcpd -H "Content-Type: application/json" -d '{"action":"stop"}'

Metrics APIs

The metrics API uses Kwollect and has a dedicated documentation.

Status API

The Status API allows getting OAR resources status and reservation (associated job), for a site or a cluster.

Cluster status

$ curl https://api.grid5000.fr/stable/sites/grenoble/clusters/yeti/status?pretty
 "uid": 1607009770,
 "links": [
   {
     "rel": "self",
     "href": "/stable/sites/grenoble/clusters/yeti/status",
     "type": "application/vnd.grid5000.item+json"
   },
   {
     "rel": "parent",
     "href": "/stable/sites/grenoble/clusters/yeti",
     "type": "application/vnd.grid5000.item+json"
   }
 ],
 "disks": {
   "sdd.yeti-1.grenoble.grid5000.fr": {
     "hard": "alive",
     "soft": "free",
     "diskpath": "/dev/disk/by-path/pci-0000:18:00.0-scsi-0:0:3:0",
     "reservations": [
      
     ]
   },
   "sdd.yeti-2.grenoble.grid5000.fr": {
     "hard": "alive",
     "soft": "free",
     "diskpath": "/dev/disk/by-path/pci-0000:18:00.0-scsi-0:0:3:0",
     "reservations": [
      
     ]
   },
  …
 "nodes": {
   "yeti-1.grenoble.grid5000.fr": {
     "hard": "standby",
     "soft": "free",
     "comment": "OK",
     "reservations": [
        
     ],
     "free_slots": 64,
     "freeable_slots": 0,
     "busy_slots": 0
   },
   …

The status of a cluster contains the status of nodes and disks (if the cluster has reservable disks).

Site status

$ curl https://api.grid5000.fr/stable/sites/grenoble/clusters/status?pretty

On the site level, the Status API gives the status of the nodes, disks, vlans, and subnets OAR resources.

Stitching API

See here for a stitching example.

Storage API

See here for examples on how to use the storage API.