diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 767d9c8..a0049b4 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,6 +60,15 @@ jobs: - name: Run tests run: cargo test --verbose + markdown_lint: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: DavidAnson/markdownlint-cli2-action@v18 + with: + config: '.markdownlint.yaml' + globs: '**/README.md' + # NOTE: In GitHub repository settings, the "Require status checks to pass # before merging" branch protection rule ensures that commits are only merged # from branches where specific status checks have passed. These checks are @@ -68,7 +77,7 @@ jobs: ci: name: CI status checks runs-on: ubuntu-latest - needs: build + needs: [build, markdown_lint] if: always() steps: - name: Check whether all jobs pass diff --git a/.markdownlint.yaml b/.markdownlint.yaml new file mode 100644 index 0000000..12f7379 --- /dev/null +++ b/.markdownlint.yaml @@ -0,0 +1,6 @@ +{ + "MD013": false, # Line length limitation + "MD033": false, # Enable Inline HTML + "MD041": false, # Allow first line heading + "MD045": false, # Allow Images have no alternate text +} \ No newline at end of file diff --git a/README.md b/README.md index 6aac254..ad1dd89 100644 --- a/README.md +++ b/README.md @@ -15,6 +15,7 @@ Zenoh (pronounce _/zeno/_) unifies data in motion, data at rest and computations Check the website [zenoh.io](http://zenoh.io) and the [roadmap](https://github.com/eclipse-zenoh/roadmap) for more detailed information. ------------------------------- + # File system backend In zenoh a backend is a storage technology (such as DBMS, time-series database, file system...) alowing to store the @@ -24,68 +25,73 @@ See the [zenoh documentation](https://zenoh.io/docs/manual/abstractions/#storage This backend relies on the host's file system to implement the storages. Its library name (without OS specific prefix and extension) that zenoh will rely on to find it and load it is **`zenoh_backend_fs`**. +:point_right: **Install latest release:** see [below](#how-to-install-it) -:point_right: **Install latest release:** see [below](#How-to-install-it) - -:point_right: **Build "main" branch:** see [below](#How-to-build-it) +:point_right: **Build "main" branch:** see [below](#how-to-build-it) ------------------------------- + ## **Examples of usage** Prerequisites: - - You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. - - Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). - If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. + +- You have a zenoh router (`zenohd`) installed, and the `zenoh_backend_fs` library file is available in `~/.zenoh/lib`. +- Declare the `ZENOH_BACKEND_FS_ROOT` environment variable to the directory where you want the files to be stored (or exposed from). + If you don't declare it, the `~/.zenoh/zenoh_backend_fs` directory will be used. You can setup storages either at zenoh router startup via a configuration file, either at runtime via the zenoh admin space, using for instance the REST API. + ### **Setup via a JSON5 configuration file** - - Create a `zenoh.json5` configuration file containing: - ```json5 - { - plugins: { - // configuration of "storage-manager" plugin: - storage_manager: { - volumes: { - // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) - fs: {}, - }, - storages: { - // configuration of a "demo" storage using the "fs" volume - demo: { - // the key expression this storage will subscribes to - key_expr: "demo/example/**", - // this prefix will be stripped from the received key when converting to file path - // this argument is optional. - strip_prefix: "demo/example", - volume: { - id: "fs", - // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) - dir: "example" - } +- Create a `zenoh.json5` configuration file containing: + + ```json5 + { + plugins: { + // configuration of "storage-manager" plugin: + storage_manager: { + volumes: { + // configuration of a "fs" volume (the "zenoh_backend_fs" backend library will be loaded at startup) + fs: {}, + }, + storages: { + // configuration of a "demo" storage using the "fs" volume + demo: { + // the key expression this storage will subscribes to + key_expr: "demo/example/**", + // this prefix will be stripped from the received key when converting to file path + // this argument is optional. + strip_prefix: "demo/example", + volume: { + id: "fs", + // the key/values will be stored as files within this directory (relative to ${ZENOH_BACKEND_FS_ROOT}) + dir: "example" } } - }, - // Optionally, add the REST plugin - rest: { http_port: 8000 } - } + } + }, + // Optionally, add the REST plugin + rest: { http_port: 8000 } } - ``` - - Run the zenoh router with: - `zenohd -c zenoh.json5` + } + ``` + +- Run the zenoh router with: + `zenohd -c zenoh.json5` ### **Setup at runtime via `curl` commands on the admin space** - - Run the zenoh router, with write permissions to its admin space and with the REST plugin: - `zenohd --adminspace-permissions=rw --rest-http-port=8000` - - Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): - `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` - - Add the "demo" storage using the "fs" backend: - `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` +- Run the zenoh router, with write permissions to its admin space and with the REST plugin: + `zenohd --adminspace-permissions=rw --rest-http-port=8000` +- Add the "fs" backend (the "zenoh_backend_fs" library will be loaded): + `curl -X PUT -H 'content-type:application/json' -d '{}' http://localhost:8000/@/router/local/config/plugins/storage_manager/volumes/fs` +- Add the "demo" storage using the "fs" backend: + `curl -X PUT -H 'content-type:application/json' -d '{key_expr:"demo/example/**",strip_prefix:"demo/example", volume: {id: "fs", dir:"example"}}' http://localhost:8000/@/router/local/config/plugins/storage_manager/storages/demo` ### **Tests using the REST API** Using `curl` to publish and query keys/values, you can: + ```bash # Put values that will be stored under ${ZENOH_BACKEND_FS_ROOT}/example curl -X PUT -d "TEST-1" http://localhost:8000/demo/example/test-1 @@ -111,15 +117,19 @@ Alternatively, you can test the zenoh router in a Docker container: --> ------------------------------- + ## Configuration + ### Extra configuration for filesystem-backed volumes Volumes using the `fs` backend don't need any extra configuration at the volume level. Any volume can use the `fs` backend by specifying the value `"fs"` for the `backend` configuration key. A volume named `fs` will automatically be backed by the `fs` backend if no other backend is specified. ------------------------------- + ### Storage-level configuration for filesystem-backed volumes Storages relying on a `fs` backed volume must/can specify additional configuration specific to that volume, as shown in the example [above](#setup-via-a-json5-configuration-file): + - `dir` (**required**, string) : The directory that will be used to store data. - `read_only` (optional, boolean) : the storage will only answer to GET queries. It will not accept any PUT or DELETE message, and won't write any file. `false` by default. @@ -131,27 +141,30 @@ Storages relying on a `fs` backed volume must/can specify additional configurati - `follow_links` (optional, boolean) : If set to `true` the storage will follow the symbolic links. The default value is `false`. - `keep_mime_types` (optional, boolean) : When replying to a GET query with a file for which the zenoh encoding is not known, the storage guess its mime-type according to the file extension. If the mime-type doesn't correspond to a supported zenoh encoding, this option will drive the returned value: - - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) - is returned with the description set to the mime-type. - - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with - APP_OCTET_STREAM encoding is returned. + - `true` (default value): a [Custom value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Custom) + is returned with the description set to the mime-type. + - `false`: a [Raw value](https://docs.rs/zenoh/latest/zenoh/enum.Value.html#variant.Raw) with + APP_OCTET_STREAM encoding is returned. ------------------------------- + ## **Behaviour of the backend** ### Mapping to file system + Each **storage** will map to a directory with path: `${ZENOH_BACKEND_FS_ROOT}/