mirror of
https://github.com/systemd/systemd.git
synced 2024-11-27 12:13:33 +08:00
systemadm: implement basic control UI systemadm
This commit is contained in:
parent
b548631afc
commit
501c7d0b77
3
.gitignore
vendored
3
.gitignore
vendored
@ -5,3 +5,6 @@ test-job-type
|
||||
systemd-logger
|
||||
systemctl
|
||||
systemctl.c
|
||||
systemd-interfaces.c
|
||||
systemadm
|
||||
systemadm.c
|
||||
|
9
Makefile
9
Makefile
@ -29,7 +29,7 @@ COMMON= \
|
||||
dbus-unit.o \
|
||||
dbus-job.o
|
||||
|
||||
all: systemd test-engine test-job-type systemd-logger systemctl
|
||||
all: systemd test-engine test-job-type systemd-logger systemctl systemadm
|
||||
|
||||
systemd: main.o $(COMMON)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
@ -44,7 +44,10 @@ test-job-type: test-job-type.o $(COMMON)
|
||||
$(CC) $(CFLAGS) -o $@ $^ $(LIBS)
|
||||
|
||||
systemctl: systemctl.vala
|
||||
valac --save-temps systemctl.vala --pkg=dbus-glib-1 --pkg=posix
|
||||
valac -g --save-temps systemctl.vala systemd-interfaces.vala --pkg=dbus-glib-1 --pkg=posix
|
||||
|
||||
systemadm: systemadm.vala
|
||||
valac -g --save-temps systemadm.vala systemd-interfaces.vala --pkg=dbus-glib-1 --pkg=posix --pkg gee-1.0 --pkg gtk+-2.0
|
||||
|
||||
clean:
|
||||
rm -f *.o systemd test-engine systemctl
|
||||
rm -f *.o systemd test-engine systemctl systemadm
|
||||
|
438
systemadm.vala
Normal file
438
systemadm.vala
Normal file
@ -0,0 +1,438 @@
|
||||
using Gtk;
|
||||
using GLib;
|
||||
using DBus;
|
||||
using Pango;
|
||||
|
||||
public class LeftLabel : Label {
|
||||
public LeftLabel(string? text = null) {
|
||||
if (text != null)
|
||||
set_markup("<b>%s</b>".printf(text));
|
||||
set_alignment(1, 0);
|
||||
set_padding(6, 0);
|
||||
}
|
||||
}
|
||||
|
||||
public class RightLabel : Label {
|
||||
public RightLabel(string? text = null) {
|
||||
set_text_or_na(text);
|
||||
set_alignment(0, 1);
|
||||
set_ellipsize(EllipsizeMode.START);
|
||||
set_selectable(true);
|
||||
}
|
||||
|
||||
public void set_text_or_na(string? text = null) {
|
||||
if (text == null || text == "")
|
||||
set_markup("<i>n/a</i>");
|
||||
else
|
||||
set_text(text);
|
||||
}
|
||||
}
|
||||
|
||||
public class MainWindow : Window {
|
||||
|
||||
private TreeView unit_view;
|
||||
private TreeView job_view;
|
||||
|
||||
private ListStore unit_model;
|
||||
private ListStore job_model;
|
||||
|
||||
private Button start_button;
|
||||
private Button stop_button;
|
||||
private Button restart_button;
|
||||
private Button reload_button;
|
||||
private Button cancel_button;
|
||||
|
||||
private Connection bus;
|
||||
private Manager manager;
|
||||
|
||||
private RightLabel unit_id_label;
|
||||
private RightLabel unit_description_label;
|
||||
private RightLabel unit_load_state_label;
|
||||
private RightLabel unit_active_state_label;
|
||||
private RightLabel unit_load_path_label;
|
||||
private RightLabel unit_active_enter_timestamp_label;
|
||||
private RightLabel unit_active_exit_timestamp_label;
|
||||
private RightLabel unit_can_start_label;
|
||||
private RightLabel unit_can_reload_label;
|
||||
|
||||
private RightLabel job_id_label;
|
||||
private RightLabel job_state_label;
|
||||
private RightLabel job_type_label;
|
||||
|
||||
public MainWindow() throws DBus.Error {
|
||||
title = "systemdadm";
|
||||
position = WindowPosition.CENTER;
|
||||
set_default_size(1000, 700);
|
||||
set_border_width(12);
|
||||
destroy.connect(Gtk.main_quit);
|
||||
|
||||
Notebook notebook = new Notebook();
|
||||
add(notebook);
|
||||
|
||||
Box unit_vbox = new VBox(false, 6);
|
||||
notebook.append_page(unit_vbox, new Label("Units"));
|
||||
unit_vbox.set_border_width(12);
|
||||
|
||||
Box job_vbox = new VBox(false, 6);
|
||||
notebook.append_page(job_vbox, new Label("Jobs"));
|
||||
job_vbox.set_border_width(12);
|
||||
|
||||
|
||||
unit_model = new ListStore(6, typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string));
|
||||
job_model = new ListStore(5, typeof(string), typeof(string), typeof(string), typeof(string), typeof(string), typeof(string));
|
||||
|
||||
unit_view = new TreeView.with_model(unit_model);
|
||||
job_view = new TreeView.with_model(job_model);
|
||||
|
||||
unit_view.cursor_changed.connect(unit_changed);
|
||||
job_view.cursor_changed.connect(job_changed);
|
||||
|
||||
unit_view.insert_column_with_attributes(-1, "Unit", new CellRendererText(), "text", 0);
|
||||
unit_view.insert_column_with_attributes(-1, "Description", new CellRendererText(), "text", 1);
|
||||
unit_view.insert_column_with_attributes(-1, "Load State", new CellRendererText(), "text", 2);
|
||||
unit_view.insert_column_with_attributes(-1, "Active State", new CellRendererText(), "text", 3);
|
||||
unit_view.insert_column_with_attributes(-1, "Job", new CellRendererText(), "text", 4);
|
||||
|
||||
job_view.insert_column_with_attributes(-1, "Job", new CellRendererText(), "text", 0);
|
||||
job_view.insert_column_with_attributes(-1, "Unit", new CellRendererText(), "text", 1);
|
||||
job_view.insert_column_with_attributes(-1, "Type", new CellRendererText(), "text", 2);
|
||||
job_view.insert_column_with_attributes(-1, "State", new CellRendererText(), "text", 3);
|
||||
|
||||
ScrolledWindow scroll = new ScrolledWindow(null, null);
|
||||
scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
|
||||
scroll.set_shadow_type(ShadowType.IN);
|
||||
scroll.add(unit_view);
|
||||
unit_vbox.pack_start(scroll, true, true, 0);
|
||||
|
||||
scroll = new ScrolledWindow(null, null);
|
||||
scroll.set_policy(PolicyType.AUTOMATIC, PolicyType.AUTOMATIC);
|
||||
scroll.set_shadow_type(ShadowType.IN);
|
||||
scroll.add(job_view);
|
||||
job_vbox.pack_start(scroll, true, true, 0);
|
||||
|
||||
unit_id_label = new RightLabel();
|
||||
unit_description_label = new RightLabel();
|
||||
unit_load_state_label = new RightLabel();
|
||||
unit_active_state_label = new RightLabel();
|
||||
unit_load_path_label = new RightLabel();
|
||||
unit_active_enter_timestamp_label = new RightLabel();
|
||||
unit_active_exit_timestamp_label = new RightLabel();
|
||||
unit_can_start_label = new RightLabel();
|
||||
unit_can_reload_label = new RightLabel();
|
||||
|
||||
job_id_label = new RightLabel();
|
||||
job_state_label = new RightLabel();
|
||||
job_type_label = new RightLabel();
|
||||
|
||||
Table unit_table = new Table(9, 2, false);
|
||||
unit_table.set_row_spacings(6);
|
||||
unit_table.set_border_width(12);
|
||||
unit_vbox.pack_start(unit_table, false, true, 0);
|
||||
|
||||
Table job_table = new Table(2, 2, false);
|
||||
job_table.set_row_spacings(6);
|
||||
job_table.set_border_width(12);
|
||||
job_vbox.pack_start(job_table, false, true, 0);
|
||||
|
||||
unit_table.attach(new LeftLabel("Id:"), 0, 1, 0, 1, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(unit_id_label, 1, 2, 0, 1, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(new LeftLabel("Description:"), 0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(unit_description_label, 1, 2, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(new LeftLabel("Load State:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(unit_load_state_label, 1, 2, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(new LeftLabel("Active State:"), 0, 1, 3, 4, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(unit_active_state_label, 1, 2, 3, 4, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(new LeftLabel("Load Path:"), 0, 1, 4, 5, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(unit_load_path_label, 1, 2, 4, 5, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(new LeftLabel("Active Enter Timestamp:"), 0, 1, 5, 6, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(unit_active_enter_timestamp_label, 1, 2, 5, 6, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(new LeftLabel("Active Exit Timestamp:"), 0, 1, 6, 7, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(unit_active_exit_timestamp_label, 1, 2, 6, 7, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(new LeftLabel("Can Start/Stop:"), 0, 1, 7, 8, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(unit_can_start_label, 1, 2, 7, 8, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(new LeftLabel("Can Reload:"), 0, 1, 8, 9, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
unit_table.attach(unit_can_reload_label, 1, 2, 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);
|
||||
job_table.attach(new LeftLabel("State:"), 0, 1, 1, 2, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
job_table.attach(job_state_label, 1, 2, 1, 2, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
job_table.attach(new LeftLabel("Type:"), 0, 1, 2, 3, AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
job_table.attach(job_type_label, 1, 2, 2, 3, AttachOptions.EXPAND|AttachOptions.FILL, AttachOptions.FILL, 0, 0);
|
||||
|
||||
ButtonBox bbox = new HButtonBox();
|
||||
bbox.set_layout(ButtonBoxStyle.START);
|
||||
bbox.set_spacing(6);
|
||||
unit_vbox.pack_start(bbox, false, true, 0);
|
||||
|
||||
start_button = new Button.with_mnemonic("_Start");
|
||||
stop_button = new Button.with_mnemonic("Sto_p");
|
||||
reload_button = new Button.with_mnemonic("_Reload");
|
||||
restart_button = new Button.with_mnemonic("Res_tart");
|
||||
|
||||
start_button.clicked.connect(on_start);
|
||||
stop_button.clicked.connect(on_stop);
|
||||
reload_button.clicked.connect(on_reload);
|
||||
restart_button.clicked.connect(on_restart);
|
||||
|
||||
bbox.pack_start(start_button, false, true, 0);
|
||||
bbox.pack_start(stop_button, false, true, 0);
|
||||
bbox.pack_start(restart_button, false, true, 0);
|
||||
bbox.pack_start(reload_button, false, true, 0);
|
||||
|
||||
bbox = new HButtonBox();
|
||||
bbox.set_layout(ButtonBoxStyle.START);
|
||||
bbox.set_spacing(6);
|
||||
job_vbox.pack_start(bbox, false, true, 0);
|
||||
|
||||
cancel_button = new Button.with_mnemonic("_Cancel");
|
||||
|
||||
cancel_button.clicked.connect(on_cancel);
|
||||
|
||||
bbox.pack_start(cancel_button, false, true, 0);
|
||||
|
||||
bus = Bus.get(BusType.SESSION);
|
||||
|
||||
manager = bus.get_object (
|
||||
"org.freedesktop.systemd1",
|
||||
"/org/freedesktop/systemd1",
|
||||
"org.freedesktop.systemd1") as Manager;
|
||||
|
||||
clear_unit();
|
||||
populate_unit_model();
|
||||
populate_job_model();
|
||||
}
|
||||
|
||||
public void populate_unit_model() throws DBus.Error {
|
||||
unit_model.clear();
|
||||
|
||||
var list = manager.list_units();
|
||||
|
||||
foreach (var i in list) {
|
||||
TreeIter iter;
|
||||
|
||||
unit_model.append(out iter);
|
||||
unit_model.set(iter,
|
||||
0, i.id,
|
||||
1, i.description,
|
||||
2, i.load_state,
|
||||
3, i.active_state,
|
||||
4, i.job_type != "" ? "→ %s".printf(i.job_type) : "",
|
||||
5, i.unit_path);
|
||||
}
|
||||
}
|
||||
|
||||
public void populate_job_model() throws DBus.Error {
|
||||
job_model.clear();
|
||||
|
||||
var list = manager.list_jobs();
|
||||
|
||||
foreach (var i in list) {
|
||||
TreeIter iter;
|
||||
|
||||
job_model.append(out iter);
|
||||
job_model.set(iter,
|
||||
0, "%u".printf(i.id),
|
||||
1, i.name,
|
||||
2, "→ %s".printf(i.type),
|
||||
3, i.state,
|
||||
4, i.job_path);
|
||||
}
|
||||
}
|
||||
|
||||
public Unit? get_current_unit() {
|
||||
TreePath p;
|
||||
unit_view.get_cursor(out p, null);
|
||||
|
||||
if (p == null)
|
||||
return null;
|
||||
|
||||
TreeIter iter;
|
||||
string path;
|
||||
|
||||
unit_model.get_iter(out iter, p);
|
||||
unit_model.get(iter, 5, out path);
|
||||
|
||||
return bus.get_object (
|
||||
"org.freedesktop.systemd1",
|
||||
path,
|
||||
"org.freedesktop.systemd1.Unit") as Unit;
|
||||
}
|
||||
|
||||
public void unit_changed() {
|
||||
Unit u = get_current_unit();
|
||||
|
||||
if (u == null)
|
||||
clear_unit();
|
||||
else
|
||||
show_unit(u);
|
||||
}
|
||||
|
||||
public void clear_unit() {
|
||||
start_button.set_sensitive(false);
|
||||
stop_button.set_sensitive(false);
|
||||
reload_button.set_sensitive(false);
|
||||
restart_button.set_sensitive(false);
|
||||
|
||||
unit_id_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_load_path_label.set_text_or_na();
|
||||
unit_active_enter_timestamp_label.set_text_or_na();
|
||||
unit_active_exit_timestamp_label.set_text_or_na();
|
||||
unit_can_reload_label.set_text_or_na();
|
||||
unit_can_start_label.set_text_or_na();
|
||||
}
|
||||
|
||||
public void show_unit(Unit unit) {
|
||||
unit_id_label.set_text_or_na(unit.id);
|
||||
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);
|
||||
unit_load_path_label.set_text_or_na(unit.load_path);
|
||||
|
||||
uint64 t = unit.active_enter_timestamp;
|
||||
if (t > 0) {
|
||||
TimeVal tv = { (long) (t / 1000000), (long) (t % 1000000) };
|
||||
unit_active_enter_timestamp_label.set_text_or_na(tv.to_iso8601());
|
||||
} else
|
||||
unit_active_enter_timestamp_label.set_text_or_na();
|
||||
|
||||
t = unit.active_exit_timestamp;
|
||||
if (t > 0) {
|
||||
TimeVal tv = { (long) (t / 1000000), (long) (t % 1000000) };
|
||||
unit_active_exit_timestamp_label.set_text_or_na(tv.to_iso8601());
|
||||
} else
|
||||
unit_active_exit_timestamp_label.set_text_or_na();
|
||||
|
||||
bool b = unit.can_start;
|
||||
start_button.set_sensitive(b);
|
||||
stop_button.set_sensitive(b);
|
||||
restart_button.set_sensitive(b);
|
||||
unit_can_start_label.set_text_or_na(b ? "Yes" : "No");
|
||||
|
||||
b = unit.can_reload;
|
||||
reload_button.set_sensitive(b);
|
||||
unit_can_reload_label.set_text_or_na(b ? "Yes" : "No");
|
||||
}
|
||||
|
||||
public Job? get_current_job() {
|
||||
TreePath p;
|
||||
job_view.get_cursor(out p, null);
|
||||
|
||||
if (p == null)
|
||||
return null;
|
||||
|
||||
TreeIter iter;
|
||||
string path;
|
||||
|
||||
job_model.get_iter(out iter, p);
|
||||
job_model.get(iter, 4, out path);
|
||||
|
||||
return bus.get_object (
|
||||
"org.freedesktop.systemd1",
|
||||
path,
|
||||
"org.freedesktop.systemd1.Job") as Job;
|
||||
}
|
||||
|
||||
public void job_changed() {
|
||||
Job j = get_current_job();
|
||||
|
||||
if (j == null)
|
||||
clear_job();
|
||||
else
|
||||
show_job(j);
|
||||
}
|
||||
|
||||
public void clear_job() {
|
||||
job_id_label.set_text_or_na();
|
||||
job_state_label.set_text_or_na();
|
||||
job_type_label.set_text_or_na();
|
||||
}
|
||||
|
||||
public void show_job(Job job) {
|
||||
job_id_label.set_text_or_na("%u".printf(job.id));
|
||||
job_state_label.set_text_or_na(job.state);
|
||||
job_type_label.set_text_or_na(job.job_type);
|
||||
}
|
||||
|
||||
public void on_start() {
|
||||
Unit u = get_current_unit();
|
||||
|
||||
if (u == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
u.start("replace");
|
||||
} catch (DBus.Error e) {
|
||||
message("%s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
public void on_stop() {
|
||||
Unit u = get_current_unit();
|
||||
|
||||
if (u == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
u.stop("replace");
|
||||
} catch (DBus.Error e) {
|
||||
message("%s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
public void on_reload() {
|
||||
Unit u = get_current_unit();
|
||||
|
||||
if (u == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
u.reload("replace");
|
||||
} catch (DBus.Error e) {
|
||||
message("%s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
public void on_restart() {
|
||||
Unit u = get_current_unit();
|
||||
|
||||
if (u == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
u.restart("replace");
|
||||
} catch (DBus.Error e) {
|
||||
message("%s", e.message);
|
||||
}
|
||||
}
|
||||
|
||||
public void on_cancel() {
|
||||
Job j = get_current_job();
|
||||
|
||||
if (j == null)
|
||||
return;
|
||||
|
||||
try {
|
||||
j.cancel();
|
||||
} catch (DBus.Error e) {
|
||||
message("%s", e.message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main (string[] args) {
|
||||
Gtk.init(ref args);
|
||||
|
||||
try {
|
||||
MainWindow window = new MainWindow();
|
||||
window.show_all();
|
||||
} catch (DBus.Error e) {
|
||||
message("%s", e.message);
|
||||
}
|
||||
|
||||
Gtk.main();
|
||||
return 0;
|
||||
}
|
109
systemctl.vala
109
systemctl.vala
@ -1,45 +1,15 @@
|
||||
using DBus;
|
||||
using GLib;
|
||||
|
||||
[DBus (name = "org.freedesktop.systemd1")]
|
||||
public interface Manager : DBus.Object {
|
||||
|
||||
public struct UnitInfo {
|
||||
string id;
|
||||
string description;
|
||||
string load_state;
|
||||
string active_state;
|
||||
ObjectPath unit_path;
|
||||
uint32 job_id;
|
||||
string job_type;
|
||||
ObjectPath job_path;
|
||||
}
|
||||
|
||||
public struct JobInfo {
|
||||
uint32 id;
|
||||
string name;
|
||||
string type;
|
||||
string state;
|
||||
ObjectPath job_path;
|
||||
ObjectPath unit_path;
|
||||
}
|
||||
|
||||
public abstract UnitInfo[] ListUnits() throws DBus.Error;
|
||||
public abstract JobInfo[] ListJobs() throws DBus.Error;
|
||||
|
||||
public abstract ObjectPath LoadUnit(string name) throws DBus.Error;
|
||||
|
||||
public abstract void ClearJobs() throws DBus.Error;
|
||||
}
|
||||
|
||||
static string type = null;
|
||||
static bool all = false;
|
||||
static bool replace = false;
|
||||
|
||||
public static int job_info_compare(void* key1, void* key2) {
|
||||
Manager.JobInfo *j1 = (Manager.JobInfo*) key1;
|
||||
Manager.JobInfo *j2 = (Manager.JobInfo*) key2;
|
||||
|
||||
return Posix.strcmp(j1->name, j2->name);
|
||||
return j1->id < j2->id ? -1 : (j1->id > j2->id ? 1 : 0);
|
||||
}
|
||||
|
||||
public static int unit_info_compare(void* key1, void* key2) {
|
||||
@ -54,8 +24,9 @@ public static int unit_info_compare(void* key1, void* key2) {
|
||||
}
|
||||
|
||||
static const OptionEntry entries[] = {
|
||||
{ "type", 't', 0, OptionArg.STRING, out type, "List only particular type of units", "TYPE" },
|
||||
{ "all", 'a', 0, OptionArg.NONE, out all, "Show all units, including dead ones", null },
|
||||
{ "type", 't', 0, OptionArg.STRING, out type, "List only particular type of units", "TYPE" },
|
||||
{ "all", 'a', 0, OptionArg.NONE, out all, "Show all units, including dead ones", null },
|
||||
{ "replace", 0, 0, OptionArg.NONE, out replace, "When installing a new job, replace existing conflicting ones.", null },
|
||||
{ null }
|
||||
};
|
||||
|
||||
@ -79,7 +50,7 @@ int main (string[] args) {
|
||||
"org.freedesktop.systemd1") as Manager;
|
||||
|
||||
if (args[1] == "list-units" || args.length <= 1) {
|
||||
var list = manager.ListUnits();
|
||||
var list = manager.list_units();
|
||||
uint n = 0;
|
||||
Posix.qsort(list, list.length, sizeof(Manager.UnitInfo), unit_info_compare);
|
||||
|
||||
@ -109,19 +80,19 @@ int main (string[] args) {
|
||||
|
||||
|
||||
} else if (args[1] == "list-jobs") {
|
||||
var list = manager.ListJobs();
|
||||
var list = manager.list_jobs();
|
||||
Posix.qsort(list, list.length, sizeof(Manager.JobInfo), job_info_compare);
|
||||
|
||||
stdout.printf("%-45s %-17s %-7s\n", "UNIT", "TYPE", "STATE");
|
||||
stdout.printf("%4s %-45s %-17s %-7s\n", "JOB", "UNIT", "TYPE", "STATE");
|
||||
|
||||
foreach (var i in list)
|
||||
stdout.printf("%-45s → %-15s %-7s\n", i.name, i.type, i.state);
|
||||
stdout.printf("%4u %-45s → %-15s %-7s\n", i.id, i.name, i.type, i.state);
|
||||
|
||||
stdout.printf("\n%u jobs listed.\n", list.length);
|
||||
|
||||
} else if (args[1] == "clear-jobs") {
|
||||
|
||||
manager.ClearJobs();
|
||||
manager.clear_jobs();
|
||||
|
||||
} else if (args[1] == "load") {
|
||||
|
||||
@ -130,7 +101,65 @@ int main (string[] args) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
manager.LoadUnit(args[2]);
|
||||
for (uint i = 2; i < args.length; i++)
|
||||
manager.load_unit(args[i]);
|
||||
|
||||
} else if (args[1] == "cancel") {
|
||||
|
||||
if (args.length < 3) {
|
||||
stderr.printf("Missing argument.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (uint i = 2; i < args.length; i++) {
|
||||
uint32 id;
|
||||
|
||||
if (args[i].scanf("%u", out id) != 1) {
|
||||
stderr.printf("Failed to parse argument.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
ObjectPath p = manager.get_job(id);
|
||||
|
||||
Job j = bus.get_object (
|
||||
"org.freedesktop.systemd1",
|
||||
p,
|
||||
"org.freedesktop.systemd1.Job") as Job;
|
||||
|
||||
j.cancel();
|
||||
}
|
||||
|
||||
} else if (args[1] == "start" ||
|
||||
args[1] == "stop" ||
|
||||
args[1] == "reload" ||
|
||||
args[1] == "restart") {
|
||||
|
||||
if (args.length < 3) {
|
||||
stderr.printf("Missing argument.\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
for (uint i = 2; i < args.length; i++) {
|
||||
|
||||
ObjectPath p = manager.get_unit(args[i]);
|
||||
|
||||
Unit u = bus.get_object(
|
||||
"org.freedesktop.systemd1",
|
||||
p,
|
||||
"org.freedesktop.systemd1.Unit") as Unit;
|
||||
|
||||
string mode = replace ? "replace" : "fail";
|
||||
|
||||
if (args[1] == "start")
|
||||
u.start(mode);
|
||||
else if (args[1] == "stop")
|
||||
u.stop(mode);
|
||||
else if (args[1] == "restart")
|
||||
u.restart(mode);
|
||||
else if (args[1] == "reload")
|
||||
u.reload(mode);
|
||||
}
|
||||
|
||||
} else {
|
||||
stderr.printf("Unknown command %s.\n", args[1]);
|
||||
return 1;
|
||||
|
61
systemd-interfaces.vala
Normal file
61
systemd-interfaces.vala
Normal file
@ -0,0 +1,61 @@
|
||||
using DBus;
|
||||
|
||||
[DBus (name = "org.freedesktop.systemd1")]
|
||||
public interface Manager : DBus.Object {
|
||||
|
||||
public struct UnitInfo {
|
||||
string id;
|
||||
string description;
|
||||
string load_state;
|
||||
string active_state;
|
||||
ObjectPath unit_path;
|
||||
uint32 job_id;
|
||||
string job_type;
|
||||
ObjectPath job_path;
|
||||
}
|
||||
|
||||
public struct JobInfo {
|
||||
uint32 id;
|
||||
string name;
|
||||
string type;
|
||||
string state;
|
||||
ObjectPath job_path;
|
||||
ObjectPath unit_path;
|
||||
}
|
||||
|
||||
public abstract UnitInfo[] list_units() throws DBus.Error;
|
||||
public abstract JobInfo[] list_jobs() throws DBus.Error;
|
||||
|
||||
public abstract ObjectPath get_unit(string name) throws DBus.Error;
|
||||
public abstract ObjectPath load_unit(string name) throws DBus.Error;
|
||||
public abstract ObjectPath get_job(uint32 id) throws DBus.Error;
|
||||
|
||||
public abstract void clear_jobs() throws DBus.Error;
|
||||
}
|
||||
|
||||
[DBus (name = "org.freedesktop.systemd1.Unit")]
|
||||
public interface Unit : DBus.Object {
|
||||
public abstract string id { owned get; }
|
||||
public abstract string description { owned get; }
|
||||
public abstract string load_state { owned get; }
|
||||
public abstract string active_state { owned get; }
|
||||
public abstract string load_path { owned get; }
|
||||
public abstract uint64 active_enter_timestamp { owned get; }
|
||||
public abstract uint64 active_exit_timestamp { owned get; }
|
||||
public abstract bool can_reload { owned get; }
|
||||
public abstract bool can_start { owned get; }
|
||||
|
||||
public abstract ObjectPath start(string mode) throws DBus.Error;
|
||||
public abstract ObjectPath stop(string mode) throws DBus.Error;
|
||||
public abstract ObjectPath restart(string mode) throws DBus.Error;
|
||||
public abstract ObjectPath reload(string mode) throws DBus.Error;
|
||||
}
|
||||
|
||||
[DBus (name = "org.freedesktop.systemd1.Job")]
|
||||
public interface Job : DBus.Object {
|
||||
public abstract uint32 id { owned get; }
|
||||
public abstract string state { owned get; }
|
||||
public abstract string job_type { owned get; }
|
||||
|
||||
public abstract void cancel() throws DBus.Error;
|
||||
}
|
Loading…
Reference in New Issue
Block a user