chiark / gitweb /
systemadm: show dependencies in the UI
[elogind.git] / systemadm.vala
index 6ea464f58dba461ab3d1d86aa9fbaf6cc8fdc40a..de2fa3ae9c6d1fae988520f5c9bd3cc95c6aef0d 100644 (file)
@@ -47,6 +47,13 @@ public class RightLabel : Label {
                 else
                         set_text(text);
         }
+
+        public void set_markup_or_na(string? text = null) {
+                if (text == null || text == "")
+                        set_markup("<i>n/a</i>");
+                else
+                        set_markup(text);
+        }
 }
 
 public class MainWindow : Window {
@@ -66,6 +73,9 @@ public class MainWindow : Window {
         private Button reload_button;
         private Button cancel_button;
 
+        private Entry unit_load_entry;
+        private Button unit_load_button;
+
         private Button server_snapshot_button;
         private Button server_reload_button;
 
@@ -74,6 +84,7 @@ public class MainWindow : Window {
 
         private RightLabel unit_id_label;
         private RightLabel unit_aliases_label;
+        private RightLabel unit_dependency_label;
         private RightLabel unit_description_label;
         private RightLabel unit_load_state_label;
         private RightLabel unit_active_state_label;
@@ -126,7 +137,19 @@ public class MainWindow : Window {
                 unit_type_combo_box.set_active(1);
                 unit_type_combo_box.changed += unit_type_changed;
 
-                server_snapshot_button = new Button.with_mnemonic("Take _Snapshot");
+                unit_load_entry = new Entry();
+                unit_load_button = new Button.with_mnemonic("_Load");
+                unit_load_button.set_sensitive(false);
+
+                unit_load_entry.changed += on_unit_load_entry_changed;
+                unit_load_entry.activate += on_unit_load;
+                unit_load_button.clicked += on_unit_load;
+
+                Box unit_load_hbox = new HBox(false, 6);
+                unit_load_hbox.pack_start(unit_load_entry, false, true, 0);
+                unit_load_hbox.pack_start(unit_load_button, false, true, 0);
+
+                server_snapshot_button = new Button.with_mnemonic("Take S_napshot");
                 server_reload_button = new Button.with_mnemonic("Reload _Configuration");
 
                 server_snapshot_button.clicked += on_server_snapshot;
@@ -134,6 +157,7 @@ public class MainWindow : Window {
 
                 type_hbox.pack_end(server_snapshot_button, false, true, 0);
                 type_hbox.pack_end(server_reload_button, false, true, 0);
+                type_hbox.pack_end(unit_load_hbox, false, true, 24);
 
                 unit_model = new ListStore(7, typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(Unit));
                 job_model = new ListStore(6, typeof(string), typeof(string), typeof(string), typeof(string), typeof(Job), typeof(uint32));
@@ -173,6 +197,7 @@ public class MainWindow : Window {
 
                 unit_id_label = new RightLabel();
                 unit_aliases_label = new RightLabel();
+                unit_dependency_label = new RightLabel();
                 unit_description_label = new RightLabel();
                 unit_load_state_label = new RightLabel();
                 unit_active_state_label = new RightLabel();
@@ -188,6 +213,10 @@ public class MainWindow : Window {
                 job_state_label = new RightLabel();
                 job_type_label = new RightLabel();
 
+                unit_dependency_label.set_track_visited_links(false);
+                unit_dependency_label.set_selectable(false);
+                unit_dependency_label.activate_link += on_activate_link;
+
                 Table unit_table = new Table(8, 6, false);
                 unit_table.set_row_spacings(6);
                 unit_table.set_border_width(0);
@@ -204,27 +233,29 @@ public class MainWindow : Window {
                 unit_table.attach(unit_aliases_label,                       1, 6, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
                 unit_table.attach(new LeftLabel("Description:"),            0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
                 unit_table.attach(unit_description_label,                   1, 6, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(new LeftLabel("Fragment Path:"),          0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(unit_fragment_path_label,                 1, 6, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(new LeftLabel("Control Group:"),          0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(unit_cgroup_label,                        1, 6, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-
-                unit_table.attach(new LeftLabel("Load State:"),             0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(unit_load_state_label,                    1, 2, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(new LeftLabel("Active State:"),           0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(unit_active_state_label,                  1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(new LeftLabel("Unit State:"),             0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(unit_sub_state_label,                     1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-
-                unit_table.attach(new LeftLabel("Active Enter Timestamp:"), 2, 3, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(unit_active_enter_timestamp_label,        3, 4, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(new LeftLabel("Active Exit Timestamp:"),  2, 3, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(unit_active_exit_timestamp_label,         3, 4, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-
-                unit_table.attach(new LeftLabel("Can Start/Stop:"),         4, 5, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(unit_can_start_label,                     5, 6, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(new LeftLabel("Can Reload:"),             4, 5, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
-                unit_table.attach(unit_can_reload_label,                    5, 6, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(new LeftLabel("Dependencies:"),           0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_dependency_label,                    1, 6, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(new LeftLabel("Fragment Path:"),          0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_fragment_path_label,                 1, 6, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(new LeftLabel("Control Group:"),          0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_cgroup_label,                        1, 6, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+
+                unit_table.attach(new LeftLabel("Load State:"),             0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_load_state_label,                    1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(new LeftLabel("Active State:"),           0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_active_state_label,                  1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(new LeftLabel("Unit State:"),             0, 1, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_sub_state_label,                     1, 2, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+
+                unit_table.attach(new LeftLabel("Active Enter Timestamp:"), 2, 3, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_active_enter_timestamp_label,        3, 4, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(new LeftLabel("Active Exit Timestamp:"),  2, 3, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_active_exit_timestamp_label,         3, 4, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+
+                unit_table.attach(new LeftLabel("Can Start/Stop:"),         4, 5, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_can_start_label,                     5, 6, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(new LeftLabel("Can Reload:"),             4, 5, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
+                unit_table.attach(unit_can_reload_label,                    5, 6, 8, 9, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
 
                 job_table.attach(new LeftLabel("Id:"),                      0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
                 job_table.attach(job_id_label,                              1, 2, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
@@ -374,6 +405,7 @@ public class MainWindow : Window {
                 unit_id_label.set_text_or_na();
                 unit_aliases_label.set_text_or_na();
                 unit_description_label.set_text_or_na();
+                unit_description_label.set_text_or_na();
                 unit_load_state_label.set_text_or_na();
                 unit_active_state_label.set_text_or_na();
                 unit_sub_state_label.set_text_or_na();
@@ -385,6 +417,30 @@ public class MainWindow : Window {
                 unit_cgroup_label.set_text_or_na();
         }
 
+        public string make_dependency_string(string? prefix, string word, string[] dependencies) {
+                bool first = true;
+                string r;
+
+                if (prefix == null)
+                        r = "";
+                else
+                        r = prefix;
+
+                foreach (string i in dependencies) {
+                        if (r != "")
+                                r += first ? "\n" : ",";
+
+                        if (first) {
+                                r += word;
+                                first = false;
+                        }
+
+                        r += " <a href=\"" + i + "\">" + i + "</a>";
+                }
+
+                return r;
+        }
+
         public void show_unit(Unit unit) {
                 current_unit_id = unit.id;
 
@@ -402,6 +458,44 @@ public class MainWindow : Window {
                 }
 
                 unit_aliases_label.set_text_or_na(a);
+
+                string[]
+                        requires = unit.requires,
+                        requires_overridable = unit.requires_overridable,
+                        requisite = unit.requisite,
+                        requisite_overridable = unit.requisite_overridable,
+                        wants = unit.wants,
+                        required_by = unit.required_by,
+                        required_by_overridable = unit.required_by_overridable,
+                        wanted_by = unit.wanted_by,
+                        conflicts = unit.conflicts,
+                        before = unit.before,
+                        after = unit.after;
+
+                unit_dependency_label.set_markup_or_na(
+                                make_dependency_string(
+                                make_dependency_string(
+                                make_dependency_string(
+                                make_dependency_string(
+                                make_dependency_string(
+                                make_dependency_string(
+                                make_dependency_string(
+                                make_dependency_string(
+                                make_dependency_string(
+                                make_dependency_string(
+                                make_dependency_string(null,
+                                "requires", requires),
+                                "overridable requires", requires_overridable),
+                                "requisite", requisite),
+                                "overridable requisite", requisite_overridable),
+                                "wants", wants),
+                                "conflicts", conflicts),
+                                "required by", required_by),
+                                "overridable required by", required_by_overridable),
+                                "wanted by", wanted_by),
+                                "after", after),
+                                "before", before));
+
                 unit_description_label.set_text_or_na(unit.description);
                 unit_load_state_label.set_text_or_na(unit.load_state);
                 unit_active_state_label.set_text_or_na(unit.active_state);
@@ -768,11 +862,62 @@ public class MainWindow : Window {
                 }
         }
 
+        public void on_unit_load() {
+                string t = unit_load_entry.get_text();
+
+                if (t == "")
+                        return;
+
+                try {
+                        var path = manager.load_unit(t);
+
+                        Unit u = bus.get_object(
+                                        "org.freedesktop.systemd1",
+                                        path,
+                                        "org.freedesktop.systemd1.Unit") as Unit;
+
+                        var m = new MessageDialog(this,
+                                                  DialogFlags.DESTROY_WITH_PARENT,
+                                                  MessageType.INFO,
+                                                  ButtonsType.CLOSE,
+                                                  "Unit available as id %s", u.id);
+                        m.title = "Unit";
+                        m.run();
+                        m.destroy();
+
+                } catch (DBus.Error e) {
+                        show_error(e.message);
+                }
+        }
+
+        public void on_unit_load_entry_changed() {
+                unit_load_button.set_sensitive(unit_load_entry.get_text() != "");
+        }
+
+        public bool on_activate_link(string uri) {
+
+                try {
+                        string path = manager.get_unit(uri);
+
+                        Unit u = bus.get_object(
+                                        "org.freedesktop.systemd1",
+                                        path,
+                                        "org.freedesktop.systemd1.Unit") as Unit;
+
+                        show_unit(u);
+                } catch (DBus.Error e) {
+                        show_error(e.message);
+                }
+
+                return true;
+        }
+
         public void show_error(string e) {
                 var m = new MessageDialog(this,
                                           DialogFlags.DESTROY_WITH_PARENT,
                                           MessageType.ERROR,
                                           ButtonsType.CLOSE, "%s", e);
+                m.title = "Error";
                 m.run();
                 m.destroy();
         }