1{ pkgs, lib, ... }:
2let
3 user = "alice";
4in
5{
6 name = "ayatana-indicators";
7
8 meta = {
9 maintainers = lib.teams.lomiri.members;
10 };
11
12 nodes.machine =
13 { config, ... }:
14 {
15 imports = [
16 ./common/auto.nix
17 ./common/user-account.nix
18 ];
19
20 test-support.displayManager.auto = {
21 enable = true;
22 inherit user;
23 };
24
25 services.xserver = {
26 enable = true;
27 desktopManager.mate.enable = true;
28 };
29 services.displayManager.defaultSession = lib.mkForce "mate";
30
31 services.ayatana-indicators = {
32 enable = true;
33 packages =
34 with pkgs;
35 [
36 ayatana-indicator-bluetooth
37 ayatana-indicator-datetime
38 ayatana-indicator-display
39 ayatana-indicator-messages
40 ayatana-indicator-power
41 ayatana-indicator-session
42 ayatana-indicator-sound
43 ]
44 ++ (with pkgs.lomiri; [
45 lomiri-indicator-datetime
46 lomiri-indicator-network
47 lomiri-telephony-service
48 ]);
49 };
50
51 # Setup needed by some indicators
52
53 services.accounts-daemon.enable = true; # messages
54
55 # Lomiri-ish setup for Lomiri indicators
56 # TODO move into a Lomiri module, once the package set is far enough for the DE to start
57
58 networking.networkmanager.enable = true; # lomiri-network-indicator
59 # TODO potentially urfkill for lomiri-network-indicator?
60
61 services.dbus.packages = with pkgs.lomiri; [ libusermetrics ];
62
63 environment.systemPackages = with pkgs.lomiri; [ lomiri-schemas ];
64
65 services.telepathy.enable = true;
66
67 users.users.usermetrics = {
68 group = "usermetrics";
69 home = "/var/lib/usermetrics";
70 createHome = true;
71 isSystemUser = true;
72 };
73
74 users.groups.usermetrics = { };
75 };
76
77 # TODO session indicator starts up in a semi-broken state, but works fine after a restart. maybe being started before graphical session is truly up & ready?
78 testScript =
79 { nodes, ... }:
80 let
81 runCommandOverServiceList = list: command: lib.strings.concatMapStringsSep "\n" command list;
82
83 runCommandOverAyatanaIndicators = runCommandOverServiceList nodes.machine.systemd.user.targets.ayatana-indicators.wants;
84
85 runCommandOverLomiriIndicators = runCommandOverServiceList nodes.machine.systemd.user.targets.lomiri-indicators.wants;
86 in
87 ''
88 start_all()
89 machine.wait_for_x()
90
91 # Desktop environment should reach graphical-session.target
92 machine.wait_for_unit("graphical-session.target", "${user}")
93
94 # MATE relies on XDG autostart to bring up the indicators.
95 # Not sure *when* XDG autostart fires them up, and awaiting pgrep success seems to misbehave?
96 machine.sleep(10)
97
98 # Now check if all indicators were brought up successfully, and kill them for later
99 ''
100 + (runCommandOverAyatanaIndicators (
101 service:
102 let
103 serviceExec = builtins.replaceStrings [ "." ] [ "-" ] service;
104 in
105 ''
106 machine.wait_until_succeeds("pgrep -u ${user} -f ${serviceExec}")
107 machine.succeed("pkill -f ${serviceExec}")
108 ''
109 ))
110 + ''
111
112 # Ayatana target is the preferred way of starting up indicators on SystemD session, the graphical session is responsible for starting this if it supports them.
113 # Mate currently doesn't do this, so start it manually for checking (https://github.com/mate-desktop/mate-indicator-applet/issues/63)
114 machine.systemctl("start ayatana-indicators.target", "${user}")
115 machine.wait_for_unit("ayatana-indicators.target", "${user}")
116
117 # Let all indicator services do their startups, potential post-launch crash & restart cycles so we can properly check for failures
118 # Not sure if there's a better way of awaiting this without false-positive potential
119 machine.sleep(10)
120
121 # Now check if all indicator services were brought up successfully
122 ''
123 + runCommandOverAyatanaIndicators (service: ''
124 machine.wait_for_unit("${service}", "${user}")
125 '')
126 + ''
127 # Stop the target
128 machine.systemctl("stop ayatana-indicators.target", "${user}")
129
130 # Let all indicator services do their shutdowns
131 # Not sure if there's a better way of awaiting this without false-positive potential
132 machine.sleep(10)
133
134 # Lomiri uses a different target, which launches a slightly different set of indicators
135 machine.systemctl("start lomiri-indicators.target", "${user}")
136 machine.wait_for_unit("lomiri-indicators.target", "${user}")
137
138 # Let all indicator services do their startups, potential post-launch crash & restart cycles so we can properly check for failures
139 # Not sure if there's a better way of awaiting this without false-positive potential
140 machine.sleep(10)
141
142 # Now check if all indicator services were brought up successfully
143 ''
144 + runCommandOverLomiriIndicators (service: ''
145 machine.wait_for_unit("${service}", "${user}")
146 '');
147}