Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(update-agent): publishing update-agent progress to dbus #349

Open
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

sfikastheo
Copy link
Contributor

WIP

@sfikastheo sfikastheo requested a review from TheButlah January 13, 2025 13:55
Copy link
Collaborator

@TheButlah TheButlah left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

very nice! just a few small tweaks and we will be done :)

#[derive(Default, Debug, Serialize, Deserialize, Type, Clone, Value, OwnedValue)]
pub struct UpdateStatus {
pub components: Vec<ComponentStatus>,
pub error: String,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

check out zbus::fdo::Result, this might let you get rid of this error field and use a result type instead

Comment on lines +27 to +81
pub fn signal_error(error: &str, conn: &Connection) {
if let Ok(iface) = get_iface_ref(conn) {
iface.get_mut().0.error = error.to_string();
emit_signal(&iface);
} else {
warn!("failed to get interface reference");
}
}

pub fn init_components(components: &[ManifestComponent], conn: &Connection) {
if let Ok(iface) = get_iface_ref(conn) {
iface.get_mut().0.components = components
.iter()
.map(|c| ComponentStatus {
name: c.name.clone(),
state: ComponentState::None,
})
.collect();
} else {
warn!("failed to get interface reference");
}
}

pub fn update_component_state(name: &str, state: ComponentState, conn: &Connection) {
if let Ok(iface) = get_iface_ref(conn) {
if let Some(component) = iface
.get_mut()
.0
.components
.iter_mut()
.find(|c| c.name == name)
{
component.state = state;
}
emit_signal(&iface);
} else {
warn!("failed to get interface reference");
}
}

fn emit_signal(iface: &InterfaceRef<UpdateProgress<UpdateStatus>>) {
if let Err(err) =
async_io::block_on(iface.get_mut().status_changed(iface.signal_context()))
{
warn!("failed to emit signal: {}", err);
}
}

fn get_iface_ref(
conn: &Connection,
) -> Result<InterfaceRef<UpdateProgress<UpdateStatus>>, zbus::Error> {
let object_server = conn.object_server();
object_server
.interface::<_, UpdateProgress<UpdateStatus>>("org.worldcoin.UpdateProgress1")
}
Copy link
Collaborator

@TheButlah TheButlah Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would probably delete the get_iface_ref function and the emit_signal functions

} else {
match zbus::blocking::Connection::session()
.wrap_err("failed establishing a `session` dbus connection")
let supervisor_proxy = zbus::blocking::Connection::session()
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you create a connection twice: once here and once in create_dbus_connection. lets instead create the connection only once, then you can clone that connection or give references out to any proxies or interfaces that need it.

Doing this will also eliminate the need for the tuple

/// A wrapper struct for types implementing [`UpdateProgressT`].
pub struct UpdateProgress<T: UpdateProgressT>(pub T);

#[derive(Debug, Serialize, Deserialize, Type, Clone, Value, OwnedValue)]
Copy link
Collaborator

@TheButlah TheButlah Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Might as well make it Copy, PartialEq, Eq

Suggested change
#[derive(Debug, Serialize, Deserialize, Type, Clone, Value, OwnedValue)]
#[derive(Debug, Serialize, Deserialize, Type, Clone, Copy, Eq, PartialEq, Value, OwnedValue)]

interfaces::update_component_state(
component.name(),
ComponentState::Installed,
conn,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

try passing around the InterfaceRef instead of the connection itself. It makes it a bit more clear what this function is doing.

}
}

pub fn init_components(components: &[ManifestComponent], conn: &Connection) {
Copy link
Collaborator

@TheButlah TheButlah Jan 13, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the name could be more informative, maybe init_dbus_properties

}
}

pub fn update_component_state(name: &str, state: ComponentState, conn: &Connection) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name could be more informative, maybe set_dbus_properties

//! org.freedesktop.DBus.Properties.Get org.worldcoin.UpdateProgress1 Status
//! ```
//!
//! Montor for signals:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Monitor

pub enum ComponentState {
None = 1,
Fetched = 2,
Processed = 3,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is "Processed"? In update-agent I think we have 2 steps: fetch and update(install)

#[derive(Debug, Serialize, Deserialize, Type, Clone, Value, OwnedValue)]
pub struct ComponentStatus {
pub name: String,
pub state: ComponentState,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

i like it, also easily extensible for progress bar for each component, but then should we switch component status instead of past tense to current? "Installed" -> "Installing" etc.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

actually even now I don't see a reason why we should use past tense, it might be misleading?

@@ -252,6 +278,15 @@ fn run(args: &Args) -> eyre::Result<()> {
info!("running update for component `{}`", component.name());
component
.run_update(target_slot, &claim, settings.recovery)
.inspect(|_| {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What if for any reason update_component_state panics? do we want to be resilient and this case and continue the update?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants