Although there are several reference runtime implementations in-tree, it’s very easy to develop a new runtime for the preferred programming language not implemented so far.
Note
Actually, in the production environment(especially in the public cloud), it’s recommended that cloud providers provide their own runtime implementation for security reasons. Knowing how the runtime is implemented gives the malicious user the chance to attack the cloud environment.
Qinling uses Kubernetes as the default container orchestrator, so this guide will describe how the runtime containers working in the Kubernetes environment.
There are two containers in a Kubernetes pod serving the runtime, one is called “sidecar” which is responsible for downloading the function package if needed, the other one is the actual runtime container that is also running as an HTTP server. Once a Qinling runtime is created, there is a pool of such pods, when a function is being executed, some pods(according to the autoscaling policy) are chosen to run the function code.
Usually, you only need to develop the runtime container and re-use the sidecar container in the pod. There is only one public API that the runtime container should provide.
Example request:
POST /execute
Parameters provided by Qinling:
The execution information.
execution_id: The Qinling execution UUID.
download_url: The URL sent to Qinling to download the function
package. Here is an example for how to download function package in your
runtime implementation using requests
python library, the request is
meant to send to the sidecar container, the final package should be put
in /var/qinling/packages/<function_id>.zip
if the request is
successfully handled by the sidecar:
resp = requests.post(
'http://localhost:9091/download',
json={
'download_url': download_url,
'function_id': function_id,
'token': params.get('token')
}
)
function_id: The Qinling function UUID.
entry: The function entry that user defines when creating the function, e.g. “hello_world.main”
input: The dictionary of the function input that user defines when
creating the function execution. e.g. {"key": "value"}
. If the user
specifies the positional params when creating the function execution, the
input will be something like
{"__function_input": ("arg1", "arg2"), "key": "value"}
timeout: The timeout in seconds user defines when creating the function, the default value is 5. Your runtime implementation should take this timeout value into account when executing the code. If the timeout is reached, you should terminate the function execution and return an appropriate error message.
cpu: The CPU limit user defines when creating the function. Your runtime is responsible for limiting the CPU resource usage when the function is running.
memory_size: The memory limit user defines when creating the function. Your runtime is responsible for limiting the memory resource usage when the function is running.
request_id: The request UUID for the function execution which can be used to track the execution for debugging purpose.
The Information of the user who triggers the function execution.
Most of that information is used for creating a Keystone session that could be passed to the function, so it’s easy to interact with the OpenStack services in the function code.
Content in the response dictionary:
Except where otherwise noted, this document is licensed under Creative Commons Attribution 3.0 License. See all OpenStack Legal Documents.