1
0
forked from brl/citadel-tools

update dbus crate

This commit is contained in:
Bruce Leidl 2020-07-02 11:59:04 -04:00
parent c9d36aca59
commit 874dbd1654
3 changed files with 33 additions and 45 deletions

3
Cargo.lock generated
View File

@ -886,8 +886,7 @@ dependencies = [
name = "realmsd" name = "realmsd"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"dbus 0.6.5 (registry+https://github.com/rust-lang/crates.io-index)", "dbus 0.8.4 (registry+https://github.com/rust-lang/crates.io-index)",
"failure 0.1.8 (registry+https://github.com/rust-lang/crates.io-index)",
"libcitadel 0.1.0", "libcitadel 0.1.0",
] ]

View File

@ -6,6 +6,5 @@ edition = "2018"
[dependencies] [dependencies]
libcitadel = { path = "../libcitadel" } libcitadel = { path = "../libcitadel" }
failure = "0.1" dbus = "0.8"
dbus = "0.6"

View File

@ -1,10 +1,12 @@
use std::fmt;
use std::sync::Arc; use std::sync::Arc;
use std::{result, thread}; use std::{result, thread};
use dbus::tree::{self, Factory, MTFn, MethodResult, Tree, MethodErr}; use dbus::tree::{self, Factory, MTFn, MethodResult, Tree, MethodErr};
use dbus::{Connection, NameFlag, Message}; use dbus::blocking::LocalConnection;
use dbus::Message;
use libcitadel::{Result, RealmManager, Realm, RealmEvent, OverlayType, RealmFS, terminal}; use libcitadel::{Result, RealmManager, Realm, RealmEvent, OverlayType, RealmFS, terminal};
use std::fmt; use std::time::Duration;
type MethodInfo<'a> = tree::MethodInfo<'a, MTFn<TData>, TData>; type MethodInfo<'a> = tree::MethodInfo<'a, MTFn<TData>, TData>;
@ -20,11 +22,8 @@ const OBJECT_PATH: &str = "/com/subgraph/realms";
const INTERFACE_NAME: &str = "com.subgraph.realms.Manager"; const INTERFACE_NAME: &str = "com.subgraph.realms.Manager";
const BUS_NAME: &str = "com.subgraph.realms"; const BUS_NAME: &str = "com.subgraph.realms";
const OBJECT_MANAGER_INTERFACE: &str = "org.freedesktop.DBus.ObjectManager";
const VPN_CONNECTION_INTERFACE: &str = "org.freedesktop.VPN.Connection";
pub struct DbusServer { pub struct DbusServer {
connection: Arc<Connection>, connection: Arc<LocalConnection>,
manager: Arc<RealmManager>, manager: Arc<RealmManager>,
events: EventHandler, events: EventHandler,
} }
@ -32,7 +31,9 @@ pub struct DbusServer {
impl DbusServer { impl DbusServer {
pub fn connect(manager: Arc<RealmManager>) -> Result<DbusServer> { pub fn connect(manager: Arc<RealmManager>) -> Result<DbusServer> {
let connection = Arc::new(Connection::get_private(dbus::BusType::System)?); let connection = LocalConnection::new_system()
.map_err(|e| format_err!("Failed to connect to DBUS system bus: {}", e))?;
let connection = Arc::new(connection);
let events = EventHandler::new(connection.clone()); let events = EventHandler::new(connection.clone());
let server = DbusServer { events, connection, manager }; let server = DbusServer { events, connection, manager };
Ok(server) Ok(server)
@ -122,8 +123,8 @@ impl DbusServer {
let manager = m.tree.get_data().manager(); let manager = m.tree.get_data().manager();
let ret = m.msg.method_return(); let ret = m.msg.method_return();
let msg = match manager.current_realm() { let msg = match manager.current_realm() {
Some(realm) => ret.append(realm.name()), Some(realm) => ret.append1(realm.name()),
None => ret.append(""), None => ret.append1(""),
}; };
Ok(vec![msg]) Ok(vec![msg])
} }
@ -218,8 +219,8 @@ impl DbusServer {
let manager = m.tree.get_data().manager(); let manager = m.tree.get_data().manager();
let ret = m.msg.method_return(); let ret = m.msg.method_return();
let msg = match manager.realm_by_pid(pid) { let msg = match manager.realm_by_pid(pid) {
Some(realm) => ret.append(realm.name()), Some(realm) => ret.append1(realm.name()),
None => ret.append(""), None => ret.append1(""),
}; };
Ok(vec![msg]) Ok(vec![msg])
} }
@ -238,12 +239,11 @@ impl DbusServer {
pub fn start(&self) -> Result<()> { pub fn start(&self) -> Result<()> {
let tree = self.build_tree(); let tree = self.build_tree();
self.connection.register_name(BUS_NAME, NameFlag::ReplaceExisting as u32)?; if let Err(err) = self.connection.request_name(BUS_NAME, false, true, false) {
tree.set_registered(&self.connection, true)?; bail!("failed to register DBUS name {}: {}", BUS_NAME, err);
self.connection.add_handler(tree); }
self.receive_signals_from(VPN_CONNECTION_INTERFACE)?; tree.start_receive(self.connection.as_ref());
self.receive_signals_from(OBJECT_MANAGER_INTERFACE)?;
self.manager.add_event_handler({ self.manager.add_event_handler({
let events = self.events.clone(); let events = self.events.clone();
@ -257,34 +257,23 @@ impl DbusServer {
self.send_service_started(); self.send_service_started();
loop { loop {
if let Some(msg) = self.connection.incoming(1000).next() { self.connection
self.process_message(msg)?; .process(Duration::from_millis(1000))
.map_err(context!("Error handling dbus messages"))?;
} }
} }
}
fn process_message(&self, _msg: Message) -> Result<()> {
// add handlers for expected signals here
Ok(())
}
fn receive_signals_from(&self, interface: &str) -> Result<()> {
let rule = format!("type=signal,interface={}", interface);
self.connection.add_match(rule.as_str())?;
Ok(())
}
fn send_service_started(&self) { fn send_service_started(&self) {
let signal = Self::create_signal("ServiceStarted"); let signal = Self::create_signal("ServiceStarted");
if self.connection.send(signal).is_err() { if self.connection.channel().send(signal).is_err() {
warn!("Failed to send ServiceStarted signal"); warn!("failed to send ServiceStarted signal");
} }
} }
fn create_signal(name: &str) -> Message { fn create_signal(name: &str) -> Message {
let path = dbus::Path::new(OBJECT_PATH).unwrap(); let path = dbus::Path::new(OBJECT_PATH).unwrap();
let iface = dbus::Interface::new(INTERFACE_NAME).unwrap(); let iface = dbus::strings::Interface::new(INTERFACE_NAME).unwrap();
let member = dbus::Member::new(name).unwrap(); let member = dbus::strings::Member::new(name).unwrap();
Message::signal(&path, &iface, &member) Message::signal(&path, &iface, &member)
} }
@ -297,19 +286,20 @@ impl DbusServer {
/// internally libdbus uses a mutex to control concurrent access /// internally libdbus uses a mutex to control concurrent access
/// to the dbus_connection_send() function. /// to the dbus_connection_send() function.
#[derive(Clone)] #[derive(Clone)]
struct ConnectionSender(Arc<Connection>); struct ConnectionSender(Arc<LocalConnection>);
unsafe impl Send for ConnectionSender {} unsafe impl Send for ConnectionSender {}
unsafe impl Sync for ConnectionSender {} unsafe impl Sync for ConnectionSender {}
impl ConnectionSender { impl ConnectionSender {
fn new(connection: Arc<Connection>) -> Self { fn new(connection: Arc<LocalConnection>) -> Self {
ConnectionSender(connection) ConnectionSender(connection)
} }
fn send(&self, msg: Message) -> Result<()> { fn send(&self, msg: Message) -> Result<()> {
self.0.send(msg) if let Err(()) = self.0.channel().send(msg) {
.map_err(|()| failure::err_msg("failed to send message"))?; bail!("failed to send DBUS message");
}
Ok(()) Ok(())
} }
} }
@ -320,7 +310,7 @@ struct EventHandler {
} }
impl EventHandler { impl EventHandler {
fn new(conn: Arc<Connection>) -> EventHandler { fn new(conn: Arc<LocalConnection>) -> EventHandler {
EventHandler { EventHandler {
sender: ConnectionSender::new(conn), sender: ConnectionSender::new(conn),
} }
@ -358,8 +348,8 @@ impl EventHandler {
fn create_realm_signal(name: &str) -> Message { fn create_realm_signal(name: &str) -> Message {
let path = dbus::Path::new(OBJECT_PATH).unwrap(); let path = dbus::Path::new(OBJECT_PATH).unwrap();
let iface = dbus::Interface::new(INTERFACE_NAME).unwrap(); let iface = dbus::strings::Interface::new(INTERFACE_NAME).unwrap();
let member = dbus::Member::new(name).unwrap(); let member = dbus::strings::Member::new(name).unwrap();
Message::signal(&path, &iface, &member) Message::signal(&path, &iface, &member)
} }