RunUpdates is a deterministic, operator‑grade update orchestrator for Linux hosts.
It provides reproducible sequencing, audit‑transparent execution, and a clean, YAML‑driven model for managing package updates across heterogeneous environments.
RunUpdates is designed for engineers who want predictable behavior, clear logging, and a workflow that scales from a single workstation to a full fleet.
-
Deterministic execution pipeline
Pre‑update list → Update → Post‑update list → Reboot detection → Summary generation -
Inventory‑driven orchestration
Families → Distros → Hosts with inheritance, flattening, and strict validation -
Local + remote execution
- Local execution via
sudo_run - Remote execution via
SSHSession(keyfile preferred, password fallback)
- Local execution via
-
Declarative distro model
Commands, exit‑codes, and reboot indicators defined per distro -
Operator‑grade logging
Structured, timestamped, redacted, and suitable for audit trails -
Flexible host selection
--family,--distro,--host, or full‑inventory runs -
Dry‑run mode
Preview commands without executing them -
Machine‑readable summaries
Per‑host JSON summaries for dashboards and automation
git clone https://github.com/Linktech-Engineering-LLC/RunUpdates.git
cd RunUpdates
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txtRunUpdates is now ready to use.
RunUpdates uses a structured YAML inventory that defines:
- distro families
- package manager commands
- exit‑code interpretation
- host lists
- connection parameters
*** Example (openSUSE)
Note: All values below (ports, addresses, hostnames) are placeholders. Replace them with your actual environment.
linux:
opensuse:
packages:
check: "zypper patch-check --with-optional"
refresh: "zypper refresh"
update: "zypper --non-interactive up --auto-agree-with-licenses --recommends --replacefiles --allow-vendor-change"
clean: "zypper clean"
orphans: "zypper packages --orphaned"
list: "zypper list-updates --all"
reboot: "zypper needs-rebooting"
reboot_now: "systemctl reboot || shutdown -r now"
exit_codes:
refresh:
success: [0]
error: ["*"]
check:
up_to_date: [0]
patches_available: [100, 101]
error: ["*"]
update:
success: [0]
reboot_required: [102, 104]
restart_services: [103]
error: ["*"]
reboot:
no_reboot: [0]
reboot_required: [102]
restart_services: [103]
reboot_and_restart: [104]
error: ["*"]
port: nnnn # Non-Standard Port used for ssh
hosts:
sample_host:
enabled: true
address: [nnn.nnn.nnn.nnn, nnn.nnn.nnn.nnn]- Family (e.g., linux)
- Distro (e.g., opensuse)
- Hosts (e.g., Lab-Suse-01)
RunUpdates merges:
- family defaults
- distro defaults
- host overrides
…into a flattened host object used during execution.
Secrets are loaded from a vault file or environment variables.
username: "ssh username"
password: "optional ssh + sudo password"
keyfile: "/path/to/private/key"- username → SSH username
- keyfile → primary SSH authentication
- password → fallback SSH authentication + sudo password
At least one authentication method must be available.
RunUpdates injects secrets into PythonTools at startup. Secrets are never logged or written to disk.
runupdates --list-families
runupdates --list-distros
runupdates --list-hosts
runupdates --list-inventoryRun against a family:
runupdates --family linuxRun against a specific distro:
runupdates --family linux --distro opensuseRun against a single host:
runupdates --host Lab-Suse-01Dry‑run mode:
runupdates --dry-runEach host runs the following steps in order:
- Pre‑update list
- Update execution
- Post‑update list
- Reboot detection
- Summary generation
Each step is logged with:
- exit code
- stdout/stderr
- classification (success/warning/error/fatal)
Failures do not stop the overall run.
text main.py └── UpdateOrchestrator ├── InventoryProcessor ├── HostSelector ├── HostConnector │ ├── local (sudo_run) │ └── SSHSession └── HostExecutor
- InventoryProcessor → flattens and normalizes inventory
- HostSelector → determines which hosts should run
- HostConnector → selects local vs remote execution
- HostExecutor → runs the distro‑defined pipeline
- PythonTools → provides execution primitives and session layer
For full architecture details:
RunUpdates uses a unified, distro‑agnostic classification model:
- success
- warning
- error
- fatal
Mapped from exit codes and PythonTools exceptions.
Full classification rules:
RunUpdates is designed with a minimal attack surface:
- no dynamic code execution
- no YAML‑driven logic paths
- no secrets in logs
- SSH keyfile preferred
- deterministic logging
- strict inventory validation
RunUpdates is built on top of a shared execution layer called PythonTools, which provides the deterministic command‑execution substrate used across the Linktech Engineering Tools Suite.
PythonTools supplies:
sudo_runfor privileged local executionlocal_commandfor non‑privileged local executionSSHSessionfor remote execution- structured logging injection
- secrets injection
- consistent return structures
- reusable helpers (in progress)
PythonTools is currently embedded within RunUpdates for rapid iteration, but it is architected for extraction into a standalone Linktech Engineering micro‑library.
Once extracted, RunUpdates, BotScanner, TimerDeck, and future tools will share a unified execution model.
Pull requests are welcome.
Please ensure:
- deterministic behavior
- no breaking changes to the inventory schema
- clear, structured logging
- placeholder‑only examples
- documentation updates for new features
MIT License — see LICENSE for details.
RunUpdates is part of the Linktech Engineering Tools Suite.
You may also find these projects useful:
-
NMS_Tools
A suite of deterministic Nagios-compatible monitoring tools with structured logging and operator‑grade output.
https://github.com/Linktech-Engineering-LLC/NMS_Tools -
VSCode-Updater
A cross‑platform, operator‑grade updater for Visual Studio Code with deterministic logging and reproducible workflows.
https://github.com/Linktech-Engineering-LLC/VSCode-Updater -
BotScanner
A lightweight, deterministic scanning tool for identifying automated traffic patterns and bot signatures.
https://github.com/Linktech-Engineering-LLC/BotScanner -
licensegen
A simple, reproducible license generator supporting SPDX identifiers and clean header injection.
https://github.com/Linktech-Engineering-LLC/licensegen -
rust_logger
A minimal, deterministic logging library for Rust projects with operator‑grade formatting.
https://github.com/Linktech-Engineering-LLC/rust_logger