aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
Diffstat (limited to 'tools')
-rw-r--r--tools/default.nix1
-rw-r--r--tools/waybar-systemd-units/default.nix27
-rwxr-xr-xtools/waybar-systemd-units/waybar-systemd.py75
3 files changed, 103 insertions, 0 deletions
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()