Skip to main content

Service orchestration for OneTimeSecret: Podman Quadlets and systemd service management

Project description

rots - Remote OTS Commander

Service orchestration CLI for OneTimeSecret infrastructure.

Dual-purpose management tool:

  • Container orchestration: Containerized OTS deployments via Podman Quadlets (systemd integration)
  • Service management: Native systemd services for dependencies (Valkey, Redis)

Installation

With pipx (Recommended)

pipx installs CLI tools in isolated environments, preventing dependency conflicts and enabling clean upgrades.

# Install pipx if needed
pip install pipx
pipx ensurepath

# Install rots
pipx install rots

# Or from git
pipx install git+https://github.com/onetimesecret/ots-containers.git

Migrating from pip to pipx

If you previously installed with pip:

pip uninstall rots
pipx install rots

With pip

Not recommended for production. Use pipx instead.

pip install rots

From source

git clone https://github.com/onetimesecret/ots-containers.git
cd ots-containers
pipx install .

Upgrading

# Check for updates
rots self check

# Upgrade to latest
rots self upgrade

# Upgrade to specific version
rots self upgrade --version 0.24.0

The rots self upgrade command wraps pipx and is safe to invoke remotely via the sidecar.

Usage

rots --help
rots --version

Instance Types

Three container types with explicit systemd unit naming:

Type Unit Name Identifier Use
--web onetime-web@{port} Port number HTTP servers
--worker onetime-worker@{id} Name/number Background jobs
--scheduler onetime-scheduler@{id} Name/number Scheduled tasks

Managing OTS Containers

# List all instances
rots instances
rots instances --json

# List by type
rots instances --web
rots instances --worker
rots instances --scheduler

# Deploy instances
rots instances deploy --web 7043 7044
rots instances deploy --worker billing emails
rots instances deploy --scheduler main

# Redeploy (regenerate quadlet and restart)
rots instances redeploy                    # all running
rots instances redeploy --web 7043         # specific

# Start/stop/restart
rots instances start --web 7043
rots instances stop --scheduler main
rots instances restart                     # all running

# Status and logs
rots instances status
rots instances logs --web 7043 -f
rots instances logs --scheduler main -f

# Enable/disable at boot
rots instances enable --web 7043
rots instances disable --scheduler main -y

# Interactive shell
rots instances exec --web 7043

Managing systemd Services (Valkey, Redis)

# Initialize new service instance
rots service init valkey 6379
rots service init redis 6380 --bind 0.0.0.0

# Start/stop/restart
rots service start valkey 6379
rots service stop redis 6380
rots service restart valkey 6379

# Status and logs
rots service status valkey 6379
rots service logs valkey 6379 --follow

# Enable/disable at boot
rots service enable valkey 6379
rots service disable redis 6380

# List available service packages
rots service

Generating Cloud-Init Configurations

# Generate basic cloud-init config
rots cloudinit generate > user-data.yaml

# Include PostgreSQL repository
rots cloudinit generate --include-postgresql --postgresql-key /path/to/pgdg.asc

# Include Valkey repository
rots cloudinit generate --include-valkey --valkey-key /path/to/valkey.gpg

# Validate configuration
rots cloudinit validate user-data.yaml

Environment Variables

# Use a specific image tag
TAG=v0.23.0 rots instances redeploy --web 7043

# Use a different image
IMAGE=ghcr.io/onetimesecret/onetimesecret TAG=latest rots instances deploy --web 7044

Prerequisites

  • Linux with systemd
  • Podman installed and configured
  • Python 3.11+

Server Setup

FHS-compliant directory structure:

OTS Container Configuration

/etc/onetimesecret/              # System configuration
├── config.yaml                  # Application configuration
├── auth.yaml                    # Authentication config
└── logging.yaml                 # Logging config

/etc/default/onetimesecret       # Environment file (shared by all instances)

/etc/containers/systemd/         # Quadlet templates (managed by tool)
├── onetime-web@.container
├── onetime-worker@.container
└── onetime-scheduler@.container

/var/lib/onetimesecret/          # Runtime data
└── deployments.db               # Deployment timeline (SQLite)

Service Configuration (Valkey/Redis)

/etc/valkey/                     # Valkey system configuration
├── valkey.conf                  # Default config template
└── instances/                   # Instance configs (created by tool)
    ├── 6379.conf
    └── 6379-secrets.conf        # Secrets file (mode 0640)

/var/lib/valkey/                 # Runtime data
└── 6379/
    └── dump.rdb

How It Works

Container Management

  1. Quadlet templates: Writes systemd unit templates to /etc/containers/systemd/
  2. Environment: Reads from /etc/default/onetimesecret
  3. Secrets: Uses Podman secrets for sensitive values
  4. Timeline: Records deployments to SQLite for audit and rollback

Service Management

  1. Config files: Copies package defaults to instance-specific configs
  2. Secrets: Creates separate secrets files with restricted permissions
  3. Data directories: Creates per-instance data directories with correct ownership
  4. systemd: Manages services using package-provided templates

Troubleshooting

# Check instance status
rots instances status
systemctl status onetime-web@7043

# View logs
rots instances logs --web 7043 -f
journalctl -u onetime-web@7043 -f

# Unified log filtering (all instance types)
journalctl -t onetime -f

# List all onetime systemd units
systemctl list-units 'onetime-*'

# Verify Quadlet templates
cat /etc/containers/systemd/onetime-web@.container

# Reload systemd after manual changes
systemctl daemon-reload

Development

# Editable install
git clone https://github.com/onetimesecret/ots-containers.git
cd ots-containers
pip install -e ".[dev,test]"

# Run tests
pytest tests/

# Run with coverage (CI threshold: 70%)
pytest tests/ --cov=ots_containers --cov-fail-under=70

# Pre-commit hooks
pre-commit install

Running as root

# Use full path
sudo /home/youruser/.local/bin/rots instances status

# Or create symlink
sudo ln -s /home/youruser/.local/bin/rots /usr/local/bin/rots

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rots-0.6.1.tar.gz (431.7 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rots-0.6.1-py3-none-any.whl (180.5 kB view details)

Uploaded Python 3

File details

Details for the file rots-0.6.1.tar.gz.

File metadata

  • Download URL: rots-0.6.1.tar.gz
  • Upload date:
  • Size: 431.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rots-0.6.1.tar.gz
Algorithm Hash digest
SHA256 0e27eaad67fd790b70ca581b94163c81a80351739f226973b19f1dc991361630
MD5 c6c890c936fd636467e564ca1e572dd4
BLAKE2b-256 4f21ed4ff42198c377da1e571402b93d762c848b2fa80a7c07c2d0b9cb8ea55f

See more details on using hashes here.

Provenance

The following attestation bundles were made for rots-0.6.1.tar.gz:

Publisher: release.yml on onetimesecret/rots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rots-0.6.1-py3-none-any.whl.

File metadata

  • Download URL: rots-0.6.1-py3-none-any.whl
  • Upload date:
  • Size: 180.5 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rots-0.6.1-py3-none-any.whl
Algorithm Hash digest
SHA256 331d01f49b5b70b0ff4247c43bc3b6e89b6bb73001fe3232faa3a087f4dadb81
MD5 045531d951ab68d47389dc9b07287697
BLAKE2b-256 4f7ae6ae8769ecbed1bc6813c3b57039e80f18f48683f05471c00d881dd6f041

See more details on using hashes here.

Provenance

The following attestation bundles were made for rots-0.6.1-py3-none-any.whl:

Publisher: release.yml on onetimesecret/rots

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page