jps-systemctl-utils
A Python utility for automating systemctl service management operations with comprehensive logging and reporting.
🚀 Overview
jps-systemctl-utils provides a simple, sequential utility to manage systemd services in bulk. It automates the common workflow of checking status, stopping, starting, and verifying services, with full logging and detailed reports.
Features
- ✅ YAML Configuration - Define services and safety checks in structured YAML format
- 🔄 Automated Workflow - Runs
status → stop → start → statusfor each service - 🛡️ Safety Checks - Configurable pre-restart checks to prevent unsafe operations
- 📊 Progress Tracking - Real-time progress bar using Rich
- 📝 Comprehensive Logging - Dual logging to file (INFO) and stderr (WARNING+)
- 📋 Detailed Reports - Timestamped reports with all command outputs
- 🧪 Dry-run Mode - Test your workflow without executing commands
- ⚙️ Flexible Configuration - Custom output directories, log files, and reports
- 🎯 Smart Skipping - Automatically skip services with active jobs
Use Cases
- Restarting multiple services after configuration changes
- Performing routine service maintenance
- Testing service restart procedures
- Documenting service states before/after operations
- Automating deployment workflows
📦 Installation
From Source
git clone https://github.com/jai-python3/jps-systemctl-utils.git
cd jps-systemctl-utils
make install
For Development
make install-dev-tools
🎯 Usage
Basic Usage
Create a YAML configuration file with services and optional safety checks:
# services.yaml
---
nginx.service:
# No safety checks - will always restart
apache2.service:
mysql.service:
postgresql.service:
Run the utility:
jps-systemctl-utils-restart-services --infile services.yaml
Advanced: YAML Configuration with Safety Checks
For more control, use a YAML configuration file with safety check commands:
# services.yaml
---
nginx.service:
- pgrep -f nginx_backup
- test -f /var/lock/nginx.lock
apache2.service:
- systemctl is-active httpd-backup
mysql.service:
- pgrep -f mysqldump
- pgrep -f mysql_backup
postgresql.service:
# No safety checks - will always restart
Run with safety checks:
jps-systemctl-utils-restart-services --infile services.yaml
How Safety Checks Work:
- Each service can have a list of shell commands to execute before restarting
- If ANY command returns output, the service restart is skipped
- If all commands return no output, it's safe to restart
- Services without safety checks are always restarted (if no jobs found)
- Useful for checking if batch jobs, database operations, or critical processes are running
Dry-run Mode
Test without executing commands:
jps-systemctl-utils-restart-services --infile services.txt --dryrun
Custom Output Location
jps-systemctl-utils-restart-services --infile services.txt --outdir /var/log/service-ops
Full Control
jps-systemctl-utils-restart-services \
--infile services.txt \
--outdir /custom/output \
--report-file /custom/report.txt \
--logfile /custom/app.log \
--dryrun
Example Output Structure
Default output location: /tmp/<username>/systemctl_runner/<timestamp>/
/tmp/myuser/systemctl_runner/2025-12-13-143000/
├── systemctl_runner_report.txt # Detailed command outputs
└── systemctl_runner.log # Application logs
Report Format
The generated report includes safety check results and command outputs:
## method-created: /path/to/restart_services.py
## date-created: 2025-12-13 14:30:00
## created-by: myuser
## logfile: /tmp/myuser/restart_services/2025-12-13-143000/restart_services.log
## infile: /path/to/services.yaml
# Service: nginx.service
# Running safety checks for nginx.service:
$ pgrep -f nginx_backup
(exit: 0)
# Safety checks PASSED: Safe to restart nginx.service
$ systemctl status nginx.service
● nginx.service - A high performance web server
Loaded: loaded (/etc/systemd/system/nginx.service)
Active: active (running)
(exit: 0)
$ systemctl stop nginx.service
(exit: 0)
$ systemctl start nginx.service
(exit: 0)
$ systemctl status nginx.service
● nginx.service - A high performance web server
Active: active (running)
(exit: 0)
# Service: mysql.service
# Running safety checks for mysql.service:
$ pgrep -f mysql_backup
12345
mysql_backup_process
(exit: 0)
# Safety check FAILED: Output detected, service has active jobs
⚠️ SKIPPING mysql.service: Safety check failed - jobs are still running
📚 API Documentation
Command-line Options
| Option | Type | Required | Description |
|---|---|---|---|
--infile |
Path | Yes | YAML file with service configurations and safety checks |
--outdir |
Path | No | Output directory for logs and reports |
--report-file |
Path | No | Custom path for the report file |
--logfile |
Path | No | Custom path for the log file |
--dryrun |
Flag | No | If set, no systemctl commands are executed (safety checks bypassed) |
Input File Format
YAML Format:
---
service_name.service:
- safety_check_command_1
- safety_check_command_2
another_service.service:
# Empty list, null, or omitted means no safety checks
third_service.service: null
fourth_service.service: []
Safety Check Examples:
pgrep -f process_name- Check for running processespgrep -f backup_script- Check if backup is runningsystemctl is-active dependent-service- Check dependent servicescurl -s http://localhost/health | grep OK- Health check endpointstest -f /var/lock/myservice.lock- Check for lock filesps aux | grep 'my_job' | grep -v grep- Check for specific jobs
🧪 Development
Running Tests
# Run all tests with coverage
make test
# Run specific test file
pytest tests/test_processor.py -v
# Run with detailed coverage report
pytest tests/ -v --cov=src/jps_systemctl_utils --cov-report=html
Code Quality
# Auto-fix code issues
make fix
# Format code with black
make format
# Run linting
make lint
# Run all quality checks
make fix && make format && make lint
Pre-commit Hooks
# Install pre-commit hooks
make precommit
Building and Publishing
# Build distribution packages
make build
# Check built packages
make check-build
# Publish to PyPI (with dry-run option)
make publish DRYRUN=1
make publish
🏗️ Project Structure
jps-systemctl-utils/
├── src/
│ └── jps_systemctl_utils/
│ ├── __init__.py # Package version
│ ├── constants.py # Logging constants
│ ├── logging_helper.py # Logging configuration
│ ├── processor.py # Core service processing logic
│ ├── report_writer.py # Report generation
│ └── systemctl_runner.py # CLI entry point
├── tests/
│ ├── conftest.py # Shared fixtures
│ ├── test_constants.py # Constants tests
│ ├── test_logging_helper.py # Logging tests
│ ├── test_processor.py # Processor tests
│ ├── test_report_writer.py # Report writer tests
│ └── test_systemctl_runner.py # CLI tests
├── pyproject.toml # Project metadata
├── Makefile # Development commands
└── README.md # This file
🧩 Requirements
- Python 3.10+
- typer >= 0.12.3
- rich >= 13.0.0
- pyyaml >= 6.0.0
🤝 Contributing
Contributions are welcome! Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git checkout -b feature/AmazingFeature) - Run tests (
make test) - Commit your changes (
git commit -m 'Add some AmazingFeature') - Push to the branch (
git push origin feature/AmazingFeature) - Open a Pull Request
📝 Changelog
See CHANGELOG.md for version history.
📄 License
MIT License © Jaideep Sundaram
🔗 Links
⚠️ Disclaimer
This tool executes systemctl commands that affect system services. Always:
- Test with
--dryrunfirst - Review the service list carefully
- Have appropriate system permissions
- Back up important configurations
- Use in controlled environments
Metadata
Release files for jps-systemctl-utils 0.3.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| jps_systemctl_utils-0.3.0.tar.gz | 20.1 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| jps_systemctl_utils-0.3.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 31.0 kB
Release files / jps_systemctl_utils-0.3.0.tar.gz
| Download URL | jps_systemctl_utils-0.3.0.tar.gz |
|---|---|
| Size | 20.1 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e4e41ab4c065528c59b3c1122a38c1e18e8a7c3859bc2716c4668e1d33e84c66
|
|
BLAKE2b-256 checksum How to use checksums |
c3426ef085746e0648135439e877539e34b0fb3db04834d93f2c4ef74c0f1735
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|
Release files / jps_systemctl_utils-0.3.0-py3-none-any.whl
| Download URL | jps_systemctl_utils-0.3.0-py3-none-any.whl |
|---|---|
| Size | 10.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
281dc663099cb27a03eb878ac9ccaa212e605802cbcd6865659a362053a8e26b
|
|
BLAKE2b-256 checksum How to use checksums |
b7d1b49327ce81539a901bfc7530cf528950a98f1307b46a8250f15c422c9c2f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.12.3
|