about summary refs log tree commit diff
path: root/tools/waybar-systemd-units/waybar-systemd.py
blob: de5c2e09edb4d2c64762377fb3ad280728317fc7 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
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()