From 60dd31fd1cb822600147ccd4292f05c85482a1d3 Mon Sep 17 00:00:00 2001 From: Menno van Leeuwen Date: Tue, 23 Sep 2025 17:26:44 +0200 Subject: [PATCH] Add --system flag to update system packages in update.py --- bin/actions/update.py | 86 ++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 81 insertions(+), 5 deletions(-) diff --git a/bin/actions/update.py b/bin/actions/update.py index 1c10bde..4963cd5 100755 --- a/bin/actions/update.py +++ b/bin/actions/update.py @@ -31,6 +31,7 @@ def help_message(): " --full-speed, -F Upgrade packages and use all available cores for compilation. (Default: 8 cores)", ) printfe("green", " --skip-check, -s Skip checking for dotfiles updates.") + printfe("green", " --system, -S Update system packages (flatpak, brew, apt, etc.)") printfe("green", " --help, -h Display this help message.") return 0 @@ -242,6 +243,68 @@ def get_sudo_password_from_1password(username, hostname): return None +def get_distro(): + """Detect the Linux distribution.""" + try: + with open('/etc/os-release', 'r') as f: + for line in f: + if line.startswith('ID='): + return line.split('=', 1)[1].strip().strip('"').lower() + except: + return None + + +def update_system_packages(sudo_password): + """Update system packages using available package managers.""" + # System package updates + printfe("cyan", "Checking for system package updates...") + + # Check for flatpak + status, _ = run_command(["which", "flatpak"], shell=False) + if status: + printfe("cyan", "Updating Flatpak packages...") + result = subprocess.run(["flatpak", "update", "-y"], check=False) + if result.returncode != 0: + printfe("yellow", "Flatpak update failed.") + + # Check for brew + status, _ = run_command(["which", "brew"], shell=False) + if status: + printfe("cyan", "Updating Homebrew packages...") + result = subprocess.run(["brew", "update"], check=False) + if result.returncode == 0: + result = subprocess.run(["brew", "upgrade"], check=False) + if result.returncode != 0: + printfe("yellow", "Brew upgrade failed.") + else: + printfe("yellow", "Brew update failed.") + + # Distro specific updates + distro = get_distro() + if distro: + printfe("cyan", f"Detected distro: {distro}") + sudo_cmd = ["sudo", "-S"] + if distro in ["ubuntu", "debian"]: + cmds = [["apt", "update"], ["apt", "upgrade", "-y"]] + elif distro == "arch": + cmds = [["pacman", "-Syu", "--noconfirm"]] + elif distro in ["fedora", "rhel", "centos"]: + cmds = [["yum", "update", "-y"]] + else: + cmds = [] + for cmd in cmds: + full_cmd = sudo_cmd + cmd + printfe("cyan", f"Running: {' '.join(full_cmd)}") + if sudo_password: + result = subprocess.run(full_cmd, input=sudo_password + "\n", text=True, check=False) + else: + result = subprocess.run(full_cmd, check=False) + if result.returncode != 0: + printfe("yellow", "Command failed.") + else: + printfe("yellow", "Could not detect distro, skipping package manager updates.") + + def main(): # Parse arguments parser = argparse.ArgumentParser(add_help=False) @@ -271,15 +334,29 @@ def main(): help="Skip checking for dotfiles updates", ) + parser.add_argument( + "--system", + "-S", + action="store_true", + help="Update system packages (flatpak, brew, apt, etc.)", + ) + args = parser.parse_args() if args.help: return help_message() + username = os.environ.get("USER", os.environ.get("USERNAME", "user")) + hostname = os.uname().nodename + sudo_password = None + if os.isatty(sys.stdin.fileno()): + sudo_password = get_sudo_password_from_1password(username, hostname) + # If no specific option provided, run all if not args.ha and not args.ansible and not args.ansible_verbose: args.ha = True args.ansible = True + args.system = True # If ansible_verbose is set, also set ansible if args.ansible_verbose: @@ -293,6 +370,9 @@ def main(): else: printfe("yellow", "Skipping dotfiles repository update check (--skip-check).") + if args.system: + update_system_packages(sudo_password) + # Set cores and jobs based on full-speed flag if args.full_speed: import multiprocessing @@ -364,8 +444,6 @@ def main(): dotfiles_path = os.environ.get( "DOTFILES_PATH", os.path.expanduser("~/.dotfiles") ) - hostname = os.uname().nodename - username = os.environ.get("USER", os.environ.get("USERNAME", "user")) # Ensure required collections are installed if not ensure_ansible_collections(): @@ -390,7 +468,6 @@ def main(): hostname, ] - sudo_password = None if not os.isatty(sys.stdin.fileno()): printfe( "yellow", @@ -398,7 +475,6 @@ def main(): ) ansible_cmd.append("--ask-become-pass") else: - sudo_password = get_sudo_password_from_1password(username, hostname) if sudo_password: ansible_cmd.extend(["--become-pass-file", "-"]) else: @@ -420,7 +496,7 @@ def main(): # Execute the Ansible command, passing password via stdin if available if sudo_password: result = subprocess.run( - ansible_cmd, input=sudo_password.encode("utf-8"), check=False + ansible_cmd, input=sudo_password + "\n", text=True, check=False ) else: result = subprocess.run(ansible_cmd, check=False)