ya-runtime-sdk is a Rust library for building Computation Environments and Self-contained Runtimes,
executed by Provider nodes in the Golem network.
ya-runtime-sdk provides facilitation in the following areas:
- interfacing with the computation orchestrator
- computation lifecycle management
- command output handling
- billing information reporting (TBD)
Table of contents
Runtime is responsible for performing computation specified in an Agreement between a Provider and a Requestor. Runtimes are executed only after a successful marketplace negotiation has taken place, where prices, computation deadlines and rented hardware resources have been agreed upon.
The degree of remote control that a Requestor can have over a Runtime depends on its flavour:
-
Computation Environment
Fully controlled by the Requestor via a well-defined set of commands ("ExeScript"). Requestor is responsible for triggering deployment of the payload (e.g. a Virtual Machine image) specified in an Agreement, starting the environment, executing commands within that environment and terminating the setup.
-
Self-contained Runtime
The payload is pre-defined by the developer. In this case, deploying, starting, executing commands and terminating the runtime can be only hinted by the Requestor; the implementation determines the exact behaviour of those actions.
Runtimes are orchestrated by their parent process, the ExeUnit Supervisor, via a standardized set of command line
arguments and a Runtime API protocol. ya-runtime-sdk handles all the communication automatically for any struct
implementing the Runtime trait.
The Runtime trait specifies handlers for each of the execution phases:
-
deployDescription: Initial configuration of the environment and payload.
Output: Optional JSON response in the following format:
{ "startMode": "blocking", "valid": {"Ok": "success"}, "vols": [ {"name": "vol-9a0c1c4a", "path": "/in"}, {"name": "vol-a68672e0", "path": "/out"} ], "customKey": "customValue" }Required properties:
-
startModeDetermines whether a runtime is a long-running application or a one-shot command.
"blocking"forRuntimeMode::Server"empty"forRuntimeMode::Command
-
validDeployment status.
{"Ok": "success message"}{"Err": "error message"}
-
volsLocal filesystem directory to runtime directory mapping.
nameis a subdirectory on a local filesystem, in a directory chosen by the Supervisor,pathis an alias of that directory, seen from inside the runtime and Supervisor services (e.g. file transfer)
-
-
startDescription: Enable the runtime to be used by the Requestor.
Can be run in one of the execution modes.
Output: Optional JSON response.
-
run_commandDescription: Parse, interpret and handle an array of string arguments. Optional in case of self-contained runtimes.
Can be run in any of the execution modes
-
kill_commandDescription: Terminate command execution.
Optional in case of self-contained runtimes.
-
stopDescription: Terminate the runtime.
May be triggered by the Requestor on demand or by the Provider Agent due to execution time constraints specified in the Agreement. Runtime is given a short (< 5s) time window to perform a graceful shutdown, otherwise it will be forcefully closed.
Runtime::MODE specifies one of 2 possible execution modes:
-
ServerThe
startcommand spawns a background task and returns promptly. Usually,runcommands have to be invoked inServermode (see command execution modes). -
Commandstartcommand is a one-shot invocation, which completes promptly. All of theruncommands are expected to be invoked via command line.
-
ServerCommand was invoked by a runtime running in a
Servermode.Developers may use the
RunCommandExttrait orContext::commandto wrap command execution and publish
stdout, stderr and usage counter events in a simple manner. -
CommandCommand was invoked via command line.
run_command implementation should distinguish each of the execution modes but is not required to support both.
In addition to the lifecycle and execution logic, runtimes can implement 2 additional customization functions:
-
testDescription: Perform a self-test.
Always executed during Provider Agent startup - i.e. during local yagna provider initialization, external to the negotiation phase and computation.
Implementation must allow execution at any time.
Example: the VM runtime (
ya-runtime-vm) spawns a Virtual Machine with a minimal test image attached, to verify that KVM is properly configured on provider's operating system and all bundled components are available in the expected location on disk. -
offerDescription: Inject custom properties and / or constraints to an Offer, published by the Provider Agent on the marketplace.
offeris executed by the Provider Agent while publishing new offers on the market, also during agent's initialization phase.Implementation must allow execution at any time.
Output: Optional JSON response in the following format:
{ "constraints": "", "properties": {} }
(TBD) Future versions of ya-runtime-sdk may cover additional types of events:
- runtime state change indication w/ JSON payload
- custom usage counters for billing purposes
Runtimes can be implemented by performing the following steps:
#[derive(Default, RuntimeDef)]on a runtime struct- implement the
Runtimetrait for the struct - use the
ya_runtime_sdk::runmethod to start the runtime
See the example-runtime for more details.
Each of the Runtime trait functions is parameterized with a mutable reference to the runtime, and a runtime
execution context object.
The Context struct exposes the following properties:
-
cliCommand line arguments provided to the binary
-
confDeserialized runtime configuration
-
conf_pathPath to the configuration file on a local filesystem
-
envAn object implementing the
Env(environment settings) trait -
emitterCommand event emitter
Context also exposes functions for configuration persistence:
-
read_configRead configuration from the specified path. Supports
JSON(default),YAMLandTOMLfile formats. The desired format is -
write_configWrite configuration to the specified path.
-
controlReturn a runtime control object. Its
shutdownmethod allows to terminate the runtime running in Server mode.
Configuration struct can be set via a #[conf(..)] attribute of the RuntimeDef derive macro. On runtime startup,
configuration is read from a file located at ~/.local/share/<crate_name>/<crate_name>.<format>.
Developers can use the ya-runtime-dbg tool to interact with a runtime
running in Server mode. See the README.md file in the linked repository for more details.
- Create a
ya-runtime-<runtime_name>.jsondescriptor file in the plugins directory.
[
{
"name": "<runtime_name>",
"version": "0.1.0",
"supervisor-path": "exe-unit",
"runtime-path": "<runtime_dir>/<runtime_bin>",
"description": "Custom runtime ",
"extra-args": ["--runtime-managed-image"]
}
]-
Edit
~/.local/share/ya-provider/presets.json:- create a
presetsentry forexeunit-name: "<runtime_name>"(e.g. copy an existing preset) - include the preset name in
activearray
- create a
-
Start
golemsporya-provider.
The plugins directory is by default located at:
- golemsp:
~/.local/lib/yagna/plugins/ - ya-provider:
/usr/lib/yagna/plugins/