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()
|