Skip to content

Commit

Permalink
daemon: Share Transaction address for identical requests
Browse files Browse the repository at this point in the history
If a client makes a request that is identical (that is, same method name
and same parameters) to an ongoing transaction, return the bus address of
that transaction.  The client can then "tune in" to the progress messages.
(Remember the Transaction.Start() method returns a boolean to distinguish
a newly-started transaction from an ongoing transaction.)

The driving use case for this is a dropped ssh connection during a long
running transaction -- like "upgrade" -- and being able to reattach to
the transaction's progress messages mid-stream.
  • Loading branch information
mbarnes committed Aug 27, 2015
1 parent 1ef0a2d commit 9074d0c
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 30 deletions.
144 changes: 114 additions & 30 deletions src/daemon/rpmostreed-os.c
Original file line number Diff line number Diff line change
Expand Up @@ -415,11 +415,20 @@ os_handle_download_update_rpm_diff (RPMOSTreeOS *interface,
glnx_unref_object RpmostreedTransaction *transaction = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
glnx_unref_object GCancellable *cancellable = NULL;
const char *client_address;
const char *osname;
const char *sysroot_path;
GError *local_error = NULL;

/* If a compatible transaction is in progress, share its bus address. */
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
if (transaction != NULL)
{
if (rpmostreed_transaction_is_compatible (transaction, invocation))
goto out;

g_clear_object (&transaction);
}

cancellable = g_cancellable_new ();

sysroot_path = rpmostreed_sysroot_get_sysroot_path (rpmostreed_sysroot_get ());
Expand All @@ -444,12 +453,17 @@ os_handle_download_update_rpm_diff (RPMOSTreeOS *interface,

rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);

client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_download_update_rpm_diff (interface, invocation, client_address);

out:
if (local_error != NULL)
g_dbus_method_invocation_take_error (invocation, local_error);
{
g_dbus_method_invocation_take_error (invocation, local_error);
}
else
{
const char *client_address;
client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_download_update_rpm_diff (interface, invocation, client_address);
}

return TRUE;
}
Expand All @@ -465,11 +479,20 @@ os_handle_upgrade (RPMOSTreeOS *interface,
glnx_unref_object GCancellable *cancellable = NULL;
GVariantDict options_dict;
gboolean opt_allow_downgrade = FALSE;
const char *client_address;
const char *osname;
const char *sysroot_path;
GError *local_error = NULL;

/* If a compatible transaction is in progress, share its bus address. */
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
if (transaction != NULL)
{
if (rpmostreed_transaction_is_compatible (transaction, invocation))
goto out;

g_clear_object (&transaction);
}

cancellable = g_cancellable_new ();

sysroot_path = rpmostreed_sysroot_get_sysroot_path (rpmostreed_sysroot_get ());
Expand Down Expand Up @@ -506,12 +529,17 @@ os_handle_upgrade (RPMOSTreeOS *interface,

rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);

client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_upgrade (interface, invocation, client_address);

out:
if (local_error != NULL)
g_dbus_method_invocation_take_error (invocation, local_error);
{
g_dbus_method_invocation_take_error (invocation, local_error);
}
else
{
const char *client_address;
client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_upgrade (interface, invocation, client_address);
}

return TRUE;
}
Expand All @@ -524,11 +552,20 @@ os_handle_rollback (RPMOSTreeOS *interface,
glnx_unref_object RpmostreedTransaction *transaction = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
glnx_unref_object GCancellable *cancellable = NULL;
const char *client_address;
const char *osname;
const char *sysroot_path;
GError *local_error = NULL;

/* If a compatible transaction is in progress, share its bus address. */
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
if (transaction != NULL)
{
if (rpmostreed_transaction_is_compatible (transaction, invocation))
goto out;

g_clear_object (&transaction);
}

cancellable = g_cancellable_new ();

sysroot_path = rpmostreed_sysroot_get_sysroot_path (rpmostreed_sysroot_get ());
Expand All @@ -552,12 +589,17 @@ os_handle_rollback (RPMOSTreeOS *interface,

rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);

client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_rollback (interface, invocation, client_address);

out:
if (local_error != NULL)
g_dbus_method_invocation_take_error (invocation, local_error);
{
g_dbus_method_invocation_take_error (invocation, local_error);
}
else
{
const char *client_address;
client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_rollback (interface, invocation, client_address);
}

return TRUE;
}
Expand All @@ -570,11 +612,20 @@ os_handle_clear_rollback_target (RPMOSTreeOS *interface,
glnx_unref_object RpmostreedTransaction *transaction = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
glnx_unref_object GCancellable *cancellable = NULL;
const char *client_address;
const char *osname;
const char *sysroot_path;
GError *local_error = NULL;

/* If a compatible transaction is in progress, share its bus address. */
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
if (transaction != NULL)
{
if (rpmostreed_transaction_is_compatible (transaction, invocation))
goto out;

g_clear_object (&transaction);
}

cancellable = g_cancellable_new ();

sysroot_path = rpmostreed_sysroot_get_sysroot_path (rpmostreed_sysroot_get ());
Expand All @@ -598,12 +649,17 @@ os_handle_clear_rollback_target (RPMOSTreeOS *interface,

rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);

client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_clear_rollback_target (interface, invocation, client_address);

out:
if (local_error != NULL)
g_dbus_method_invocation_take_error (invocation, local_error);
{
g_dbus_method_invocation_take_error (invocation, local_error);
}
else
{
const char *client_address;
client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_clear_rollback_target (interface, invocation, client_address);
}

return TRUE;
}
Expand All @@ -622,11 +678,20 @@ os_handle_rebase (RPMOSTreeOS *interface,
glnx_unref_object GCancellable *cancellable = NULL;
GVariantDict options_dict;
gboolean opt_skip_purge = FALSE;
const char *client_address;
const char *osname;
const char *sysroot_path;
GError *local_error = NULL;

/* If a compatible transaction is in progress, share its bus address. */
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
if (transaction != NULL)
{
if (rpmostreed_transaction_is_compatible (transaction, invocation))
goto out;

g_clear_object (&transaction);
}

cancellable = g_cancellable_new ();

sysroot_path = rpmostreed_sysroot_get_sysroot_path (rpmostreed_sysroot_get ());
Expand Down Expand Up @@ -663,12 +728,17 @@ os_handle_rebase (RPMOSTreeOS *interface,

rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);

client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_rebase (interface, invocation, client_address);

out:
if (local_error != NULL)
g_dbus_method_invocation_take_error (invocation, local_error);
{
g_dbus_method_invocation_take_error (invocation, local_error);
}
else
{
const char *client_address;
client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_rebase (interface, invocation, client_address);
}

return TRUE;
}
Expand Down Expand Up @@ -706,11 +776,20 @@ os_handle_download_rebase_rpm_diff (RPMOSTreeOS *interface,
glnx_unref_object RpmostreedTransaction *transaction = NULL;
glnx_unref_object OstreeSysroot *sysroot = NULL;
glnx_unref_object GCancellable *cancellable = NULL;
const char *client_address;
const char *osname;
const char *sysroot_path;
GError *local_error = NULL;

/* If a compatible transaction is in progress, share its bus address. */
transaction = rpmostreed_transaction_monitor_ref_active_transaction (self->transaction_monitor);
if (transaction != NULL)
{
if (rpmostreed_transaction_is_compatible (transaction, invocation))
goto out;

g_clear_object (&transaction);
}

cancellable = g_cancellable_new ();

sysroot_path = rpmostreed_sysroot_get_sysroot_path (rpmostreed_sysroot_get ());
Expand All @@ -735,12 +814,17 @@ os_handle_download_rebase_rpm_diff (RPMOSTreeOS *interface,

rpmostreed_transaction_monitor_add (self->transaction_monitor, transaction);

client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_download_rebase_rpm_diff (interface, invocation, client_address);

out:
if (local_error != NULL)
g_dbus_method_invocation_take_error (invocation, local_error);
{
g_dbus_method_invocation_take_error (invocation, local_error);
}
else
{
const char *client_address;
client_address = rpmostreed_transaction_get_client_address (transaction);
rpmostree_os_complete_download_rebase_rpm_diff (interface, invocation, client_address);
}

return TRUE;
}
Expand Down
25 changes: 25 additions & 0 deletions src/daemon/rpmostreed-transaction.c
Original file line number Diff line number Diff line change
Expand Up @@ -724,6 +724,31 @@ rpmostreed_transaction_emit_message_printf (RpmostreedTransaction *transaction,
formatted_message);
}

