# _ __________________ # | | / / _/ ____/ _/ / # | | / // // / __ / // / # | |/ // // /_/ // // /___ # |___/___/\____/___/_____/ # © Uthmn 2025 under MIT license import subprocess import os import sys import re def require_root(): if os.geteuid() != 0: print("This script requires root privileges. Please run with sudo.") sys.exit(1) def detect_apt(): try: subprocess.run(["apt", "--version"], capture_output=True, text=True, check=True) return True except FileNotFoundError: return False except subprocess.CalledProcessError as e: raise RuntimeError(f"Error running apt: {e.stderr or e}") def check_updates(): # Update package list try: subprocess.run(["apt", "update"], capture_output=True, text=True, check=True) except FileNotFoundError: raise FileNotFoundError("apt not found on this system.") except subprocess.CalledProcessError as e: raise RuntimeError(f"Error running 'apt update': {e.stderr or e.stdout or e}") # List upgradable packages try: result = subprocess.run( ["apt", "list", "--upgradable"], capture_output=True, text=True, check=True ) upgrades = result.stdout.strip() lines = [line for line in upgrades.splitlines() if line.strip()] if len(lines) <= 1: # Only the header return {} # No upgrades package_dict = {} for line in lines[1:]: # skip header # Example line format: # docker-ce/focal-security 5:24.0.1~3-0~ubuntu-focal amd64 [upgradable from: 5:23.0.0~3-0~ubuntu-focal] match = re.match( r"([^/]+)/([^\s]+)\s+([^\s]+)\s+[^\s]+\s+\[upgradable from: ([^\]]+)\]", line ) if match: name, repo, latest_version, installed_version = match.groups() # Detect security update based on repo name containing "security" is_security = "security" in repo.lower() package_dict[name] = { "installed_version": installed_version, "latest_version": latest_version, "repo": repo, "security": is_security } return package_dict except subprocess.CalledProcessError as e: raise RuntimeError(f"Error running 'apt list --upgradable': {e.stderr or e.stdout or e}") if __name__ == "__main__": require_root() if detect_apt(): updates = check_updates() print(updates)