From 9c7344efb4e3d663d26ddb81699c6572bbcfd148 Mon Sep 17 00:00:00 2001 From: Franck Cuny Date: Sun, 28 May 2023 16:32:53 -0700 Subject: tools/waybar-systemd-units: get a list of failed systemd units Get a list of failed systemd units (both user and systems), and generate an output compatible to what waybar expects. Refer to https://github.com/Alexays/Waybar/wiki/Module:-Custom for more details about the format. --- tools/default.nix | 1 + tools/waybar-systemd-units/default.nix | 27 ++++++++++ tools/waybar-systemd-units/waybar-systemd.py | 75 ++++++++++++++++++++++++++++ 3 files changed, 103 insertions(+) create mode 100644 tools/waybar-systemd-units/default.nix create mode 100755 tools/waybar-systemd-units/waybar-systemd.py (limited to 'tools') diff --git a/tools/default.nix b/tools/default.nix index f7051fb..368ce4f 100644 --- a/tools/default.nix +++ b/tools/default.nix @@ -8,4 +8,5 @@ pkgs.lib.makeScope pkgs.newScope (pkgs: { ipconverter = pkgs.callPackage ./ipconverter { }; perf-flamegraph-pid = pkgs.callPackage ./perf-flamegraph-pid { }; seqstat = pkgs.callPackage ./seqstat { }; + waybar-systemd-units = pkgs.callPackage ./waybar-systemd-units { }; }) diff --git a/tools/waybar-systemd-units/default.nix b/tools/waybar-systemd-units/default.nix new file mode 100644 index 0000000..70cac84 --- /dev/null +++ b/tools/waybar-systemd-units/default.nix @@ -0,0 +1,27 @@ +{ self, lib, python3, stdenvNoCC, pkgs }: + +stdenvNoCC.mkDerivation rec { + pname = "waybar-systemd-units"; + src = ./waybar-systemd.py; + version = "0.1.0"; + + buildInputs = [ (pkgs.python310.withPackages (ps: with ps; [ click ])) ]; + + propagatedBuildInputs = + [ (pkgs.python310.withPackages (ps: with ps; [ click ])) ]; + + dontUnpack = true; + dontBuild = true; + + installPhase = '' + mkdir -p $out/bin + cp $src $out/bin/${pname} + ''; + + meta = with lib; { + description = "Get a list of systemd units that have failed."; + license = with licenses; [ mit ]; + platforms = platforms.unix; + maintainers = with maintainers; [ fcuny ]; + }; +} diff --git a/tools/waybar-systemd-units/waybar-systemd.py b/tools/waybar-systemd-units/waybar-systemd.py new file mode 100755 index 0000000..de5c2e0 --- /dev/null +++ b/tools/waybar-systemd-units/waybar-systemd.py @@ -0,0 +1,75 @@ +#!/usr/bin/env python3 +import json +import subprocess +from typing import List + +import click + + +def _get_failed_units(cmd) -> List[str]: + res = subprocess.run(cmd, capture_output=True, check=True) + if res.returncode == 0: + units = json.loads(res.stdout) + return [unit.get("unit") for unit in units] + else: + click.echo(f"failed to run {cmd}", err=True) + return [] + + +@click.command() +@click.version_option(version="0.1.0") +def cli() -> int: + """ + Get a list of systemd units (system and users) that have + failed, and print the output in JSON, in a format compatible to + waybar. + """ + failed_system_units = _get_failed_units( + [ + "systemctl", + "list-units", + "-o", + "json", + "--state=failed", + ], + ) + + failed_user_units = _get_failed_units( + [ + "systemctl", + "--user", + "list-units", + "-o", + "json", + "--state=failed", + ], + ) + + failed_units = len(failed_user_units) + len(failed_system_units) + + # The output format documentation: + # https://github.com/Alexays/Waybar/wiki/Module:-Custom + output = {"text": failed_units, "class": "success"} + + if failed_units > 0: + output["class"] = "errors" + + tooltip = [] + + if len(failed_user_units) > 0: + tooltip.append("failed user units: {}".format(", ".join(failed_user_units))) + + if len(failed_system_units) > 0: + tooltip.append( + "failed system units: {}".format(", ".join(failed_system_units)) + ) + + output["tooltip"] = "\n".join(tooltip) + + click.echo(json.dumps(output)) + + return 0 + + +if __name__ == "__main__": + cli() -- cgit 1.4.1