Skip to content

Linktech-Engineering-LLC/RunUpdates

RunUpdates

Linktech Engineering Tools Suite Status Python Platform Last Commit License

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.


✨ Features

  • 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)
  • 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


📦 Installation

git clone https://github.com/Linktech-Engineering-LLC/RunUpdates.git
cd RunUpdates
python3 -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt

RunUpdates is now ready to use.

🧩 Inventory Model

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]

Inventory hierarchy

  • 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 Model

Secrets are loaded from a vault file or environment variables.

Required fields

username: "ssh username"
password: "optional ssh + sudo password"
keyfile: "/path/to/private/key"

Authentication model

  • 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.

🚀 Usage

List operations

runupdates --list-families
runupdates --list-distros
runupdates --list-hosts
runupdates --list-inventory

Execute updates

Run against a family:

runupdates --family linux

Run against a specific distro:

runupdates --family linux --distro opensuse

Run against a single host:

runupdates --host Lab-Suse-01

Dry‑run mode:

runupdates --dry-run

🛠 Execution Flow

Each host runs the following steps in order:

  1. Pre‑update list
  2. Update execution
  3. Post‑update list
  4. Reboot detection
  5. Summary generation

Each step is logged with:

  • exit code
  • stdout/stderr
  • classification (success/warning/error/fatal)

Failures do not stop the overall run.

For full details, see: 📄 Execution

🧱 Architecture Overview

text main.py └── UpdateOrchestrator ├── InventoryProcessor ├── HostSelector ├── HostConnector │ ├── local (sudo_run) │ └── SSHSession └── HostExecutor

Responsibilities

  • 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: 📄 ARCHITECTURE

🧪 Error Classification

RunUpdates uses a unified, distro‑agnostic classification model:

  • success
  • warning
  • error
  • fatal

Mapped from exit codes and PythonTools exceptions.

Full classification rules:

📄 Error_Classification

🔒 Security Model

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

Full security policy: 📄 SECURITY

PythonTools Integration

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_run for privileged local execution
  • local_command for non‑privileged local execution
  • SSHSession for 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.

🤝 Contributing

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

Full guidelines: 📄 CONTRIBUTING

📄 License

MIT License — see LICENSE for details.

🔗 Related Projects

RunUpdates is part of the Linktech Engineering Tools Suite.
You may also find these projects useful:

About

“Cross‑platform update orchestrator that applies OS update instructions defined in Ansible‑style inventory files. Supports Linux package managers and Windows PowerShell update workflows.

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Releases

No releases published

Contributors

Languages