gboolean
rpmostreed_transaction_is_compatible (RpmostreedTransaction *transaction,
GDBusMethodInvocation *invocation)
{
RpmostreedTransactionPrivate *priv;
const char *method_name_a;
const char *method_name_b;
GVariant *parameters_a;
GVariant *parameters_b;

g_return_val_if_fail (RPMOSTREED_IS_TRANSACTION (transaction), FALSE);
g_return_val_if_fail (G_IS_DBUS_METHOD_INVOCATION (invocation), FALSE);

priv = rpmostreed_transaction_get_private (transaction);

method_name_a = g_dbus_method_invocation_get_method_name (priv->invocation);
method_name_b = g_dbus_method_invocation_get_method_name (invocation);

parameters_a = g_dbus_method_invocation_get_parameters (priv->invocation);
parameters_b = g_dbus_method_invocation_get_parameters (invocation);

return g_str_equal (method_name_a, method_name_b) &&
g_variant_equal (parameters_a, parameters_b);
}

void
rpmostreed_transaction_connect_download_progress (RpmostreedTransaction *transaction,
OstreeAsyncProgress *progress)
Expand Down
2 changes: 2 additions & 0 deletions src/daemon/rpmostreed-transaction.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,8 @@ const char * rpmostreed_transaction_get_client_address (RpmostreedTransactio
void rpmostreed_transaction_emit_message_printf (RpmostreedTransaction *transaction,
const char *format,
...) G_GNUC_PRINTF (2, 3);
gboolean rpmostreed_transaction_is_compatible (RpmostreedTransaction *transaction,
GDBusMethodInvocation *invocation);
void rpmostreed_transaction_connect_download_progress
(RpmostreedTransaction *transaction,
OstreeAsyncProgress *progress);
Expand Down

0 comments on commit 9074d0c

Please sign in to comment.