Rent-a-bot, your automation resource provider.
Exclusive access to a static resource is a common problem in automation. Rent-a-bot allows you to abstract your resources and lock them to prevent any concurrent access.
Rent-a-bot pursues the same objective as Jenkins Lockable Resource Plugin.
The plugin works quite well, but only if you use... well... Jenkins.
Rent-A-Bot's purpose is to fill the same needs in an environment where multiple automation applications exist.
Examples:
- Multiple Jenkins application servers
- Mixed automation applications (e.g., GitHub Actions + Jenkins)
- Shared resources between humans and automation systems
A resource is defined by a name and the existence of a lock token indicating if the resource is locked.
Optional available fields help you customize your resources with additional information:
- Resource description
- Lock description
- Endpoint
- Tags
This project uses uv for fast, reliable Python package management.
Install uv:
curl -LsSf https://astral.sh/uv/install.sh | sh
Or on macOS:
brew install uv
Clone the repository from GitHub:
git clone git@github.com:cpoisson/rent-a-bot.git
Navigate to the project directory:
cd rentabot
Install the package and dependencies using uv:
uv sync # Install dependencies and create virtual environment
uv pip install -e . # Install the package in editable mode
The easiest way to run Rent-A-Bot is using the built-in CLI:
# Run directly with uvx (no installation needed)
uvx rentabot
# Or install and run
uv pip install -e .
rentabot
CLI Options:
rentabot --help # Show help
rentabot --version # Show version
rentabot --config path/to/config.yaml # Use specific config file
rentabot --host 0.0.0.0 --port 8080 # Custom host and port
rentabot --reload # Enable auto-reload for development
rentabot --log-level debug # Set log level
Configuration File Discovery:
The CLI automatically searches for configuration files in this order:
- Explicit
--configargument ./.rentabot.yamlor./rentabot.yamlin current directory~/.rentabot/config.yamlin home directoryRENTABOT_RESOURCE_DESCRIPTORenvironment variable- No config (starts with empty resources)
You can also start the FastAPI server directly:
# With environment variable
RENTABOT_RESOURCE_DESCRIPTOR="path/to/config.yaml" uvicorn rentabot.main:app --reload --port 8000
# Or with uv
uv run uvicorn rentabot.main:app --reload --port 8000
The API will be available at:
- Main API: http://127.0.0.1:8000/
- Interactive API Docs: http://127.0.0.1:8000/docs
- ReDoc: http://127.0.0.1:8000/redoc
Alright, rent-a-bot is up and running.
At this stage you can connect to the web interface at http://127.0.0.1:8000/ or explore the interactive API documentation at http://127.0.0.1:8000/docs.
You will notice that the resource list is empty (dang...), let's populate it.
You will need a resource descriptor file to populate the resources at startup.
RENTABOT_RESOURCE_DESCRIPTOR="/absolute/path/to/your/resource/descriptor.yml"
The resource descriptor is a YAML file. Its purpose is to declare the resources you want to make available on rent-a-bot.
# Resources Description
# This file describes resources to populate in the database at rent-a-bot startup
coffee-machine:
description: "Kitchen coffee machine"
endpoint: "tcp://192.168.1.50"
tags: "coffee,kitchen,food"
3d-printer-1:
description: "Basement 3d printer 1"
endpoint: "tcp://192.168.1.60"
tags: "3d-printer,basement,tool"
another-resource:
description: "yet another resource"
endpoint: ""
tags: ""Once set, (re)start the application with the environment variable:
RENTABOT_RESOURCE_DESCRIPTOR=/path/to/your/resources.yaml uvicorn rentabot.main:app --reload --port 8000
The web view should be populated with your resources.
GET /api/v1/resources
e.g.
curl -X GET -i http://localhost:8000/api/v1/resources
GET /api/v1/resources/{resource_id}
e.g.
curl -X GET -i http://localhost:8000/api/v1/resources/2
POST /api/v1/resources/{resource_id}/lock
e.g.
curl -X POST -i http://localhost:8000/api/v1/resources/6/lock
Note: If the resource is available, a lock-token will be returned. Otherwise an error code is returned.
POST /api/v1/resources/lock
e.g.
curl -X POST -i "http://localhost:8000/api/v1/resources/lock?id=6"
curl -X POST -i "http://localhost:8000/api/v1/resources/lock?name=coffee-maker"
curl -X POST -i "http://localhost:8000/api/v1/resources/lock?tag=coffee&tag=kitchen"
Notes:
- If multiple available resources match the criteria, the first available will be returned.
- If criteria types are exclusive, resource id is prioritized over the name and tags, and name is prioritized over tags.
POST /api/v1/resources/{resource_id}/unlock?lock-token={resource/lock/token}
curl -X POST -i "http://localhost:8000/api/v1/resources/6/unlock?lock-token={resource/lock/token}"
Note: If the resource is already unlocked or the lock-token is not valid, an error code is returned.
Unit tests are done using pytest and coverage.
uv run pytest
Or with the virtual environment activated:
source .venv/bin/activate
pytest
This project uses Semantic Versioning for its versioning scheme.
Versions are formatted as MAJOR.MINOR.PATCH, where:
- MAJOR version is incremented for incompatible API changes.
- MINOR version is incremented for adding functionality in a backward-compatible manner.
- PATCH version is incremented for backward-compatible bug fixes.