📋 Pre-Release Notice
osmanageis currently in alpha/pre-release stage and is being actively developed for production use at Intevation GmbH. While the tool is functional, it is not yet ready for general community adoption:
- APIs and command interfaces may change
- Some features are still being finalized
- Documentation is work-in-progress
- Production hardening is ongoing
We plan to release a stable, community-ready version in the future. For now, use at your own risk or for experimentation only. Contributions and feedback are welcome!
A command-line interface for managing OpenSlides instances. This tool provides direct access to OpenSlides backend actions, datastore queries, database migrations, and deployment setup.
osmanage is a comprehensive management utility for OpenSlides 4.x instances. It combines deployment automation, database operations, and administrative tasks into a single tool.
Key Features:
- Deployment Setup: Generate Docker Compose and Kubernetes configurations
- Secrets Management: Automatic generation of secure passwords and certificates
- Datastore 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/osmanageIf your config has OPENSLIDES_BACKEND_CREATE_INITIAL_DATA: 1 set (default):
# 1. Generate deployment configuration
osmanage setup ./openslides-deployment \
--config config.yml \
--template templates/docker-compose.yml
# 2. Start services
cd openslides-deployment
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 -vCreates deployment configuration files, secrets, and SSL certificates.
Usage:
osmanage setup <directory> [flags]Flags:
-t, --template <path>: Custom template file or directory-c, --config <files>: YAML config file(s) (can be used multiple times)-f, --force: Overwrite existing files
Generated Files:
docker-compose.ymlor Kubernetes manifestssecrets/directory with:auth_token_keyauth_cookie_keyinternal_auth_passwordpostgres_passwordsuperadmincert_crtandcert_key(if HTTPS enabled)
Example:
osmanage setup ./deployment \
--config config.yml \
--template templates/docker-compose.ymlExecute arbitrary OpenSlides backend actions.
Usage:
osmanage action <action-name> [payload] [flags]Flags:
-a, --address: Backend service address (default:localhost:9002)--password-file: Authorization password file (default:secrets/internal_auth_password)-f, --file: JSON payload file or-for stdin
Examples:
# Inline JSON
osmanage action meeting.create '[{"name": "Annual Meeting", "committee_id": 1, "language": "de", "admin_ids": [1]}]'
# From file
osmanage action meeting.create --file meeting.json
# From stdin
echo '[{"name": "Test Meeting", "committee_id": 1, "language": "de", "admin_ids": [1]}]' | osmanage action meeting.create --file -Create a new OpenSlides user.
Usage:
osmanage create-user [user-data] [flags]Flags:
-a, --address: Backend service address (default:localhost:9002)--password-file: Authorization password file (default:secrets/internal_auth_password)-f, --file: JSON user data file or-for stdin
Required Fields:
username: User login namedefault_password: Initial password
Example:
# From file
osmanage create-user --file user.json
# Inline
osmanage create-user '{"username": "admin", "default_password": "secret123", "first_name": "Admin", "last_name": "User"}'user.json:
{
"username": "mmax",
"default_password": "changemepwd",
"first_name": "Max",
"last_name": "Mustermann",
"email": "[email protected]",
"is_active": true
}Query the OpenSlides datastore with advanced filtering.
Usage:
osmanage get <collection> [flags]Supported Collections:
usermeetingorganization
Flags:
--postgres-host: PostgreSQL host (default:localhost)--postgres-port: PostgreSQL port (default:5432)--postgres-user: PostgreSQL user (default:instance_user)--postgres-database: PostgreSQL database (default:instance_db)--postgres-password-file: Password file (default:/secrets/postgres-password)--fields: Comma-separated field list--filter: Simple key=value filters (multiple allowed, AND'ed together)--filter-raw: Complex JSON filter with operators--exists: Return boolean (requires filter)
Supported Operators (in --filter-raw):
=: Equal!=: Not equal>: Greater than<: Less than>=: Greater than or equal<=: Less than or equal~=: Regex match
Examples:
Simple queries:
# Get all users with specific fields
osmanage get user --fields first_name,last_name,email
# Filter by equality
osmanage get user --filter is_active=true --filter username=admin
# Check existence
osmanage get meeting --filter id=1 --existsComplex filters:
# Numeric comparison
osmanage get user --filter-raw '{"field":"id","operator":">","value":10}'
# Regex matching
osmanage get user --filter-raw '{"field":"username","operator":"~=","value":"^admin"}'
# AND filter
osmanage get user --filter-raw '{
"and_filter": [
{"field": "is_active", "operator": "=", "value": true},
{"field": "first_name", "operator": "~=", "value": "^M"}
]
}'
# OR filter
osmanage get meeting --filter-raw '{
"or_filter": [
{"field": "name", "operator": "~=", "value": "Annual"},
{"field": "name", "operator": "~=", "value": "Board"}
]
}'
# NOT filter
osmanage get user --filter-raw '{
"not_filter": {
"field": "is_active",
"operator": "=",
"value": false
}
}'
# Nested filters
osmanage get user --filter-raw '{
"and_filter": [
{"field": "is_active", "operator": "=", "value": true},
{
"or_filter": [
{"field": "username", "operator": "~=", "value": "^admin"},
{"field": "username", "operator": "~=", "value": "^super"}
]
}
]
}'Output Format:
{
"1": {
"id": 1,
"username": "admin",
"first_name": "Admin",
"last_name": "User",
"is_active": true
},
"2": {
"id": 2,
"username": "mmax",
"first_name": "Max",
"last_name": "Mustermann",
"is_active": true
}
}Initialize a new OpenSlides datastore.
Usage:
osmanage initial-data [flags]Flags:
-a, --address: Backend service address (default:localhost:9002)--password-file: Authorization password file (default:secrets/internal_auth_password)--superadmin-password-file: Superadmin password file (default:secrets/superadmin)-f, --file: JSON initial data file or-for stdin
Behavior:
- Sets up organization and default data
- Sets superadmin (user ID 1) password
- Returns error if datastore is not empty (exit code 2)
Example:
# With default data
osmanage initial-data \
--address localhost:9002 \
--password-file secrets/internal_auth_password \
--superadmin-password-file secrets/superadmin
# With custom initial data
osmanage initial-data \
--address localhost:9002 \
--password-file secrets/internal_auth_password \
--superadmin-password-file secrets/superadmin \
--file initial-data.jsonManage OpenSlides database migrations.
Subcommands:
migrate: Prepare migrations (dry-run)finalize: Prepare and apply migrationsreset: Reset unapplied migrationsclear-collectionfield-tables: Clear auxiliary tables (offline only)stats: Show migration statisticsprogress: Query progress of running migration
Common Flags:
-a, --address: Backend service address (default:localhost:9002)--password-file: Authorization password file (default:secrets/internal_auth_password)--interval: Progress polling interval (default:1s, use0to disable)
Features:
- Automatic retry with exponential backoff
- Real-time progress tracking
- Context-aware timeouts
- Network error handling
Examples:
# Prepare migrations (dry-run)
osmanage migrations migrate --address localhost:9002
# Apply migrations with progress
osmanage migrations finalize \
--address localhost:9002 \
--password-file secrets/internal_auth_password
# Apply migrations without progress output
osmanage migrations finalize \
--address localhost:9002 \
--interval 0
# Check migration status
osmanage migrations stats --address localhost:9002
# Monitor running migration
osmanage migrations progress --address localhost:9002
# Reset migrations
osmanage migrations reset --address localhost:9002Migration 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
Update OpenSlides objects using backend actions.
Usage:
osmanage set <action> [payload] [flags]Supported Actions:
agenda_itemcommitteegroupmeetingmotionorganizationorganization_tagprojectorthemetopicuser
Flags:
-a, --address: Backend service address (default:localhost:9002)--password-file: Authorization password file (default:secrets/internal_auth_password)-f, --file: JSON payload file or-for stdin
Examples:
# Update user
osmanage set user '[{"id": 5, "first_name": "Jane", "last_name": "Smith"}]'
# Update meeting from file
osmanage set meeting --file meeting-update.json
# Update organization
osmanage set organization '[{"id": 1, "name": "Updated Organization Name"}]'Change a user's password.
Usage:
osmanage set-password [flags]Flags:
-a, --address: Backend service address (default:localhost:9002)--password-file: Authorization password file (default:secrets/internal_auth_password)-u, --user_id: User ID (required)-p, --password: New password (required)
Example:
osmanage set-password \
--address localhost:9002 \
--user_id 5 \
--password "newSecurePassword123"Set via the --log-level flag (applies to all commands):
osmanage --log-level debug get userAvailable levels:
debug: Detailed diagnostic informationinfo: General informational messages (default)warn: Warning messageserror: Error messages only
Example output:
[INFO] === GET COLLECTION ===
[DEBUG] Collection: user
[DEBUG] Found 150 total users
[DEBUG] Fields to fetch: [id first_name last_name email is_active]
[INFO] Query completed successfully
# 1. Generate deployment configuration
osmanage setup ./openslides-deployment \
--config config.yml \
--template templates/docker-compose.yml
# 2. Start services (Docker Compose example)
cd openslides-deployment
docker-compose up -d
# 3. Access OpenSlides
# Visit http://localhost:8000
# Login as 'superadmin' with password from:
cat secrets/superadmin# Export all users to JSON
osmanage get user > backup-users-$(date +%Y%m%d).json
# Export specific fields only
osmanage get user \
--fields username,first_name,last_name,email \
> 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
# Count active meetings
osmanage get meeting \
--filter is_active_in_organization_id=1 \
| jq 'length'
# See if an active meeting exists by id
osmanage get meeting \
--filter-raw '{"and_filter": [{"field": "id", "operator": "=", "value": 1}, {"field": "is_active_in_organization_id", "operator": "=", "value": 1}]}'
--exists
# easier (id=5)
osmanage get meeting --filter is_active_in_organization=1 --fields name | jq '. "5"'openslides-cli/
├── cmd/
│ └── osmanage/ # Main entry point
│ └── main.go
├── internal/
│ ├── actions/ # Action commands
│ │ ├── action/
│ │ │ └── action.go
│ │ ├── createuser/
│ │ │ └── createuser.go
│ │ ├── get/
│ │ │ ├── get.go
│ │ │ └── get_test.go
│ │ ├── initialdata/
│ │ │ └── initialdata.go
│ │ ├── set/
│ │ │ └── set.go
│ │ └── setpassword/
│ │ └── setpassword.go
│ ├── client/ # HTTP client
│ │ ├── client.go
│ │ └── client_test.go
│ ├── logger/ # Logging
│ │ ├── logger.go
│ │ └── logger_test.go
│ ├── migrations/ # Migration commands
│ │ ├── migrations.go
│ │ └── migrations_test.go
│ ├── templating/ # Setup & templating
│ │ ├── config/
│ │ └── setup/
│ └── utils/ # Utilities
│ ├── utils.go
│ └── utils_test.go
├── go.mod
├── go.sum
├── README.md
└── LICENSE
# Run all tests
go test ./...
# Run tests with coverage
go test -cover ./...# Build for testing (bigger binary, debuggable)
go build -o osmanage ./cmd/osmanage
# Build for prod (smaller binary, no C code, no debug)
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 ./...) - 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
This tool represents a significant refactor and expansion of the original openslides-manage-service created by Norman Jäckel.
Major Changes from Original:
- Migration from
datastorereadertoopenslides-go/datastore/dsfetch - Removed gRPC
- Filtering in-memory (until better solution is found -> TODO)
- retry mechanism for migrations
- Comprehensive test coverage
- Improved deployment configuration system
- Simplified the templating
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