# tarantool-runner `tarantool-runner` is a CLI application to execute tarantool-based Rust applications. In most tarantool Rust-based applications even for smaller utilities we write special running suite because we need tarantool symbols. This project introduces binary `tarantool-runner` which takes a tarantool-ready shared object like `libexample.so`, desired entrypoint name(exported C function) and executes it in the newly created tarantool instance. After execution is completed, tarantool instance is stopped and purged. Have a quick glance on what a usage of `tarantool-runner` looks like: ```bash tarantool-runner -p ./target/debug/libexample.so -e my_exported_proc -- 'my_input_to_function' tarantool-runner -p ./target/debug/libexample.so -e my_exported_proc -- '{"key": "value"}' ``` Examples where `tarantool-runner` shines: 1) [shors](https://git.picodata.io/picodata/picodata/http-router) module introduces a brilliant feature: it can generate openapi spec directly from routes. But this algorithm involves slight interaction with `tarantool-module`, so it requires tarantool symbols. Without `tarantool-runner`, we have to write wrapping script that would execute needed rust binary in the tarantool environment ourselves. Instead, we can simply use `tarantool-runner` with the needed entrypoint. 1) Many tarantool projects require unit testing - and even unit testing could not always be executed without tarantool environment. Therefore, from project to project we write functional test suite that launches tarantool environment. `tarantool-runner` solves this issue partially - it can run any exported function in the tarantool environment, but you still have to use some test boilerplate to absorb and collect tests marked with `#[tarantool::test]`. If it is your primary case, you'd better use [tarantool-test](https://git.picodata.io/picodata/picodata/tarantool-test), which includes needed boilerplate and uses `tarantool-runner` internally, wrapping it in a pretty CLI interface. ## Utility installation You can install binary utility from `crates.io`: `cargo install tarantool-runner`. Or directly from the repository: ```bash git clone https://git.picodata.io/picodata/tarantool-runner cd tarantool-runner cargo install tarantool-runner ``` If you are interested in *extending* `tarantool-runner` or writing your own tarantool-oriented CLI application, follow the relevant [section](#using-as-a-base-for-cli-applications). ## Tutorial You can see sample of usage in `Makefile`: target `run-example` executes several entrypoints from `example` application, which can be found in `example` subdir. For your own project, your actions are as follows: 1. Ensure your package's entrypoints are usable from Lua code - if you are using `tarantool-module` it must be already done. Most of the time you just need to mark them with `tarantool::proc`: ```rust #[tarantool::proc] pub fn entrypoint_with_input(input: String) -> Result<()> { println!("{input}") Ok(()) } ``` 2. Compile your package: `cargo build -p mypackage`. At this point, take a note what is the path to the resulting shared object. It is often like `./target/debug/libmypackage.so` for linux or `./target/debug/libmypackage.dylib` for macos; 3. Use installed utility with the needed parameters and input(goes after `--`): `tarantool-runner run -p ./target/debug/libmypackage.so -e entrypoint_with_input -- '{"input": "can be json or any other format"}'`. You are done! ## Using as a base for CLI applications You can also use `tarantool-runner` as a base for your own CLI application. Just use it as a dependency for your project, it exports needed `Cli` structure, which is an ordinary `clap` application. Visit [tarantool-test](https://git.picodata.io/picodata/picodata/tarantool-test) for an example how it may look like - it is built on top of `tarantool-runner`. ## Details ### Environment By default, tarantool environment is built this way: 1) Base directory is created - it is directory with random name at /tmp dir. Base dir creation is done via [tempfile](https://github.com/Stebalien/tempfile). Initializing lua script is copied here; 1) Tarantool does not occupy any address and port, it listens socket that is placed in the previously created base dir. Therefore, you can freely use any amount of `tarantool-runner` at the same time - they won't interfere with each other. In fact, it is tested and debugged via integration tests here; 1) Tmpdir for tarantool runtime files is created - it is `tmp` directory inside base directory. 1) WAL mode set to `none` - as it would be single-instanced environment, we don't need it. WAL dir is indeed required - and we set it to previously created tmpdir. 1) `memtx_dir` is set to tmpdir. Special environment variables are available for the script and entrypoints: 1. `TARANTOOL_RUNNER_BASEDIR` - points to created base dir; 1. `TARANTOOL_RUNNER_TMPDIR` - points to created tmpdir(runtime directory for `tarantool`); 1. `TARANTOOL_RUNNER_PACKAGE_FULLPATH` - a full path to the package being executed, for example: `./target/debug/libexample.so`; 1. `TARANTOOL_RUNNER_PACKAGE_LOCATION` - directory where package is located, for example: `./target/debug`; 1. `TARANTOOL_RUNNER_PACKAGE_NAME` - a stem(filename without extension) of package. So if you have your package full path like this: `./target/debug/libexample.so`, then this variable is set to `libexample`; 1. `TARANTOOL_RUNNER_PACKAGE_ENTRYPOINT` - an entrypoint(exported function name) which is being executed. 1. `TARANTOOL_RUNNER_INPUT` - string which goes after `--` in the CLI interface. Your entrypoints would receive this string as the first argument, so no needs in retrieving it yourself. ### Entrypoints Entrypoints are just exported C functions - they don't even need to have an input argument if you want to. The result of entrypoint affects the exit code of tarantool instance - if they result in error, the whole command is failed. This could be interesting for test suite executions. ### Passing input Input is propagated to the entrypoints from the command line - pass it after `--`. It is passed as a string to your entrypoint - you can do whatever you want with it, like deserializing. ### Custom tarantool init script Lua initialization script for tarantool is builtin, but you can overwrite it with the `-i` argument, for example: `tarantool-runner run -p ./target/debug/libmypackage.so -e my_entrypoint -i /path/to/my/lua_init_script.lua -- "my_input"` You have full access to the environment variables exposed by `tarantool-runner`. See [section](#environment) for details about which are available, or check [default_init.lua](./tarantool-runner/src/default_init.lua) for an example how to use them. ## Contributing If you have question, problem or suggestion, feel free to reach me directly at `f.telnov@picodata.io` or at [telegram](https://t.me/ftelnov). You can also join Picodata chat at [telegram](https://t.me/picodataru) and tag me with your question here as well. We'll be glad to see you there!