core: add NMDevice's GetAppliedConnection D-Bus call

Expose applied connection in D-Bus API.

https://bugzilla.gnome.org/show_bug.cgi?id=760884
This commit is contained in:
Thomas Haller 2016-02-11 09:18:35 +01:00
parent 6898e2169e
commit 62910d19d7
2 changed files with 151 additions and 9 deletions

View File

@ -172,15 +172,18 @@
<method name="Reapply">
<arg name="connection" type="a{sa{sv}}" direction="in">
<tp:docstring>
The effective connection settings and properties to use. If empty, the connection
settings from the connection that is active on the device will be used.
The optional connection settings that will be reapplied on the device. If empty, the
currently active settings-connection will be used. The connection cannot arbitrarly
differ from the current applied-connection otherwise the call will fail.
Only certain changes are supported, like adding or removing IP addresses.
</tp:docstring>
</arg>
<arg name="version_id" type="t" direction="in">
<tp:docstring>
If non-zero, the current version id of the applied connection must match.
This optional argument allows to catch concurrent modifications when
reapplying the currently applied connection with modifications.
If non-zero, the current version id of the applied-connection must match.
The current version id can be retrieved via GetAppliedConnection.
This optional argument allows to catch concurrent modifications between
the GetAppliedConnection call and Reapply.
</tp:docstring>
</arg>
<arg name="flags" type="u" direction="in">
@ -190,10 +193,54 @@
</tp:docstring>
</arg>
<tp:docstring>
Attempts to update the configuration of a device without deactivating it.
You can either modify the configuration by passing the desired setup via "connection"
argument or just omit the argument to bring it in sync with the connection that
has been activated but could have been modified since.
Attempts to update the configuration of a device without deactivating it. NetworkManager
has the concept of connections, which are profiles that contain the configuration for
a networking device. Those connections are exposed via D-Bus as individual objects
that can be created, modified and deleted. When activating such a settings-connection
on a device, the settings-connection is cloned to become an applied-connection and used to
configure the device (see GetAppliedConnection). Subsequent modification of the
settings-connection don't propagate automatically to the device's applied-connection
(with exception of the firewall-zone and the metered property). For the changes to take
effect, you can either re-activate the settings-connection, or call Reapply.
The Reapply call allows you to directly update the applied-connection and reconfigure
the device.
Reapply can also be useful if the currently applied-connection is equal to the connection
that is about to be reapplied. This allows to reconfigure the device and revert external
changes like removing or adding an IP address (which NetworkManager doesn't revert
automatically because it is assumed that the user made these changes intentionally outside
of NetworkManager).
Reapply can make the applied-connection different from the settings-connection,
just like updating the settings-connection can make them different.
</tp:docstring>
</method>
<method name="GetAppliedConnection">
<arg name="flags" type="u" direction="in">
<tp:docstring>
Flags which would modify the behavior of the GetAppliedConnection call.
There are no flags defined currently and the users should use the value of 0.
</tp:docstring>
</arg>
<arg name="connection" type="a{sa{sv}}" direction="out">
<tp:docstring>
The effective connection settings that the connection has currently applied.
</tp:docstring>
</arg>
<arg name="version_id" type="t" direction="out">
<tp:docstring>
The version-id of the currently applied connection. This can be specified during
Reapply to avoid races where you first fetch the applied connection, modify it
and try to reapply it. If the applied connection is modified in the meantime, the
version_id gets incremented and Reapply will fail.
</tp:docstring>
</arg>
<tp:docstring>
Get the currently applied connection on the device. This is a snapshot of the last activated
connection on the device, that is the configuration that is currently applied on the device.
Usually this is the same as GetSettings of the referenced settings connection. However, it
can differ if the settings connection was subsequently modified or the applied connection was
modified by Reapply. The applied connection is set when activating a device or when calling
Reapply.
</tp:docstring>
</method>

View File

@ -7366,6 +7366,100 @@ impl_device_reapply (NMDevice *self,
reapply_data);
}
/*****************************************************************************/
static void
get_applied_connection_cb (NMDevice *self,
GDBusMethodInvocation *context,
NMAuthSubject *subject,
GError *error,
gpointer user_data /* possibly dangling pointer */)
{
NMDevicePrivate *priv;
NMConnection *applied_connection;
GVariant *settings;
g_return_if_fail (NM_IS_DEVICE (self));
if (error) {
g_dbus_method_invocation_return_gerror (context, error);
return;
}
priv = NM_DEVICE_GET_PRIVATE (self);
applied_connection = nm_device_get_applied_connection (self);
if (!applied_connection) {
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ACTIVE,
"Device is not activated");
g_dbus_method_invocation_take_error (context, error);
return;
}
if (applied_connection != user_data) {
/* The applied connection changed due to a race. Reauthenticate. */
g_signal_emit (self, signals[AUTH_REQUEST], 0,
context,
applied_connection,
NM_AUTH_PERMISSION_NETWORK_CONTROL,
TRUE,
get_applied_connection_cb,
applied_connection /* no need take a ref. We will not dereference this pointer. */);
return;
}
settings = nm_connection_to_dbus (applied_connection, NM_CONNECTION_SERIALIZE_NO_SECRETS);
if (!settings)
settings = g_variant_new_array (G_VARIANT_TYPE ("{sa{sv}}"), NULL, 0);
g_dbus_method_invocation_return_value (context,
g_variant_new ("(@a{sa{sv}}t)",
settings,
nm_active_connection_version_id_get ((NMActiveConnection *) priv->act_request)));
}
static void
impl_device_get_applied_connection (NMDevice *self,
GDBusMethodInvocation *context,
guint32 flags)
{
NMConnection *applied_connection;
GError *error = NULL;
g_return_if_fail (NM_IS_DEVICE (self));
/* No flags supported as of now. */
if (flags != 0) {
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_FAILED,
"Invalid flags specified");
g_dbus_method_invocation_take_error (context, error);
return;
}
applied_connection = nm_device_get_applied_connection (self);
if (!applied_connection) {
error = g_error_new_literal (NM_DEVICE_ERROR,
NM_DEVICE_ERROR_NOT_ACTIVE,
"Device is not activated");
g_dbus_method_invocation_take_error (context, error);
return;
}
/* Ask the manager to authenticate this request for us */
g_signal_emit (self, signals[AUTH_REQUEST], 0,
context,
applied_connection,
NM_AUTH_PERMISSION_NETWORK_CONTROL,
TRUE,
get_applied_connection_cb,
applied_connection /* no need take a ref. We will not dereference this pointer. */);
}
/*****************************************************************************/
static void
disconnect_cb (NMDevice *self,
GDBusMethodInvocation *context,
@ -11724,6 +11818,7 @@ nm_device_class_init (NMDeviceClass *klass)
nm_exported_object_class_add_interface (NM_EXPORTED_OBJECT_CLASS (klass),
NMDBUS_TYPE_DEVICE_SKELETON,
"Reapply", impl_device_reapply,
"GetAppliedConnection", impl_device_get_applied_connection,
"Disconnect", impl_device_disconnect,
"Delete", impl_device_delete,
NULL);