A command-line interface for managing OpenSlides instances. This tool provides deployment automation, Kubernetes orchestration, direct access to OpenSlides backend actions, database queries, and database migrations.
osmanage is a comprehensive management utility for OpenSlides 4.x instances. It combines deployment automation, Kubernetes orchestration, database operations, and administrative tasks into a single tool.
Key Features:
- Deployment Setup: Generate Docker Compose and Kubernetes configurations
- Kubernetes Management: Deploy, update, and manage OpenSlides in Kubernetes
- Secrets Management: Automatic generation of secure passwords and certificates
- Database Queries: Direct PostgreSQL access with advanced filtering
- Database Migrations: Manage OpenSlides schema migrations with progress tracking
- User Management: Create users and manage passwords
- Backend Actions: Execute arbitrary OpenSlides actions
Download the latest binary from the releases page:
# Linux AMD64
curl -L https://github.com/OpenSlides/openslides-cli/releases/latest/download/osmanage -o osmanage
chmod +x osmanage
sudo mv osmanage /usr/local/bin/Requirements:
- Go 1.23 or later
git clone https://github.com/OpenSlides/openslides-cli.git
cd openslides-cli
CGO_ENABLED=0 go build -a -ldflags="-s -w" ./cmd/osmanageStandard workflow for Docker Compose deployments:
# 1. Generate deployment configuration with random secrets
osmanage setup ./my.instance.dir.org \
--config config.yml \
--template docker-compose.yml.tmpl
# 2. Start services
cd my.instance.dir.org
docker compose up -d
# 3. Wait for services to be ready (~30 seconds)
docker compose logs -f backendManage
# 4. Access OpenSlides at http://localhost:8000
# Login as 'superadmin' with password from:
cat secrets/superadmin
# 5. Stop services when done
docker compose down
# Optional: Remove volumes (complete cleanup)
docker compose down -vThis is giving an overview of a selection of available commands. See --help messages for more complete information.
Commands for creating and managing OpenSlides instance directories.
Creates a new instance directory with deployment configuration, secrets, and SSL certificates.
Usage:
osmanage setup <instance-dir> [flags]Generated Structure:
my.instance.dir.org/
├── docker-compose.yml # (if using Docker Compose template)
└── secrets/
├── auth_token_key
├── auth_cookie_key
├── internal_auth_password
├── postgres_password
├── superadmin
├── cert_crt # (if HTTPS enabled)
└── cert_key
Examples:
# Docker Compose deployment
osmanage setup ./my.instance.dir.org \
--config config.yml \
--template docker-compose.yml.tmpl
# Multiple config files (merged, later files override earlier)
osmanage setup ./my.instance.dir.org \
--config base-config.yml \
--config prod-overrides.yml \
--template docker-compose.yml.tmpl
# Overwrite existing instance
osmanage setup ./my.instance.dir.org \
--config config.yml \
--template docker-compose.yml.tmpl \
--force(Re)creates deployment configuration files from templates and YAML config files.
Usage:
osmanage config <instance-dir> [flags]Behavior:
- Merges multiple YAML config files (later file's fields override earlier ones)
- Renders templates with merged configuration
- Creates or overwrites deployment files in the instance directory
Use Cases:
- Regenerate deployment files after config changes
- Update templates without recreating secrets
- Apply new configuration to existing instance
- Fix or modify deployment manifests
Examples:
# Regenerate deployment files
osmanage config ./my.instance.dir.org \
--template ./k8s-templates \
--config ./config.yml
# Update with multiple configs (merged)
osmanage config ./my.instance.dir.org \
--template ./k8s-templates \
--config base-config.yml \
--config prod-overrides.yml
# Force overwrite existing files
osmanage config ./my.instance.dir.org \
--template docker-compose.yml \
--config config.yml \
--forceNote: This command does NOT regenerate secrets - it only (re)creates deployment files. Use osmanage setup for initial instance creation with secrets, or osmanage create to update passwords.
Commands for interacting with the OpenSlides backend API.
Note: All backend action commands require --address and --password-file flags.
Manage OpenSlides database migrations.
Subcommands:
migrate: Run migrations on auxiliary tablesfinalize: Apply migrations to live tablesreset: Reset unapplied migrationsstats: Show migration statisticsprogress: Check running migration progress
Examples:
# Check migration status
osmanage migrations stats \
--address localhost:9002 \
--password-file ./secrets/internal_auth_password
# Run migrations
osmanage migrations migrate \
--address localhost:9002 \
--password-file ./secrets/internal_auth_password
# Apply migrations
osmanage migrations finalize \
--address localhost:9002 \
--password-file ./secrets/internal_auth_password
# Apply without progress output
osmanage migrations finalize \
--address localhost:9002 \
--password-file ./secrets/internal_auth_password \
--interval 0Migration Stats Output:
current_migration_index: 15
target_migration_index: 20
positions: 1500
events: 5000
partially_migrated_positions: 500
fully_migrated_positions: 1000
status: migration_running
Initialize a new OpenSlides database.
Usage:
osmanage initial-data [flags]Behavior:
- Sets up organization and default data
- Sets superadmin (user ID 1) password
- Returns error if database is not empty (exit code 2)
Examples:
# Docker Compose
osmanage initial-data \
--address localhost:9002 \
--password-file ./secrets/internal_auth_password \
--superadmin-password-file ./secrets/superadminCreate a new OpenSlides user.
Usage:
osmanage create-user [user-data] [flags]Required JSON Fields:
username: User login namedefault_password: Initial password
Examples:
# Inline JSON
osmanage create-user '{"username": "admin", "default_password": "secret123"}' \
--address localhost:9002 \
--password-file ./secrets/internal_auth_password
# From file
osmanage create-user \
--file user.json \
--address localhost:9002 \
--password-file ./secrets/internal_auth_passworduser.json:
{
"username": "mmax",
"default_password": "changemepwd",
"first_name": "Max",
"last_name": "Mustermann",
"email": "mmax@example.com",
"is_active": true
}Change a user's password.
Usage:
osmanage set-password [flags]Example:
osmanage set-password \
--address localhost:9002 \
--password-file ./secrets/internal_auth_password \
--user_id 5 \
--password "newSecurePassword123"Query the OpenSlides database with advanced filtering.
Important
Requires access to postgres. Examples assume port is forwarded.
Usage:
osmanage get <collection> [flags]Supported Collections:
usermeetingorganization
Supported Operators (in --filter-raw):
=: Equal!=: Not equal>: Greater than<: Less than>=: Greater than or equal<=: Less than or equal~=: Regex match
Examples:
# Simple query
osmanage get user --fields first_name,last_name,email \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user openslides \
--postgres-database openslides \
--postgres-password-file ./secrets/postgres_password
# With filter
osmanage get user --filter is_active=true \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user openslides \
--postgres-database openslides \
--postgres-password-file ./secrets/postgres_passwordComplex filters:
# Regex matching
osmanage get user \
--filter-raw '{"field":"username","operator":"~=","value":"^admin"}' \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user openslides \
--postgres-database openslides \
--postgres-password-file ./secrets/postgres_password
# AND filter
osmanage get user \
--filter-raw '{"and_filter":[{"field":"is_active","operator":"=","value":true},{"field":"first_name","operator":"~=","value":"^M"}]}' \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user openslides \
--postgres-database openslides \
--postgres-password-file ./secrets/postgres_password
# Check existence
osmanage get meeting \
--filter id=1 \
--exists \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user openslides \
--postgres-database openslides \
--postgres-password-file ./secrets/postgres_passwordUpdate OpenSlides objects using backend actions.
Usage:
osmanage set <action> [payload] [flags]Supported Actions:
agenda_item,committee,group,meeting,motion,organization,organization_tag,projector,theme,topic,user
Examples:
# Update user
osmanage set user '[{"id": 5, "first_name": "Jane", "last_name": "Smith"}]' \
--address localhost:9002 \
--password-file ./secrets/internal_auth_password
# Update from file
osmanage set meeting \
--file meeting-update.json \
--address localhost:9002 \
--password-file ./secrets/internal_auth_passwordExecute arbitrary OpenSlides backend actions.
Usage:
osmanage action <action-name> [payload] [flags]Examples:
# Docker Compose (localhost)
osmanage action meeting.create '[{"name": "Annual Meeting", "committee_id": 1, "language": "de", "admin_ids": [1]}]' \
--address localhost:9002 \
--password-file ./my.instance.dir.org/secrets/internal_auth_password
# Kubernetes (port-forwarded)
kubectl port-forward -n myinstancedirorg svc/backendmanage 9002:9002 &
osmanage action meeting.create '[{"name": "Board Meeting", "committee_id": 1, "language": "de", "admin_ids": [1]}]' \
--address localhost:9002 \
--password-file ./my.instance.dir.org/secrets/internal_auth_password
# From file
osmanage action meeting.create \
--file meeting.json \
--address localhost:9002 \
--password-file ./secrets/internal_auth_password
# From stdin
echo '[{"name": "Test", "committee_id": 1, "language": "de", "admin_ids": [1]}]' | \
osmanage action meeting.create --file - \
--address localhost:9002 \
--password-file ./secrets/internal_auth_passwordCommands for managing OpenSlides instances in Kubernetes.
Caution
These commands are still experimental. Use with caution!
Requirements:
- Valid kubeconfig file with cluster access (typically
~/.kube/config)- Or running inside a Kubernetes cluster with service account permissions
- Sufficient Kubernetes RBAC permissions to create/manage namespaces and resources
Note: osmanage uses the Kubernetes Go client library and does not require kubectl to be installed.
Deploys an OpenSlides instance to Kubernetes.
Usage:
osmanage k8s start <instance-dir> [flags]Features:
- Creates dedicated namespace from namespace.yaml
- Creates secrets from instance secrets/ directory (base64-encoded)
- Applies all Kubernetes manifests from stack/ directory
- Shows progress bars for deployment readiness
- Waits for all pods to be healthy
Stops and removes an OpenSlides instance from Kubernetes.
Usage:
osmanage k8s stop <instance-dir> [flags]Behavior:
- Saves TLS certificate secret (if exists) to
secrets/tls-letsencrypt-secret.yaml - Deletes the namespace and all resources
Warning: This deletes the namespace and all resources, including persistent volumes.
Updates an existing Kubernetes instance with new manifests.
Usage:
osmanage k8s update-instance <instance-dir> [flags]Use Cases:
- Apply configuration changes
- Update resource limits
- Modify service definitions
- Change replica counts
Updates the backendmanage container image.
Usage:
osmanage k8s update-backendmanage <instance-dir> [flags]Scales a specific service deployment.
Usage:
osmanage k8s scale <instance-dir> [flags]Note: You must edit the deployment manifest file (stack/<service>-deployment.yaml) to change replica count before running this command.
Checks the health status of an OpenSlides instance.
Usage:
osmanage k8s health <instance-dir> [flags]Features:
- Reports pod status for all deployments
- Shows ready/total pod counts
- Indicates overall instance health
Displays comprehensive cluster status.
Usage:
osmanage k8s cluster-status [flags]Features:
- Shows cluster-wide node health
- Reports ready vs total nodes
# 1. Generate instance
osmanage setup ./prod.instance.org \
--config prod-config.yml \
--template k8s-template-dir
# 2. Customize secrets (optional)
osmanage create ./prod.instance.org \
--db-password "$SECURE_DB_PASS" \
--superadmin-password "$SECURE_ADMIN_PASS"
# 3. Deploy to Kubernetes
osmanage k8s start ./prod.instance.org
# 4. Check health
osmanage k8s health ./prod.instance.org
# 5. Scale backend deployment (after editing manifest)
osmanage k8s scale ./prod.instance.org --service projector
# 6. Update backend image
osmanage k8s update-backendmanage ./prod.instance.org \
--tag 4.2.1 \
--container-registry myregistry
# 7. Stop instance
osmanage k8s stop ./prod.instance.org# Export all users
osmanage get user \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user instance_user \
--postgres-database instance_db \
--postgres-password-file ./my.instance.dir.org/secrets/postgres_password \
> backup-users-$(date +%Y%m%d).json
# Export specific fields
osmanage get user \
--fields username,first_name,last_name,email \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user instance_user \
--postgres-database instance_db \
--postgres-password-file ./my.instance.dir.org/secrets/postgres_password \
> backup-users-minimal.json# Get all active meetings with details
osmanage get meeting \
--filter is_active_in_organization_id=1 \
--fields name,start_time,end_time,location \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user openslides \
--postgres-database openslides \
--postgres-password-file ./secrets/postgres_password
# Count active meetings
osmanage get meeting \
--filter is_active_in_organization_id=1 \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user openslides \
--postgres-database openslides \
--postgres-password-file ./secrets/postgres_password \
| jq 'length'
# Check if specific meeting exists and is active
osmanage get meeting \
--filter-raw '{"and_filter":[{"field":"id","operator":"=","value":1},{"field":"is_active_in_organization_id","operator":"=","value":1}]}' \
--exists \
--postgres-host localhost \
--postgres-port 5432 \
--postgres-user openslides \
--postgres-database openslides \
--postgres-password-file ./secrets/postgres_password# Run all tests
go test ./...
# Run with coverage
go test -cover ./...
# Run specific package
go test ./internal/k8s/actions
# Verbose output
go test -v ./...# Development build (larger binary, debuggable)
go build -o osmanage ./cmd/osmanage
# Production build (smaller binary, optimized, no debug symbols)
CGO_ENABLED=0 go build -a -ldflags="-s -w" -o osmanage ./cmd/osmanage- Fork the repository
- Create a feature branch (
git checkout -b feature/amazing-feature) - Write tests for your changes
- Ensure all tests pass (
go test ./...) - Run
go fmt ./...to format code - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
Code Style:
- Follow standard Go conventions
- Run
go fmtbefore committing - Add tests for new functionality
- Update documentation as needed
- Use project constants from
internal/constants
This tool represents a significant refactor and expansion of the original openslides-manage-service created by Norman Jäckel.
Major Changes from Original:
- Complete Kubernetes orchestration system with health checks and progress tracking
- Migration from
datastorereadertoopenslides-go/datastore/dsfetch - Removed gRPC dependencies
- In-memory filtering for datastore queries
- Comprehensive retry mechanisms for migrations
- Extensive test coverage
- Improved deployment configuration and templating
- Centralized constants and project structure
- Instance management commands (setup/config/create/remove)
- Real-time deployment monitoring with progress bars
- Cluster status and health monitoring
Refactored/Developed by: Alexej Antoni @ Intevation GmbH
Original work by: Norman Jäckel
This project is licensed under the MIT License - see the LICENSE file for details.
- Issues: GitHub Issues
- Discussions: GitHub Discussions