mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-14 05:10:35 +01:00
libnm,core: merge branch 'th/settings-add2-and-update2-options'
https://bugzilla.redhat.com/show_bug.cgi?id=1677068 https://bugzilla.redhat.com/show_bug.cgi?id=1677070 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/201
This commit is contained in:
commit
40355d03a4
19 changed files with 845 additions and 265 deletions
|
|
@ -176,6 +176,7 @@ EXTRA_DIST += \
|
|||
examples/python/gi/get-active-connections.py \
|
||||
examples/python/gi/get_ips.py \
|
||||
examples/python/gi/list-connections.py \
|
||||
examples/python/gi/nm-add-connection2.py \
|
||||
examples/python/gi/nm-connection-update-stable-id.py \
|
||||
examples/python/gi/nm-wg-set \
|
||||
examples/python/gi/setting-user-data.py \
|
||||
|
|
|
|||
|
|
@ -41,6 +41,8 @@
|
|||
#include "devices.h"
|
||||
#include "polkit-agent.h"
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
PROPERTY_INF_FLAG_NONE = 0x0,
|
||||
PROPERTY_INF_FLAG_DISABLED = 0x1, /* Don't ask due to runtime decision. */
|
||||
|
|
@ -50,14 +52,13 @@ typedef enum {
|
|||
|
||||
typedef char *(*CompEntryFunc) (const char *, int);
|
||||
|
||||
typedef struct _OptionInfo OptionInfo;
|
||||
struct _OptionInfo {
|
||||
typedef struct _OptionInfo {
|
||||
const NMMetaSettingInfoEditor *setting_info;
|
||||
const char *property;
|
||||
const char *option;
|
||||
gboolean (*check_and_set)(NmCli *nmc, NMConnection *connection, const OptionInfo *option, const char *value, GError **error);
|
||||
gboolean (*check_and_set)(NmCli *nmc, NMConnection *connection, const struct _OptionInfo *option, const char *value, GError **error);
|
||||
CompEntryFunc generator_func;
|
||||
};
|
||||
} OptionInfo;
|
||||
|
||||
/* define some prompts for connection editor */
|
||||
#define EDITOR_PROMPT_SETTING _("Setting name? ")
|
||||
|
|
@ -96,6 +97,47 @@ NM_UTILS_LOOKUP_STR_DEFINE_STATIC (vpn_connection_state_to_string, NMVpnConnecti
|
|||
NM_UTILS_LOOKUP_ITEM_IGNORE (NM_VPN_CONNECTION_STATE_UNKNOWN),
|
||||
)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
NmCli *nmc;
|
||||
char *orig_id;
|
||||
char *orig_uuid;
|
||||
char *new_id;
|
||||
} AddConnectionInfo;
|
||||
|
||||
static AddConnectionInfo *
|
||||
_add_connection_info_new (NmCli *nmc,
|
||||
NMConnection *orig_connection,
|
||||
NMConnection *new_connection)
|
||||
{
|
||||
AddConnectionInfo *info;
|
||||
|
||||
info = g_slice_new (AddConnectionInfo);
|
||||
*info = (AddConnectionInfo) {
|
||||
.nmc = nmc,
|
||||
.orig_id = orig_connection ? g_strdup (nm_connection_get_id (orig_connection)) : NULL,
|
||||
.orig_uuid = orig_connection ? g_strdup (nm_connection_get_uuid (orig_connection)) : NULL,
|
||||
.new_id = g_strdup (nm_connection_get_id (new_connection)),
|
||||
};
|
||||
return info;
|
||||
}
|
||||
|
||||
static void
|
||||
_add_connection_info_free (AddConnectionInfo *info)
|
||||
{
|
||||
g_free (info->orig_id);
|
||||
g_free (info->orig_uuid);
|
||||
g_free (info->new_id);
|
||||
nm_g_slice_free (info);
|
||||
}
|
||||
|
||||
NM_AUTO_DEFINE_FCN (AddConnectionInfo *, _nm_auto_free_add_connection_info, _add_connection_info_free)
|
||||
|
||||
#define nm_auto_free_add_connection_info nm_auto (_nm_auto_free_add_connection_info)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* Essentially a version of nm_setting_connection_get_connection_type() that
|
||||
* prefers an alias instead of the settings name when in pretty print mode.
|
||||
* That is so that we print "wifi" instead of "802-11-wireless" in "nmcli c". */
|
||||
|
|
@ -4755,28 +4797,23 @@ nmc_read_connection_properties (NmCli *nmc,
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NmCli *nmc;
|
||||
char *con_name;
|
||||
} AddConnectionInfo;
|
||||
|
||||
static void
|
||||
add_connection_cb (GObject *client,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
AddConnectionInfo *info = (AddConnectionInfo *) user_data;
|
||||
nm_auto_free_add_connection_info AddConnectionInfo *info = user_data;
|
||||
NmCli *nmc = info->nmc;
|
||||
NMRemoteConnection *connection;
|
||||
GError *error = NULL;
|
||||
const GPtrArray *connections;
|
||||
guint i, found;
|
||||
|
||||
connection = nm_client_add_connection_finish (NM_CLIENT (client), result, &error);
|
||||
connection = nm_client_add_connection2_finish (NM_CLIENT (client), result, NULL, &error);
|
||||
if (error) {
|
||||
g_string_printf (nmc->return_text,
|
||||
_("Error: Failed to add '%s' connection: %s"),
|
||||
info->con_name, error->message);
|
||||
info->new_id, error->message);
|
||||
g_error_free (error);
|
||||
nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
|
||||
} else {
|
||||
|
|
@ -4788,7 +4825,7 @@ add_connection_cb (GObject *client,
|
|||
|
||||
if ((NMConnection *) connection == candidate)
|
||||
continue;
|
||||
if (nm_streq0 (nm_connection_get_id (candidate), info->con_name))
|
||||
if (nm_streq0 (nm_connection_get_id (candidate), info->new_id))
|
||||
found++;
|
||||
}
|
||||
if (found > 0) {
|
||||
|
|
@ -4796,7 +4833,7 @@ add_connection_cb (GObject *client,
|
|||
"Warning: There is another connection with the name '%1$s'. Reference the connection by its uuid '%2$s'\n",
|
||||
"Warning: There are %3$u other connections with the name '%1$s'. Reference the connection by its uuid '%2$s'\n",
|
||||
found),
|
||||
info->con_name,
|
||||
info->new_id,
|
||||
nm_connection_get_uuid (NM_CONNECTION (connection)),
|
||||
found);
|
||||
}
|
||||
|
|
@ -4808,30 +4845,39 @@ add_connection_cb (GObject *client,
|
|||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
g_free (info->con_name);
|
||||
g_free (info);
|
||||
quit ();
|
||||
}
|
||||
|
||||
static void
|
||||
add_new_connection (gboolean persistent,
|
||||
NMClient *client,
|
||||
NMConnection *connection,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
add_connection (NMClient *client,
|
||||
NMConnection *connection,
|
||||
gboolean temporary,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
nm_client_add_connection_async (client, connection, persistent,
|
||||
NULL, callback, user_data);
|
||||
nm_client_add_connection2 (client,
|
||||
nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL),
|
||||
temporary
|
||||
? NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY
|
||||
: NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK,
|
||||
NULL,
|
||||
TRUE,
|
||||
NULL,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
static void
|
||||
update_connection (gboolean persistent,
|
||||
NMRemoteConnection *connection,
|
||||
update_connection (NMRemoteConnection *connection,
|
||||
gboolean temporary,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
nm_remote_connection_commit_changes_async (connection, persistent,
|
||||
NULL, callback, user_data);
|
||||
nm_remote_connection_commit_changes_async (connection,
|
||||
!temporary,
|
||||
NULL,
|
||||
callback,
|
||||
user_data);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
|
|
@ -5150,7 +5196,6 @@ do_connection_add (NmCli *nmc, int argc, char **argv)
|
|||
gs_unref_object NMConnection *connection = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
gs_free_error GError *error = NULL;
|
||||
AddConnectionInfo *info = NULL;
|
||||
gboolean save_bool = TRUE;
|
||||
gboolean seen_dash_dash = FALSE;
|
||||
NMMetaSettingType s;
|
||||
|
|
@ -5295,19 +5340,13 @@ read_properties:
|
|||
}
|
||||
}
|
||||
|
||||
add_connection (nmc->client,
|
||||
connection,
|
||||
!save_bool,
|
||||
add_connection_cb,
|
||||
_add_connection_info_new (nmc, NULL, connection));
|
||||
nmc->should_wait++;
|
||||
|
||||
info = g_malloc0 (sizeof (AddConnectionInfo));
|
||||
info->nmc = nmc;
|
||||
info->con_name = g_strdup (nm_connection_get_id (connection));
|
||||
|
||||
/* Tell the settings service to add the new connection */
|
||||
add_new_connection (save_bool,
|
||||
nmc->client,
|
||||
connection,
|
||||
add_connection_cb,
|
||||
info);
|
||||
|
||||
finish:
|
||||
reset_options ();
|
||||
return nmc->return_value;
|
||||
|
|
@ -6656,14 +6695,11 @@ add_connection_editor_cb (GObject *client,
|
|||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMRemoteConnection *connection;
|
||||
GError *error = NULL;
|
||||
gs_unref_object NMRemoteConnection *connection = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
connection = nm_client_add_connection_finish (NM_CLIENT (client), result, &error);
|
||||
connection = nm_client_add_connection2_finish (NM_CLIENT (client), result, NULL, &error);
|
||||
set_info_and_signal_editor_thread (error, NULL);
|
||||
|
||||
g_clear_object (&connection);
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -7242,7 +7278,6 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
const NMMetaSettingValidPartItem *const*valid_settings_slave;
|
||||
gs_free char *valid_settings_str = NULL;
|
||||
const char *s_type = NULL;
|
||||
AddConnectionInfo *info = NULL;
|
||||
gboolean temp_changes;
|
||||
GError *err1 = NULL;
|
||||
NmcEditorMenuContext menu_ctx = { 0 };
|
||||
|
|
@ -7761,7 +7796,7 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
case NMC_EDITOR_MAIN_CMD_SAVE:
|
||||
/* Save the connection */
|
||||
if (nm_connection_verify (connection, &err1)) {
|
||||
gboolean persistent = TRUE;
|
||||
gboolean temporary = FALSE;
|
||||
gboolean connection_changed;
|
||||
nm_auto_unref_gsource GSource *source = NULL;
|
||||
gboolean timeout = FALSE;
|
||||
|
|
@ -7770,9 +7805,9 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
/* parse argument */
|
||||
if (cmd_arg) {
|
||||
if (matches (cmd_arg, "temporary"))
|
||||
persistent = FALSE;
|
||||
temporary = TRUE;
|
||||
else if (matches (cmd_arg, "persistent"))
|
||||
persistent = TRUE;
|
||||
temporary = FALSE;
|
||||
else {
|
||||
g_print (_("Error: invalid argument '%s'\n"), cmd_arg);
|
||||
break;
|
||||
|
|
@ -7788,21 +7823,17 @@ editor_menu_main (NmCli *nmc, NMConnection *connection, const char *connection_t
|
|||
}
|
||||
|
||||
if (!rem_con) {
|
||||
/* Tell the settings service to add the new connection */
|
||||
info = g_malloc0 (sizeof (AddConnectionInfo));
|
||||
info->nmc = nmc;
|
||||
info->con_name = g_strdup (nm_connection_get_id (connection));
|
||||
add_new_connection (persistent,
|
||||
nmc->client,
|
||||
connection,
|
||||
add_connection_editor_cb,
|
||||
info);
|
||||
add_connection (nmc->client,
|
||||
connection,
|
||||
temporary,
|
||||
add_connection_editor_cb,
|
||||
NULL);
|
||||
connection_changed = TRUE;
|
||||
} else {
|
||||
/* Save/update already saved (existing) connection */
|
||||
nm_connection_replace_settings_from_connection (NM_CONNECTION (rem_con),
|
||||
connection);
|
||||
update_connection (persistent, rem_con, update_connection_editor_cb, NULL);
|
||||
update_connection (rem_con, temporary, update_connection_editor_cb, NULL);
|
||||
|
||||
handler_id = g_signal_connect (rem_con,
|
||||
NM_CONNECTION_CHANGED,
|
||||
|
|
@ -8403,35 +8434,27 @@ do_connection_modify (NmCli *nmc,
|
|||
if (nmc->complete)
|
||||
return nmc->return_value;
|
||||
|
||||
update_connection (!temporary, rc, modify_connection_cb, nmc);
|
||||
update_connection (rc, temporary, modify_connection_cb, nmc);
|
||||
nmc->should_wait++;
|
||||
|
||||
return nmc->return_value;
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
NmCli *nmc;
|
||||
char *orig_id;
|
||||
char *orig_uuid;
|
||||
char *con_id;
|
||||
} CloneConnectionInfo;
|
||||
|
||||
static void
|
||||
clone_connection_cb (GObject *client,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
CloneConnectionInfo *info = (CloneConnectionInfo *) user_data;
|
||||
nm_auto_free_add_connection_info AddConnectionInfo *info = user_data;
|
||||
NmCli *nmc = info->nmc;
|
||||
NMRemoteConnection *connection;
|
||||
GError *error = NULL;
|
||||
gs_unref_object NMRemoteConnection *connection = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
connection = nm_client_add_connection_finish (NM_CLIENT (client), result, &error);
|
||||
connection = nm_client_add_connection2_finish (NM_CLIENT (client), result, NULL, &error);
|
||||
if (error) {
|
||||
g_string_printf (nmc->return_text,
|
||||
_("Error: Failed to add '%s' connection: %s"),
|
||||
info->con_id, error->message);
|
||||
g_error_free (error);
|
||||
info->new_id, error->message);
|
||||
nmc->return_value = NMC_RESULT_ERROR_CON_ACTIVATION;
|
||||
} else {
|
||||
g_print (_("%s (%s) cloned as %s (%s).\n"),
|
||||
|
|
@ -8439,13 +8462,8 @@ clone_connection_cb (GObject *client,
|
|||
info->orig_uuid,
|
||||
nm_connection_get_id (NM_CONNECTION (connection)),
|
||||
nm_connection_get_uuid (NM_CONNECTION (connection)));
|
||||
g_object_unref (connection);
|
||||
}
|
||||
|
||||
g_free (info->con_id);
|
||||
g_free (info->orig_id);
|
||||
g_free (info->orig_uuid);
|
||||
g_slice_free (CloneConnectionInfo, info);
|
||||
quit ();
|
||||
}
|
||||
|
||||
|
|
@ -8454,11 +8472,9 @@ do_connection_clone (NmCli *nmc, int argc, char **argv)
|
|||
{
|
||||
NMConnection *connection = NULL;
|
||||
gs_unref_object NMConnection *new_connection = NULL;
|
||||
NMSettingConnection *s_con;
|
||||
CloneConnectionInfo *info;
|
||||
const char *new_name;
|
||||
gs_free char *new_name_ask = NULL;
|
||||
char *uuid;
|
||||
gs_free char *new_name_free = NULL;
|
||||
gs_free char *uuid = NULL;
|
||||
gboolean temporary = FALSE;
|
||||
char **arg_arr = NULL;
|
||||
int arg_num;
|
||||
|
|
@ -8499,8 +8515,8 @@ do_connection_clone (NmCli *nmc, int argc, char **argv)
|
|||
if (argv[0])
|
||||
new_name = *argv;
|
||||
else if (nmc->ask) {
|
||||
new_name = new_name_ask = nmc_readline (&nmc->nmc_config,
|
||||
_("New connection name: "));
|
||||
new_name = new_name_free = nmc_readline (&nmc->nmc_config,
|
||||
_("New connection name: "));
|
||||
} else {
|
||||
g_string_printf (nmc->return_text, _("Error: <new name> argument is missing."));
|
||||
NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT);
|
||||
|
|
@ -8511,35 +8527,23 @@ do_connection_clone (NmCli *nmc, int argc, char **argv)
|
|||
NMC_RETURN (nmc, NMC_RESULT_ERROR_USER_INPUT);
|
||||
}
|
||||
|
||||
/* Copy the connection */
|
||||
new_connection = nm_simple_connection_new_clone (connection);
|
||||
|
||||
s_con = nm_connection_get_setting_connection (new_connection);
|
||||
g_assert (s_con);
|
||||
uuid = nm_utils_uuid_generate ();
|
||||
g_object_set (s_con,
|
||||
g_object_set (nm_connection_get_setting_connection (new_connection),
|
||||
NM_SETTING_CONNECTION_ID, new_name,
|
||||
NM_SETTING_CONNECTION_UUID, uuid,
|
||||
NULL);
|
||||
g_free (uuid);
|
||||
|
||||
/* Merge secrets into the new connection */
|
||||
update_secrets_in_connection (NM_REMOTE_CONNECTION (connection), new_connection);
|
||||
|
||||
info = g_slice_new0 (CloneConnectionInfo);
|
||||
info->nmc = nmc;
|
||||
info->orig_id = g_strdup (nm_connection_get_id (connection));
|
||||
info->orig_uuid = g_strdup (nm_connection_get_uuid (connection));
|
||||
info->con_id = g_strdup (nm_connection_get_id (new_connection));
|
||||
|
||||
/* Add the new cloned connection to NetworkManager */
|
||||
add_new_connection (!temporary,
|
||||
nmc->client,
|
||||
new_connection,
|
||||
clone_connection_cb,
|
||||
info);
|
||||
|
||||
add_connection (nmc->client,
|
||||
new_connection,
|
||||
temporary,
|
||||
clone_connection_cb,
|
||||
_add_connection_info_new (nmc, connection, new_connection));
|
||||
nmc->should_wait++;
|
||||
|
||||
return nmc->return_value;
|
||||
}
|
||||
|
||||
|
|
@ -8826,7 +8830,6 @@ do_connection_import (NmCli *nmc, int argc, char **argv)
|
|||
const char *type = NULL, *filename = NULL;
|
||||
gs_free char *type_ask = NULL;
|
||||
gs_free char *filename_ask = NULL;
|
||||
AddConnectionInfo *info;
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
NMVpnEditorPlugin *plugin;
|
||||
gs_free char *service_type = NULL;
|
||||
|
|
@ -8943,18 +8946,13 @@ do_connection_import (NmCli *nmc, int argc, char **argv)
|
|||
NMC_RETURN (nmc, NMC_RESULT_ERROR_UNKNOWN);
|
||||
}
|
||||
|
||||
info = g_malloc0 (sizeof (AddConnectionInfo));
|
||||
info->nmc = nmc;
|
||||
info->con_name = g_strdup (nm_connection_get_id (connection));
|
||||
|
||||
/* Add the new imported connection to NetworkManager */
|
||||
add_new_connection (!temporary,
|
||||
nmc->client,
|
||||
connection,
|
||||
add_connection_cb,
|
||||
info);
|
||||
|
||||
add_connection (nmc->client,
|
||||
connection,
|
||||
temporary,
|
||||
add_connection_cb,
|
||||
_add_connection_info_new (nmc, NULL, connection));
|
||||
nmc->should_wait++;
|
||||
|
||||
return nmc->return_value;
|
||||
}
|
||||
|
||||
|
|
|
|||
156
examples/python/gi/nm-add-connection2.py
Executable file
156
examples/python/gi/nm-add-connection2.py
Executable file
|
|
@ -0,0 +1,156 @@
|
|||
#!/usr/bin/env python
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License along
|
||||
# with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
#
|
||||
# Copyright 2019 Red Hat, Inc.
|
||||
#
|
||||
|
||||
import sys
|
||||
import re
|
||||
|
||||
import gi
|
||||
gi.require_version('NM', '1.0')
|
||||
from gi.repository import GLib, NM
|
||||
|
||||
def find_connections(nm_client, arg_type, arg_id):
|
||||
for c in nm_client.get_connections():
|
||||
if arg_type in [None, 'id'] and c.get_id() == arg_id:
|
||||
yield c
|
||||
if arg_type in [None, 'uuid'] and c.get_uuid() == arg_id:
|
||||
yield c
|
||||
|
||||
def find_connection_first(nm_client, arg_type, arg_id):
|
||||
for f in find_connections(nm_client, arg_type, arg_id):
|
||||
return f
|
||||
|
||||
def con_to_str(con):
|
||||
s_con = con.get_setting_connection()
|
||||
return '"%s" (%s)' % (s_con.get_id(), s_con.get_uuid())
|
||||
|
||||
def usage():
|
||||
print('Usage: %s --clone [[id] <id>]' % (sys.argv[0]))
|
||||
print(' %s --clone [[uuid] <uuid>]' % (sys.argv[0]))
|
||||
return 1
|
||||
|
||||
def die(msg, print_usage=False):
|
||||
print(msg)
|
||||
if print_usage:
|
||||
usage()
|
||||
sys.exit(1)
|
||||
|
||||
def main():
|
||||
|
||||
main_loop = GLib.MainLoop()
|
||||
|
||||
nm_client = NM.Client.new(None)
|
||||
|
||||
arg_mode = None
|
||||
arg_block_autoconnect = NM.SettingsAddConnection2Flags.NONE
|
||||
arg_id = None
|
||||
arg_uuid = None
|
||||
|
||||
cons = []
|
||||
|
||||
argv = list(sys.argv[1:])
|
||||
while argv:
|
||||
if argv[0] == '--clone':
|
||||
match_type = None
|
||||
if len(argv) < 2:
|
||||
die('missing argument for --clone option')
|
||||
if argv[0] in ['id', 'uuid']:
|
||||
match_type = argv[0]
|
||||
if len(argv) < 3:
|
||||
die('missing argument for "--clone %s" option' % (match_type))
|
||||
argv = argv[1:]
|
||||
if cons:
|
||||
die('cannot specify --clone argument more than once')
|
||||
cons.extend(find_connections(nm_client, match_type, argv[1]))
|
||||
if len(cons) == 0:
|
||||
die('could not find connection for "--clone %s%s"' % ((match_type or ''), argv[1]))
|
||||
if len(cons) != 1:
|
||||
die('could not find unique connection for "--clone %s%s"' % ((match_type or ''), argv[1]))
|
||||
argv = argv[2:]
|
||||
continue
|
||||
if argv[0] in ['--block-autoconnect']:
|
||||
arg_block_autoconnect = NM.SettingsAddConnection2Flags.BLOCK_AUTOCONNECT
|
||||
argv = argv[1:]
|
||||
continue
|
||||
if argv[0] in ['--to-disk', '--in-memory']:
|
||||
if argv[0] == '--to-disk':
|
||||
v = NM.SettingsAddConnection2Flags.TO_DISK
|
||||
elif argv[0] == '--in-memory':
|
||||
v = NM.SettingsAddConnection2Flags.IN_MEMORY
|
||||
else:
|
||||
assert(False)
|
||||
if arg_mode is not None:
|
||||
die('duplicate storage modes ("%s")' % (argv[0]))
|
||||
arg_mode = v
|
||||
argv = argv[1:]
|
||||
continue
|
||||
if argv[0] in ['--id']:
|
||||
if len(argv) < 2:
|
||||
die('missing argument for --id option')
|
||||
arg_id = argv[1]
|
||||
argv = argv[2:]
|
||||
continue
|
||||
if argv[0] in ['--uuid']:
|
||||
if len(argv) < 2:
|
||||
die('missing argument for --uuid option')
|
||||
arg_uuid = argv[1]
|
||||
argv = argv[2:]
|
||||
continue
|
||||
die('unknown argument "%s"' % (argv[0]))
|
||||
|
||||
if len(cons) != 1:
|
||||
die('missing --clone argument', True)
|
||||
|
||||
con = cons[0]
|
||||
|
||||
con2 = NM.SimpleConnection.new_clone(con)
|
||||
|
||||
s_con = con2.get_setting_connection()
|
||||
if arg_id:
|
||||
s_con.set_property(NM.SETTING_CONNECTION_ID, arg_id)
|
||||
s_con.set_property(NM.SETTING_CONNECTION_UUID, arg_uuid or NM.utils_uuid_generate())
|
||||
|
||||
result = {}
|
||||
def _add_connection2_cb(cl, async_result, user_data):
|
||||
try:
|
||||
c, r = nm_client.add_connection2_finish(async_result)
|
||||
except Exception as e:
|
||||
result['error'] = e
|
||||
else:
|
||||
result['result'] = r
|
||||
result['connection'] = c
|
||||
main_loop.quit()
|
||||
|
||||
nm_client.add_connection2(con2.to_dbus(NM.ConnectionSerializationFlags.ALL),
|
||||
(arg_mode if arg_mode is not None else NM.SettingsAddConnection2Flags.TO_DISK)
|
||||
| arg_block_autoconnect,
|
||||
None,
|
||||
False,
|
||||
None,
|
||||
_add_connection2_cb,
|
||||
None)
|
||||
|
||||
main_loop.run()
|
||||
|
||||
if 'error' in result:
|
||||
die('update connection %s failed [%s]: %s' % (con_to_str(con2), ' '.join(sys.argv), result['error']))
|
||||
|
||||
print('update connection %s succeeded [%s]: %s, %s' % (con_to_str(con2), ' '.join(sys.argv), result['connection'].get_path(), result['result']))
|
||||
|
||||
if __name__ == '__main__':
|
||||
main()
|
||||
|
|
@ -63,6 +63,41 @@
|
|||
<arg name="path" type="o" direction="out"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
AddConnection2:
|
||||
@settings: New connection settings, properties, and (optionally) secrets.
|
||||
@flags: optional flags argument. Currently the following flags are supported:
|
||||
"0x1" (to-disk),
|
||||
"0x2" (in-memory),
|
||||
"0x20" (block-autoconnect).
|
||||
Unknown flags cause the call to fail.
|
||||
@args: optional arguments dictionary, for extensibility. Currently no
|
||||
arguments are accepted. Specifying unknown keys causes the call
|
||||
to fail.
|
||||
@path: Object path of the new connection that was just added.
|
||||
@result: output argument, currently no additional results are returned.
|
||||
|
||||
Add a new connection profile.
|
||||
|
||||
Either the flags 0x1 (to-disk) or 0x2 (in-memory) must be specified.
|
||||
The effect is whether to behave like AddConnection or AddConnectionUnsaved.
|
||||
If 0x20 (block-autoconnect) is specified, autoconnect for the new profile
|
||||
is blocked from the beginnin. Otherwise, the profile might automatically
|
||||
connect if a suitable device is around.
|
||||
|
||||
AddConnection2 is a extensible alternative to AddConnection, and AddConnectionUnsaved.
|
||||
The new variant can do everything that the older variants could, and more.
|
||||
|
||||
Since: 1.20
|
||||
-->
|
||||
<method name="AddConnection2">
|
||||
<arg name="settings" type="a{sa{sv}}" direction="in"/>
|
||||
<arg name="flags" type="u" direction="in"/>
|
||||
<arg name="args" type="a{sv}" direction="in"/>
|
||||
<arg name="path" type="o" direction="out"/>
|
||||
<arg name="result" type="a{sv}" direction="out"/>
|
||||
</method>
|
||||
|
||||
<!--
|
||||
LoadConnections:
|
||||
@filenames: Array of paths to on-disk connection profiles in directories monitored by NetworkManager.
|
||||
|
|
|
|||
|
|
@ -1005,6 +1005,27 @@ typedef enum { /*< flags >*/
|
|||
NM_ACTIVATION_STATE_FLAG_LIFETIME_BOUND_TO_PROFILE_VISIBILITY = 0x40,
|
||||
} NMActivationStateFlags;
|
||||
|
||||
/**
|
||||
* NMSettingsAddConnection2Flags:
|
||||
* @NM_SETTINGS_ADD_CONNECTION2_FLAG_NONE: an alias for numeric zero, no flags set.
|
||||
* @NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK: to persist the connection to disk.
|
||||
* @NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY: to make the connection in-memory only.
|
||||
* @NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT: usually, when the connection
|
||||
* has autoconnect enabled and gets added, it becomes eligible to autoconnect
|
||||
* right away. Setting this flag, disables autoconnect until the connection
|
||||
* is manually activated.
|
||||
*
|
||||
* Numeric flags for the "flags" argument of AddConnection2() D-Bus API.
|
||||
*
|
||||
* Since: 1.20
|
||||
*/
|
||||
typedef enum { /*< flags >*/
|
||||
NM_SETTINGS_ADD_CONNECTION2_FLAG_NONE = 0,
|
||||
NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK = 0x1,
|
||||
NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY = 0x2,
|
||||
NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT = 0x20,
|
||||
} NMSettingsAddConnection2Flags;
|
||||
|
||||
/**
|
||||
* NMSettingsUpdate2Flags:
|
||||
* @NM_SETTINGS_UPDATE2_FLAG_NONE: an alias for numeric zero, no flags set.
|
||||
|
|
@ -1039,6 +1060,13 @@ typedef enum { /*< flags >*/
|
|||
* has autoconnect enabled and is modified, it becomes eligible to autoconnect
|
||||
* right away. Setting this flag, disables autoconnect until the connection
|
||||
* is manually activated.
|
||||
* @NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY: when a profile gets modified that is
|
||||
* currently active, then these changes don't take effect for the active
|
||||
* device unless the profile gets reactivated or the configuration reapplied.
|
||||
* There are two exceptions: by default "connection.zone" and "connection.metered"
|
||||
* properties take effect immediately. Specify this flag to prevent these
|
||||
* properties to take effect, so that the change is restricted to modify
|
||||
* the profile. Since: 1.20.
|
||||
*
|
||||
* Since: 1.12
|
||||
*/
|
||||
|
|
@ -1050,6 +1078,7 @@ typedef enum { /*< flags >*/
|
|||
NM_SETTINGS_UPDATE2_FLAG_IN_MEMORY_ONLY = 0x8,
|
||||
NM_SETTINGS_UPDATE2_FLAG_VOLATILE = 0x10,
|
||||
NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT = 0x20,
|
||||
NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY = 0x40,
|
||||
} NMSettingsUpdate2Flags;
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -1611,6 +1611,8 @@ global:
|
|||
|
||||
libnm_1_20_0 {
|
||||
global:
|
||||
nm_client_add_connection2;
|
||||
nm_client_add_connection2_finish;
|
||||
nm_client_connectivity_check_get_uri;
|
||||
nm_device_modem_get_apn;
|
||||
nm_device_modem_get_device_id;
|
||||
|
|
@ -1622,4 +1624,5 @@ global:
|
|||
nm_setting_ovs_dpdk_get_devargs;
|
||||
nm_setting_ovs_dpdk_get_type;
|
||||
nm_setting_ovs_dpdk_new;
|
||||
nm_settings_add_connection2_flags_get_type;
|
||||
} libnm_1_18_0;
|
||||
|
|
|
|||
|
|
@ -1631,23 +1631,55 @@ nm_client_get_connection_by_uuid (NMClient *client, const char *uuid)
|
|||
return nm_remote_settings_get_connection_by_uuid (NM_CLIENT_GET_PRIVATE (client)->settings, uuid);
|
||||
}
|
||||
|
||||
static void
|
||||
add_connection_cb (GObject *object,
|
||||
GAsyncResult *result,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *simple = user_data;
|
||||
NMRemoteConnection *conn;
|
||||
GError *error = NULL;
|
||||
typedef struct {
|
||||
NMRemoteConnection *connection;
|
||||
GVariant *results;
|
||||
} AddConnection2CbData;
|
||||
|
||||
conn = nm_remote_settings_add_connection_finish (NM_REMOTE_SETTINGS (object), result, &error);
|
||||
if (conn)
|
||||
g_simple_async_result_set_op_res_gpointer (simple, conn, g_object_unref);
|
||||
else
|
||||
g_simple_async_result_take_error (simple, error);
|
||||
static void
|
||||
add_connection2_cb_data_destroy (gpointer user_data)
|
||||
{
|
||||
AddConnection2CbData *data = user_data;
|
||||
|
||||
g_object_unref (data->connection);
|
||||
nm_g_variant_unref (data->results);
|
||||
nm_g_slice_free (data);
|
||||
}
|
||||
|
||||
static void
|
||||
add_connection2_cb (NMRemoteSettings *self,
|
||||
NMRemoteConnection *connection,
|
||||
GVariant *results,
|
||||
GError *error,
|
||||
gpointer user_data)
|
||||
{
|
||||
gs_unref_object GSimpleAsyncResult *simple = user_data;
|
||||
|
||||
if (error) {
|
||||
g_simple_async_result_take_error (simple,
|
||||
g_error_new_literal (error->domain,
|
||||
error->code,
|
||||
error->message));
|
||||
} else if (g_simple_async_result_get_source_tag (simple) == nm_client_add_connection_async) {
|
||||
g_simple_async_result_set_op_res_gpointer (simple,
|
||||
g_object_ref (connection),
|
||||
g_object_unref);
|
||||
} else {
|
||||
AddConnection2CbData *data;
|
||||
|
||||
nm_assert (g_simple_async_result_get_source_tag (simple) == nm_client_add_connection2);
|
||||
|
||||
data = g_slice_new (AddConnection2CbData);
|
||||
*data = (AddConnection2CbData) {
|
||||
.connection = g_object_ref (connection),
|
||||
.results = nm_g_variant_ref (results),
|
||||
};
|
||||
g_simple_async_result_set_op_res_gpointer (simple,
|
||||
data,
|
||||
add_connection2_cb_data_destroy);
|
||||
}
|
||||
|
||||
g_simple_async_result_complete (simple);
|
||||
g_object_unref (simple);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1698,9 +1730,17 @@ nm_client_add_connection_async (NMClient *client,
|
|||
nm_client_add_connection_async);
|
||||
if (cancellable)
|
||||
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
||||
nm_remote_settings_add_connection_async (NM_CLIENT_GET_PRIVATE (client)->settings,
|
||||
connection, save_to_disk,
|
||||
cancellable, add_connection_cb, simple);
|
||||
|
||||
nm_remote_settings_add_connection2 (NM_CLIENT_GET_PRIVATE (client)->settings,
|
||||
nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL),
|
||||
save_to_disk
|
||||
? NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK
|
||||
: NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY,
|
||||
NULL,
|
||||
TRUE,
|
||||
cancellable,
|
||||
add_connection2_cb,
|
||||
simple);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -1722,13 +1762,111 @@ nm_client_add_connection_finish (NMClient *client,
|
|||
GSimpleAsyncResult *simple;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
|
||||
g_return_val_if_fail (G_IS_SIMPLE_ASYNC_RESULT (result), NULL);
|
||||
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), nm_client_add_connection_async), NULL);
|
||||
|
||||
simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
return NULL;
|
||||
else
|
||||
return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
|
||||
return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_client_add_connection2:
|
||||
* @client: the %NMClient
|
||||
* @settings: the "a{sa{sv}}" #GVariant with the content of the setting.
|
||||
* @flags: the %NMSettingsAddConnection2Flags argument.
|
||||
* @args: (allow-none): the "a{sv}" #GVariant with extra argument or %NULL
|
||||
* for no extra arguments.
|
||||
* @ignore_out_result: this function wraps AddConnection2(), which has an
|
||||
* additional result "a{sv}" output parameter. By setting this to %TRUE,
|
||||
* you signal that you are not interested in that output parameter.
|
||||
* This allows the function to fall back to AddConnection() and AddConnectionUnsaved(),
|
||||
* which is interesting if you run against an older server version that does
|
||||
* not yet provide AddConnection2(). By setting this to %FALSE, the function
|
||||
* under the hood always calls AddConnection2().
|
||||
* @cancellable: a #GCancellable, or %NULL
|
||||
* @callback: (scope async): callback to be called when the add operation completes
|
||||
* @user_data: (closure): caller-specific data passed to @callback
|
||||
*
|
||||
* Call AddConnection2() D-Bus API asynchronously.
|
||||
*
|
||||
* Since: 1.20
|
||||
**/
|
||||
void
|
||||
nm_client_add_connection2 (NMClient *client,
|
||||
GVariant *settings,
|
||||
NMSettingsAddConnection2Flags flags,
|
||||
GVariant *args,
|
||||
gboolean ignore_out_result,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_if_fail (NM_IS_CLIENT (client));
|
||||
g_return_if_fail (g_variant_is_of_type (settings, G_VARIANT_TYPE ("a{sa{sv}}")));
|
||||
g_return_if_fail (!args || g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
|
||||
|
||||
if (!_nm_client_check_nm_running (client, &error)) {
|
||||
g_simple_async_report_take_gerror_in_idle (G_OBJECT (client), callback, user_data, error);
|
||||
return;
|
||||
}
|
||||
|
||||
simple = g_simple_async_result_new (G_OBJECT (client),
|
||||
callback,
|
||||
user_data,
|
||||
nm_client_add_connection2);
|
||||
if (cancellable)
|
||||
g_simple_async_result_set_check_cancellable (simple, cancellable);
|
||||
|
||||
nm_remote_settings_add_connection2 (NM_CLIENT_GET_PRIVATE (client)->settings,
|
||||
settings,
|
||||
flags,
|
||||
args,
|
||||
ignore_out_result,
|
||||
cancellable,
|
||||
add_connection2_cb,
|
||||
simple);
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_client_add_connection2_finish:
|
||||
* @client: the #NMClient
|
||||
* @result: the #GAsyncResult
|
||||
* @out_result: (allow-none) (transfer full) (out): the output #GVariant
|
||||
* from AddConnection2().
|
||||
* If you care about the output result, then the "ignore_out_result"
|
||||
* parameter of nm_client_add_connection2() must not be set to %TRUE.
|
||||
* @error: (allow-none): the error argument.
|
||||
*
|
||||
* Returns: (transfer full): on success, a pointer to the added
|
||||
* #NMRemoteConnection.
|
||||
*
|
||||
* Since: 1.20
|
||||
*/
|
||||
NMRemoteConnection *
|
||||
nm_client_add_connection2_finish (NMClient *client,
|
||||
GAsyncResult *result,
|
||||
GVariant **out_result,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
AddConnection2CbData *data;
|
||||
|
||||
g_return_val_if_fail (NM_IS_CLIENT (client), NULL);
|
||||
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (client), nm_client_add_connection2), NULL);
|
||||
|
||||
simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (simple, error)) {
|
||||
NM_SET_OUT (out_result, NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
data = g_simple_async_result_get_op_res_gpointer (simple);
|
||||
NM_SET_OUT (out_result, g_variant_ref (data->results));
|
||||
return g_object_ref (data->connection);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
|||
|
|
@ -389,6 +389,22 @@ NMRemoteConnection *nm_client_add_connection_finish (NMClient *client,
|
|||
GAsyncResult *result,
|
||||
GError **error);
|
||||
|
||||
NM_AVAILABLE_IN_1_20
|
||||
void nm_client_add_connection2 (NMClient *client,
|
||||
GVariant *settings,
|
||||
NMSettingsAddConnection2Flags flags,
|
||||
GVariant *args,
|
||||
gboolean ignore_out_result,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
NM_AVAILABLE_IN_1_20
|
||||
NMRemoteConnection *nm_client_add_connection2_finish (NMClient *client,
|
||||
GAsyncResult *result,
|
||||
GVariant **out_result,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_client_load_connections (NMClient *client,
|
||||
char **filenames,
|
||||
char ***failures,
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@
|
|||
|
||||
#include "nm-remote-settings.h"
|
||||
|
||||
#include "c-list/src/c-list.h"
|
||||
#include "nm-dbus-interface.h"
|
||||
#include "nm-connection.h"
|
||||
#include "nm-client.h"
|
||||
|
|
@ -43,7 +44,7 @@ typedef struct {
|
|||
GPtrArray *visible_connections;
|
||||
|
||||
/* AddConnectionInfo objects that are waiting for the connection to become initialized */
|
||||
GSList *add_list;
|
||||
CList add_lst_head;
|
||||
|
||||
char *hostname;
|
||||
gboolean can_modify;
|
||||
|
|
@ -70,51 +71,78 @@ static guint signals[LAST_SIGNAL] = { 0 };
|
|||
/*****************************************************************************/
|
||||
|
||||
typedef struct {
|
||||
CList add_lst;
|
||||
NMRemoteSettings *self;
|
||||
GSimpleAsyncResult *simple;
|
||||
NMRemoteSettingAddConnection2Callback callback;
|
||||
gpointer user_data;
|
||||
GCancellable *cancellable;
|
||||
char *path;
|
||||
gboolean saved;
|
||||
GVariant *results;
|
||||
gulong cancellable_id;
|
||||
NMSettingsAddConnection2Flags flags;
|
||||
bool ignore_out_result:1;
|
||||
} AddConnectionInfo;
|
||||
|
||||
static AddConnectionInfo *
|
||||
add_connection_info_find (NMRemoteSettings *self, const char *path)
|
||||
_add_connection_info_find (NMRemoteSettings *self, const char *path)
|
||||
{
|
||||
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
GSList *iter;
|
||||
AddConnectionInfo *info;
|
||||
|
||||
for (iter = priv->add_list; iter; iter = g_slist_next (iter)) {
|
||||
AddConnectionInfo *info = iter->data;
|
||||
|
||||
if (!g_strcmp0 (info->path, path))
|
||||
c_list_for_each_entry (info, &priv->add_lst_head, add_lst) {
|
||||
if (nm_streq0 (info->path, path))
|
||||
return info;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
add_connection_info_complete (NMRemoteSettings *self,
|
||||
AddConnectionInfo *info,
|
||||
NMRemoteConnection *connection,
|
||||
GError *error)
|
||||
_add_connection_info_complete (AddConnectionInfo *info,
|
||||
NMRemoteConnection *connection,
|
||||
GError *error_take)
|
||||
{
|
||||
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
nm_assert (info);
|
||||
|
||||
g_return_if_fail (info != NULL);
|
||||
c_list_unlink_stale (&info->add_lst);
|
||||
|
||||
if (connection) {
|
||||
g_simple_async_result_set_op_res_gpointer (info->simple,
|
||||
g_object_ref (connection),
|
||||
g_object_unref);
|
||||
} else
|
||||
g_simple_async_result_set_from_error (info->simple, error);
|
||||
g_simple_async_result_complete (info->simple);
|
||||
nm_clear_g_signal_handler (info->cancellable, &info->cancellable_id);
|
||||
|
||||
g_object_unref (info->simple);
|
||||
priv->add_list = g_slist_remove (priv->add_list, info);
|
||||
if ( info->cancellable
|
||||
&& !nm_utils_error_is_cancelled (error_take, FALSE)) {
|
||||
GError *error2 = NULL;
|
||||
|
||||
g_free (info->path);
|
||||
g_slice_free (AddConnectionInfo, info);
|
||||
if (g_cancellable_set_error_if_cancelled (info->cancellable, &error2)) {
|
||||
g_clear_error (&error_take);
|
||||
error_take = error2;
|
||||
connection = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
info->callback (info->self,
|
||||
connection,
|
||||
connection ? info->results : NULL,
|
||||
error_take,
|
||||
info->user_data);
|
||||
|
||||
g_clear_error (&error_take);
|
||||
|
||||
g_object_unref (info->self);
|
||||
nm_g_object_unref (info->cancellable);
|
||||
nm_clear_g_free (&info->path);
|
||||
nm_g_variant_unref (info->results);
|
||||
|
||||
nm_g_slice_free (info);
|
||||
}
|
||||
|
||||
static void
|
||||
_add_connection_info_cancelled (GCancellable *cancellable,
|
||||
AddConnectionInfo *info)
|
||||
{
|
||||
_add_connection_info_complete (info,
|
||||
NULL,
|
||||
g_error_new_literal (G_IO_ERROR,
|
||||
G_IO_ERROR_CANCELLED,
|
||||
"Operation was cancelled"));
|
||||
}
|
||||
|
||||
typedef const char * (*ConnectionStringGetter) (NMConnection *);
|
||||
|
|
@ -216,7 +244,7 @@ connection_added (NMRemoteSettings *self,
|
|||
NMRemoteConnection *remote)
|
||||
{
|
||||
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
AddConnectionInfo *addinfo;
|
||||
AddConnectionInfo *info;
|
||||
const char *path;
|
||||
|
||||
if (!g_signal_handler_find (remote, G_SIGNAL_MATCH_FUNC | G_SIGNAL_MATCH_DATA, 0, 0, NULL,
|
||||
|
|
@ -233,26 +261,27 @@ connection_added (NMRemoteSettings *self,
|
|||
g_signal_stop_emission (self, signals[CONNECTION_ADDED], 0);
|
||||
|
||||
path = nm_connection_get_path (NM_CONNECTION (remote));
|
||||
addinfo = add_connection_info_find (self, path);
|
||||
if (addinfo)
|
||||
add_connection_info_complete (self, addinfo, remote, NULL);
|
||||
info = _add_connection_info_find (self, path);
|
||||
if (info)
|
||||
_add_connection_info_complete (info, remote, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
object_creation_failed (NMObject *object, const char *failed_path)
|
||||
object_creation_failed (NMObject *object,
|
||||
const char *failed_path)
|
||||
{
|
||||
NMRemoteSettings *self = NM_REMOTE_SETTINGS (object);
|
||||
AddConnectionInfo *addinfo;
|
||||
GError *add_error;
|
||||
AddConnectionInfo *info;
|
||||
|
||||
addinfo = add_connection_info_find (self, failed_path);
|
||||
if (addinfo) {
|
||||
add_error = g_error_new_literal (NM_CLIENT_ERROR,
|
||||
NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
|
||||
_("Connection removed before it was initialized"));
|
||||
add_connection_info_complete (self, addinfo, NULL, add_error);
|
||||
g_error_free (add_error);
|
||||
}
|
||||
info = _add_connection_info_find (self, failed_path);
|
||||
if (!info)
|
||||
return;
|
||||
|
||||
_add_connection_info_complete (info,
|
||||
NULL,
|
||||
g_error_new_literal (NM_CLIENT_ERROR,
|
||||
NM_CLIENT_ERROR_OBJECT_CREATION_FAILED,
|
||||
_("Connection removed before it was initialized")));
|
||||
}
|
||||
|
||||
const GPtrArray *
|
||||
|
|
@ -269,83 +298,114 @@ add_connection_done (GObject *proxy, GAsyncResult *result, gpointer user_data)
|
|||
AddConnectionInfo *info = user_data;
|
||||
GError *error = NULL;
|
||||
|
||||
if (info->saved) {
|
||||
if ( info->ignore_out_result
|
||||
&& info->flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK) {
|
||||
nmdbus_settings_call_add_connection_finish (NMDBUS_SETTINGS (proxy),
|
||||
&info->path,
|
||||
result, &error);
|
||||
} else {
|
||||
result,
|
||||
&error);
|
||||
} else if ( info->ignore_out_result
|
||||
&& info->flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY) {
|
||||
nmdbus_settings_call_add_connection_unsaved_finish (NMDBUS_SETTINGS (proxy),
|
||||
&info->path,
|
||||
result, &error);
|
||||
result,
|
||||
&error);
|
||||
} else {
|
||||
nmdbus_settings_call_add_connection2_finish (NMDBUS_SETTINGS (proxy),
|
||||
&info->path,
|
||||
&info->results,
|
||||
result,
|
||||
&error);
|
||||
if (info->ignore_out_result) {
|
||||
/* despite we have the result, the caller didn't ask for it.
|
||||
* Through it away, so we consistently don't return a result. */
|
||||
nm_clear_pointer (&info->results, g_variant_unref);
|
||||
}
|
||||
}
|
||||
|
||||
if (error) {
|
||||
g_dbus_error_strip_remote_error (error);
|
||||
add_connection_info_complete (info->self, info, NULL, error);
|
||||
g_clear_error (&error);
|
||||
_add_connection_info_complete (info, NULL, error);
|
||||
return;
|
||||
}
|
||||
|
||||
/* On success, we still have to wait until the connection is fully
|
||||
* initialized before calling the callback.
|
||||
*/
|
||||
if (info->cancellable) {
|
||||
gulong id;
|
||||
|
||||
id = g_cancellable_connect (info->cancellable,
|
||||
G_CALLBACK (_add_connection_info_cancelled),
|
||||
info,
|
||||
NULL);
|
||||
if (id == 0) {
|
||||
/* the callback was invoked synchronously, which destroyed @info.
|
||||
* We must not touch @info anymore. */
|
||||
} else
|
||||
info->cancellable_id = id;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nm_remote_settings_add_connection_async (NMRemoteSettings *settings,
|
||||
NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data)
|
||||
nm_remote_settings_add_connection2 (NMRemoteSettings *self,
|
||||
GVariant *settings,
|
||||
NMSettingsAddConnection2Flags flags,
|
||||
GVariant *args,
|
||||
gboolean ignore_out_result,
|
||||
GCancellable *cancellable,
|
||||
NMRemoteSettingAddConnection2Callback callback,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMRemoteSettingsPrivate *priv;
|
||||
AddConnectionInfo *info;
|
||||
GVariant *new_settings;
|
||||
|
||||
g_return_if_fail (NM_IS_REMOTE_SETTINGS (settings));
|
||||
g_return_if_fail (NM_IS_CONNECTION (connection));
|
||||
nm_assert (NM_IS_REMOTE_SETTINGS (self));
|
||||
nm_assert (g_variant_is_of_type (settings, G_VARIANT_TYPE ("a{sa{sv}}")));
|
||||
nm_assert (!args || g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
|
||||
nm_assert (callback);
|
||||
|
||||
priv = NM_REMOTE_SETTINGS_GET_PRIVATE (settings);
|
||||
priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
|
||||
info = g_slice_new0 (AddConnectionInfo);
|
||||
info->self = settings;
|
||||
info->simple = g_simple_async_result_new (G_OBJECT (settings), callback, user_data,
|
||||
nm_remote_settings_add_connection_async);
|
||||
if (cancellable)
|
||||
g_simple_async_result_set_check_cancellable (info->simple, cancellable);
|
||||
info->saved = save_to_disk;
|
||||
info = g_slice_new (AddConnectionInfo);
|
||||
*info = (AddConnectionInfo) {
|
||||
.self = g_object_ref (self),
|
||||
.cancellable = nm_g_object_ref (cancellable),
|
||||
.flags = flags,
|
||||
.ignore_out_result = ignore_out_result,
|
||||
.callback = callback,
|
||||
.user_data = user_data,
|
||||
};
|
||||
c_list_link_tail (&priv->add_lst_head, &info->add_lst);
|
||||
|
||||
new_settings = nm_connection_to_dbus (connection, NM_CONNECTION_SERIALIZE_ALL);
|
||||
|
||||
if (save_to_disk) {
|
||||
/* Although AddConnection2() being capable to handle also AddConnection() and
|
||||
* AddConnectionUnsaved() variants, we prefer to use the old D-Bus methods when
|
||||
* they are sufficient. The reason is that libnm should avoid hard dependencies
|
||||
* on 1.20 API whenever possible. */
|
||||
if ( ignore_out_result
|
||||
&& flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK) {
|
||||
nmdbus_settings_call_add_connection (priv->proxy,
|
||||
new_settings,
|
||||
NULL,
|
||||
add_connection_done, info);
|
||||
} else {
|
||||
settings,
|
||||
cancellable,
|
||||
add_connection_done,
|
||||
info);
|
||||
} else if ( ignore_out_result
|
||||
&& flags == NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY) {
|
||||
nmdbus_settings_call_add_connection_unsaved (priv->proxy,
|
||||
new_settings,
|
||||
NULL,
|
||||
add_connection_done, info);
|
||||
settings,
|
||||
cancellable,
|
||||
add_connection_done,
|
||||
info);
|
||||
} else {
|
||||
nmdbus_settings_call_add_connection2 (priv->proxy,
|
||||
settings,
|
||||
flags,
|
||||
args
|
||||
?: g_variant_new_array (G_VARIANT_TYPE ("{sv}"), NULL, 0),
|
||||
cancellable,
|
||||
add_connection_done,
|
||||
info);
|
||||
}
|
||||
|
||||
priv->add_list = g_slist_append (priv->add_list, info);
|
||||
}
|
||||
|
||||
NMRemoteConnection *
|
||||
nm_remote_settings_add_connection_finish (NMRemoteSettings *settings,
|
||||
GAsyncResult *result,
|
||||
GError **error)
|
||||
{
|
||||
GSimpleAsyncResult *simple;
|
||||
|
||||
g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (settings), nm_remote_settings_add_connection_async), NULL);
|
||||
|
||||
simple = G_SIMPLE_ASYNC_RESULT (result);
|
||||
if (g_simple_async_result_propagate_error (simple, error))
|
||||
return NULL;
|
||||
else
|
||||
return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
|
||||
}
|
||||
|
||||
gboolean
|
||||
|
|
@ -606,6 +666,7 @@ nm_remote_settings_init (NMRemoteSettings *self)
|
|||
{
|
||||
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
|
||||
c_list_init (&priv->add_lst_head);
|
||||
priv->all_connections = g_ptr_array_new ();
|
||||
priv->visible_connections = g_ptr_array_new ();
|
||||
}
|
||||
|
|
@ -664,7 +725,7 @@ dispose (GObject *object)
|
|||
{
|
||||
NMRemoteSettings *self = NM_REMOTE_SETTINGS (object);
|
||||
NMRemoteSettingsPrivate *priv = NM_REMOTE_SETTINGS_GET_PRIVATE (self);
|
||||
int i;
|
||||
guint i;
|
||||
|
||||
if (priv->all_connections) {
|
||||
for (i = 0; i < priv->all_connections->len; i++)
|
||||
|
|
|
|||
|
|
@ -73,15 +73,20 @@ NMRemoteConnection *nm_remote_settings_get_connection_by_path (NMRemoteSettings
|
|||
NMRemoteConnection *nm_remote_settings_get_connection_by_uuid (NMRemoteSettings *settings,
|
||||
const char *uuid);
|
||||
|
||||
void nm_remote_settings_add_connection_async (NMRemoteSettings *settings,
|
||||
NMConnection *connection,
|
||||
gboolean save_to_disk,
|
||||
GCancellable *cancellable,
|
||||
GAsyncReadyCallback callback,
|
||||
gpointer user_data);
|
||||
NMRemoteConnection *nm_remote_settings_add_connection_finish (NMRemoteSettings *settings,
|
||||
GAsyncResult *result,
|
||||
GError **error);
|
||||
typedef void (*NMRemoteSettingAddConnection2Callback) (NMRemoteSettings *self,
|
||||
NMRemoteConnection *connection,
|
||||
GVariant *results,
|
||||
GError *error,
|
||||
gpointer user_data);
|
||||
|
||||
void nm_remote_settings_add_connection2 (NMRemoteSettings *self,
|
||||
GVariant *settings,
|
||||
NMSettingsAddConnection2Flags flags,
|
||||
GVariant *args,
|
||||
gboolean ignore_out_result,
|
||||
GCancellable *cancellable,
|
||||
NMRemoteSettingAddConnection2Callback callback,
|
||||
gpointer user_data);
|
||||
|
||||
gboolean nm_remote_settings_load_connections (NMRemoteSettings *settings,
|
||||
char **filenames,
|
||||
|
|
|
|||
|
|
@ -1569,6 +1569,11 @@ nm_strcmp_p (gconstpointer a, gconstpointer b)
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
#define nm_g_slice_free(ptr) \
|
||||
g_slice_free (typeof (*(ptr)), ptr)
|
||||
|
||||
/*****************************************************************************/
|
||||
|
||||
/* like g_memdup(). The difference is that the @size argument is of type
|
||||
* gsize, while g_memdup() has type guint. Since, the size of container types
|
||||
* like GArray is guint as well, this means trying to g_memdup() an
|
||||
|
|
|
|||
|
|
@ -238,6 +238,7 @@ pan_connection_check_create (NMBluezDevice *self)
|
|||
nm_settings_add_connection (priv->settings,
|
||||
connection,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
||||
NM_SETTINGS_CONNECTION_ADD_REASON_NONE,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED,
|
||||
&added,
|
||||
&error);
|
||||
|
|
|
|||
|
|
@ -472,6 +472,7 @@ mirror_8021x_connection (NMIwdManager *self,
|
|||
if (!nm_settings_add_connection (priv->settings,
|
||||
connection,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
||||
NM_SETTINGS_CONNECTION_ADD_REASON_NONE,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED,
|
||||
&settings_connection,
|
||||
&error)) {
|
||||
|
|
|
|||
|
|
@ -258,6 +258,7 @@ restore_and_activate_connection (NMCheckpoint *self,
|
|||
if (!nm_settings_add_connection (NM_SETTINGS_GET,
|
||||
dev_checkpoint->settings_connection,
|
||||
persist_mode,
|
||||
NM_SETTINGS_CONNECTION_ADD_REASON_NONE,
|
||||
sett_flags,
|
||||
&connection,
|
||||
&local_error)) {
|
||||
|
|
|
|||
|
|
@ -2674,6 +2674,7 @@ get_existing_connection (NMManager *self,
|
|||
if (!nm_settings_add_connection (priv->settings,
|
||||
connection,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
||||
NM_SETTINGS_CONNECTION_ADD_REASON_NONE,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED,
|
||||
&added,
|
||||
|
|
@ -5419,6 +5420,7 @@ _add_and_activate_auth_done (NMManager *self,
|
|||
nm_settings_add_connection_dbus (priv->settings,
|
||||
connection,
|
||||
persist_mode,
|
||||
NM_SETTINGS_CONNECTION_ADD_REASON_NONE,
|
||||
( is_volatile
|
||||
? NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
|
||||
: NM_SETTINGS_CONNECTION_INT_FLAGS_NONE),
|
||||
|
|
|
|||
|
|
@ -1438,7 +1438,7 @@ update_complete (NMSettingsConnection *self,
|
|||
|
||||
g_variant_builder_init (&result, G_VARIANT_TYPE ("a{sv}"));
|
||||
g_dbus_method_invocation_return_value (info->context,
|
||||
g_variant_new ("(@a{sv})", g_variant_builder_end (&result)));
|
||||
g_variant_new ("(a{sv})", &result));
|
||||
} else
|
||||
g_dbus_method_invocation_return_value (info->context, NULL);
|
||||
|
||||
|
|
@ -1514,12 +1514,6 @@ update_auth_cb (NMSettingsConnection *self,
|
|||
} else
|
||||
persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_KEEP;
|
||||
|
||||
if (NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT)) {
|
||||
nm_settings_connection_autoconnect_blocked_reason_set (self,
|
||||
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
nm_settings_connection_update (self,
|
||||
info->new_settings,
|
||||
persist_mode,
|
||||
|
|
@ -1529,9 +1523,14 @@ update_auth_cb (NMSettingsConnection *self,
|
|||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED
|
||||
| NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE,
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_FORCE_RENAME
|
||||
| NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL
|
||||
| ( NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY)
|
||||
? NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE
|
||||
: NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL)
|
||||
| NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS
|
||||
| NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS,
|
||||
| NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS
|
||||
| ( NM_FLAGS_HAS (info->flags, NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT)
|
||||
? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT
|
||||
: NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE),
|
||||
"update-from-dbus",
|
||||
&local);
|
||||
|
||||
|
|
@ -1733,9 +1732,10 @@ impl_settings_connection_update2 (NMDBusObject *obj,
|
|||
|
||||
g_variant_get (parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args);
|
||||
|
||||
if (NM_FLAGS_ANY (flags_u, ~((guint32) (ALL_PERSIST_MODES |
|
||||
NM_SETTINGS_UPDATE2_FLAG_VOLATILE |
|
||||
NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT)))) {
|
||||
if (NM_FLAGS_ANY (flags_u, ~((guint32) ( ALL_PERSIST_MODES
|
||||
| NM_SETTINGS_UPDATE2_FLAG_VOLATILE
|
||||
| NM_SETTINGS_UPDATE2_FLAG_BLOCK_AUTOCONNECT
|
||||
| NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY)))) {
|
||||
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
|
||||
"Unknown flags");
|
||||
|
|
@ -1757,13 +1757,7 @@ impl_settings_connection_update2 (NMDBusObject *obj,
|
|||
return;
|
||||
}
|
||||
|
||||
if (!g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}"))) {
|
||||
error = g_error_new_literal (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
|
||||
"args is of invalid type");
|
||||
g_dbus_method_invocation_take_error (invocation, error);
|
||||
return;
|
||||
}
|
||||
nm_assert (g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
|
||||
|
||||
g_variant_iter_init (&iter, args);
|
||||
while (g_variant_iter_next (&iter, "{&sv}", &args_name, NULL)) {
|
||||
|
|
|
|||
|
|
@ -28,6 +28,14 @@
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
typedef enum {
|
||||
|
||||
NM_SETTINGS_CONNECTION_ADD_REASON_NONE = 0,
|
||||
|
||||
NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT = (1u << 0),
|
||||
|
||||
} NMSettingsConnectionAddReason;
|
||||
|
||||
typedef enum {
|
||||
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE = 0,
|
||||
|
|
@ -50,7 +58,10 @@ typedef enum {
|
|||
/* Usually, changing a profile that is currently active does not immediately
|
||||
* reapply the changes. The exception are connection.zone and connection.metered
|
||||
* properties. When this flag is set, then these two properties are reapplied
|
||||
* right away. */
|
||||
* right away.
|
||||
*
|
||||
* See also %NM_SETTINGS_UPDATE2_FLAG_NO_REAPPLY flag, to prevent partial reapply
|
||||
* during Update2(). */
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_REAPPLY_PARTIAL = (1u << 2),
|
||||
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_SYSTEM_SECRETS = (1u << 3),
|
||||
|
|
@ -64,6 +75,8 @@ typedef enum {
|
|||
* to disk and it the purpose why the profile was created should be forgotten. */
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_CLEAR_DEFAULT_WIRED = (1u << 7),
|
||||
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT = (1u << 8),
|
||||
|
||||
} NMSettingsConnectionUpdateReason;
|
||||
|
||||
typedef enum {
|
||||
|
|
|
|||
|
|
@ -923,7 +923,12 @@ _connection_changed_update (NMSettings *self,
|
|||
priv->connections_generation++;
|
||||
|
||||
g_signal_connect (sett_conn, NM_SETTINGS_CONNECTION_FLAGS_CHANGED, G_CALLBACK (connection_flags_changed), self);
|
||||
}
|
||||
|
||||
if (NM_FLAGS_HAS (update_reason, NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT)) {
|
||||
nm_settings_connection_autoconnect_blocked_reason_set (sett_conn,
|
||||
NM_SETTINGS_AUTO_CONNECT_BLOCKED_REASON_USER_REQUEST,
|
||||
TRUE);
|
||||
}
|
||||
|
||||
sett_mask |= NM_SETTINGS_CONNECTION_INT_FLAGS_VISIBLE;
|
||||
|
|
@ -1371,6 +1376,7 @@ _add_connection_to_first_plugin (NMSettings *self,
|
|||
* @self: the #NMSettings object
|
||||
* @connection: the source connection to create a new #NMSettingsConnection from
|
||||
* @persist_mode: the persist-mode for this profile.
|
||||
* @add_reason: the add-reason flags.
|
||||
* @sett_flags: the settings flags to set.
|
||||
* @out_sett_conn: (allow-none) (transfer none): the added settings connection on success.
|
||||
* @error: on return, a location to store any errors that may occur
|
||||
|
|
@ -1385,6 +1391,7 @@ gboolean
|
|||
nm_settings_add_connection (NMSettings *self,
|
||||
NMConnection *connection,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
NMSettingsConnectionAddReason add_reason,
|
||||
NMSettingsConnectionIntFlags sett_flags,
|
||||
NMSettingsConnection **out_sett_conn,
|
||||
GError **error)
|
||||
|
|
@ -1408,6 +1415,8 @@ nm_settings_add_connection (NMSettings *self,
|
|||
nm_assert ( !NM_FLAGS_HAS (sett_flags, NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE)
|
||||
|| persist_mode == NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY);
|
||||
|
||||
nm_assert (!NM_FLAGS_ANY (add_reason, ~NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT));
|
||||
|
||||
NM_SET_OUT (out_sett_conn, NULL);
|
||||
|
||||
uuid = nm_connection_get_uuid (connection);
|
||||
|
|
@ -1486,7 +1495,10 @@ nm_settings_add_connection (NMSettings *self,
|
|||
_NM_SETTINGS_CONNECTION_INT_FLAGS_PERSISTENT_MASK,
|
||||
FALSE,
|
||||
NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_SYSTEM_SECRETS
|
||||
| NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS);
|
||||
| NM_SETTINGS_CONNECTION_UPDATE_REASON_RESET_AGENT_SECRETS
|
||||
| ( NM_FLAGS_HAS (add_reason, NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT)
|
||||
? NM_SETTINGS_CONNECTION_UPDATE_REASON_BLOCK_AUTOCONNECT
|
||||
: NM_SETTINGS_CONNECTION_UPDATE_REASON_NONE));
|
||||
|
||||
nm_assert (sett_conn_entry == _sett_conn_entries_get (self, sett_conn_entry->uuid));
|
||||
nm_assert (NM_IS_SETTINGS_CONNECTION (sett_conn_entry->sett_conn));
|
||||
|
|
@ -1972,6 +1984,7 @@ pk_add_cb (NMAuthChain *chain,
|
|||
nm_settings_add_connection (self,
|
||||
connection,
|
||||
GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "persist-mode")),
|
||||
GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "add-reason")),
|
||||
GPOINTER_TO_UINT (nm_auth_chain_get_data (chain, "sett-flags")),
|
||||
&added,
|
||||
&error);
|
||||
|
|
@ -1999,6 +2012,7 @@ void
|
|||
nm_settings_add_connection_dbus (NMSettings *self,
|
||||
NMConnection *connection,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
NMSettingsConnectionAddReason add_reason,
|
||||
NMSettingsConnectionIntFlags sett_flags,
|
||||
NMAuthSubject *subject,
|
||||
GDBusMethodInvocation *context,
|
||||
|
|
@ -2073,6 +2087,7 @@ nm_settings_add_connection_dbus (NMSettings *self,
|
|||
nm_auth_chain_set_data (chain, "callback-data", user_data, NULL);
|
||||
nm_auth_chain_set_data (chain, "subject", g_object_ref (subject), g_object_unref);
|
||||
nm_auth_chain_set_data (chain, "persist-mode", GUINT_TO_POINTER (persist_mode), NULL);
|
||||
nm_auth_chain_set_data (chain, "add-reason", GUINT_TO_POINTER (add_reason), NULL);
|
||||
nm_auth_chain_set_data (chain, "sett-flags", GUINT_TO_POINTER (sett_flags), NULL);
|
||||
nm_auth_chain_add_call_unsafe (chain, perm, TRUE);
|
||||
return;
|
||||
|
|
@ -2091,27 +2106,42 @@ settings_add_connection_add_cb (NMSettings *self,
|
|||
NMAuthSubject *subject,
|
||||
gpointer user_data)
|
||||
{
|
||||
gboolean is_add_connection_2 = GPOINTER_TO_INT (user_data);
|
||||
|
||||
if (error) {
|
||||
g_dbus_method_invocation_return_gerror (context, error);
|
||||
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, NULL, FALSE, NULL, subject, error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
if (is_add_connection_2) {
|
||||
GVariantBuilder builder;
|
||||
|
||||
g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT);
|
||||
g_dbus_method_invocation_return_value (context,
|
||||
g_variant_new ("(oa{sv})",
|
||||
nm_dbus_object_get_path (NM_DBUS_OBJECT (connection)),
|
||||
&builder));
|
||||
} else {
|
||||
g_dbus_method_invocation_return_value (context,
|
||||
g_variant_new ("(o)",
|
||||
nm_dbus_object_get_path (NM_DBUS_OBJECT (connection))));
|
||||
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE, NULL,
|
||||
subject, NULL);
|
||||
}
|
||||
nm_audit_log_connection_op (NM_AUDIT_OP_CONN_ADD, connection, TRUE, NULL,
|
||||
subject, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
settings_add_connection_helper (NMSettings *self,
|
||||
GDBusMethodInvocation *context,
|
||||
gboolean is_add_connection_2,
|
||||
GVariant *settings,
|
||||
NMSettingsConnectionPersistMode persist_mode)
|
||||
NMSettingsAddConnection2Flags flags)
|
||||
{
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
GError *error = NULL;
|
||||
gs_unref_object NMAuthSubject *subject = NULL;
|
||||
NMSettingsConnectionPersistMode persist_mode;
|
||||
|
||||
connection = _nm_simple_connection_new_from_dbus (settings,
|
||||
NM_SETTING_PARSE_FLAGS_STRICT
|
||||
|
|
@ -2133,14 +2163,24 @@ settings_add_connection_helper (NMSettings *self,
|
|||
return;
|
||||
}
|
||||
|
||||
if (NM_FLAGS_HAS (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK))
|
||||
persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK;
|
||||
else {
|
||||
nm_assert (NM_FLAGS_HAS (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY));
|
||||
persist_mode = NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY;
|
||||
}
|
||||
|
||||
nm_settings_add_connection_dbus (self,
|
||||
connection,
|
||||
persist_mode,
|
||||
NM_FLAGS_HAS (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT)
|
||||
? NM_SETTINGS_CONNECTION_ADD_REASON_BLOCK_AUTOCONNECT
|
||||
: NM_SETTINGS_CONNECTION_ADD_REASON_NONE,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NONE,
|
||||
subject,
|
||||
context,
|
||||
settings_add_connection_add_cb,
|
||||
NULL);
|
||||
GINT_TO_POINTER (!!is_add_connection_2));
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2156,7 +2196,7 @@ impl_settings_add_connection (NMDBusObject *obj,
|
|||
gs_unref_variant GVariant *settings = NULL;
|
||||
|
||||
g_variant_get (parameters, "(@a{sa{sv}})", &settings);
|
||||
settings_add_connection_helper (self, invocation, settings, NM_SETTINGS_CONNECTION_PERSIST_MODE_DISK);
|
||||
settings_add_connection_helper (self, invocation, FALSE, settings, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -2172,7 +2212,70 @@ impl_settings_add_connection_unsaved (NMDBusObject *obj,
|
|||
gs_unref_variant GVariant *settings = NULL;
|
||||
|
||||
g_variant_get (parameters, "(@a{sa{sv}})", &settings);
|
||||
settings_add_connection_helper (self, invocation, settings, NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY);
|
||||
settings_add_connection_helper (self, invocation, FALSE, settings, NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY);
|
||||
}
|
||||
|
||||
static void
|
||||
impl_settings_add_connection2 (NMDBusObject *obj,
|
||||
const NMDBusInterfaceInfoExtended *interface_info,
|
||||
const NMDBusMethodInfoExtended *method_info,
|
||||
GDBusConnection *connection,
|
||||
const char *sender,
|
||||
GDBusMethodInvocation *invocation,
|
||||
GVariant *parameters)
|
||||
{
|
||||
NMSettings *self = NM_SETTINGS (obj);
|
||||
gs_unref_variant GVariant *settings = NULL;
|
||||
gs_unref_variant GVariant *args = NULL;
|
||||
NMSettingsAddConnection2Flags flags;
|
||||
const char *args_name;
|
||||
GVariantIter iter;
|
||||
guint32 flags_u;
|
||||
|
||||
g_variant_get (parameters, "(@a{sa{sv}}u@a{sv})", &settings, &flags_u, &args);
|
||||
|
||||
if (NM_FLAGS_ANY (flags_u, ~((guint32) ( NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK
|
||||
| NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY
|
||||
| NM_SETTINGS_ADD_CONNECTION2_FLAG_BLOCK_AUTOCONNECT)))) {
|
||||
g_dbus_method_invocation_take_error (invocation,
|
||||
g_error_new_literal (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
|
||||
"Unknown flags"));
|
||||
return;
|
||||
}
|
||||
|
||||
flags = flags_u;
|
||||
|
||||
if (!NM_FLAGS_ANY (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK
|
||||
| NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY)) {
|
||||
g_dbus_method_invocation_take_error (invocation,
|
||||
g_error_new_literal (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
|
||||
"Requires either to-disk (0x1) or in-memory (0x2) flags"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (NM_FLAGS_ALL (flags, NM_SETTINGS_ADD_CONNECTION2_FLAG_TO_DISK
|
||||
| NM_SETTINGS_ADD_CONNECTION2_FLAG_IN_MEMORY)) {
|
||||
g_dbus_method_invocation_take_error (invocation,
|
||||
g_error_new_literal (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
|
||||
"Cannot set to-disk (0x1) and in-memory (0x2) flags together"));
|
||||
return;
|
||||
}
|
||||
|
||||
nm_assert (g_variant_is_of_type (args, G_VARIANT_TYPE ("a{sv}")));
|
||||
|
||||
g_variant_iter_init (&iter, args);
|
||||
while (g_variant_iter_next (&iter, "{&sv}", &args_name, NULL)) {
|
||||
g_dbus_method_invocation_take_error (invocation,
|
||||
g_error_new (NM_SETTINGS_ERROR,
|
||||
NM_SETTINGS_ERROR_INVALID_ARGUMENTS,
|
||||
"Unsupported argument '%s'", args_name));
|
||||
return;
|
||||
}
|
||||
|
||||
settings_add_connection_helper (self, invocation, TRUE, settings, flags);
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
|
|
@ -2941,6 +3044,7 @@ device_realized (NMDevice *device, GParamSpec *pspec, NMSettings *self)
|
|||
nm_settings_add_connection (self,
|
||||
connection,
|
||||
NM_SETTINGS_CONNECTION_PERSIST_MODE_IN_MEMORY_ONLY,
|
||||
NM_SETTINGS_CONNECTION_ADD_REASON_NONE,
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_NM_GENERATED,
|
||||
&added,
|
||||
&error);
|
||||
|
|
@ -3438,6 +3542,21 @@ static const NMDBusInterfaceInfoExtended interface_info_settings = {
|
|||
),
|
||||
.handle = impl_settings_add_connection_unsaved,
|
||||
),
|
||||
NM_DEFINE_DBUS_METHOD_INFO_EXTENDED (
|
||||
NM_DEFINE_GDBUS_METHOD_INFO_INIT (
|
||||
"AddConnection2",
|
||||
.in_args = NM_DEFINE_GDBUS_ARG_INFOS (
|
||||
NM_DEFINE_GDBUS_ARG_INFO ("settings", "a{sa{sv}}"),
|
||||
NM_DEFINE_GDBUS_ARG_INFO ("flags", "u"),
|
||||
NM_DEFINE_GDBUS_ARG_INFO ("args", "a{sv}"),
|
||||
),
|
||||
.out_args = NM_DEFINE_GDBUS_ARG_INFOS (
|
||||
NM_DEFINE_GDBUS_ARG_INFO ("path", "o"),
|
||||
NM_DEFINE_GDBUS_ARG_INFO ("result", "a{sv}"),
|
||||
),
|
||||
),
|
||||
.handle = impl_settings_add_connection2,
|
||||
),
|
||||
NM_DEFINE_DBUS_METHOD_INFO_EXTENDED (
|
||||
NM_DEFINE_GDBUS_METHOD_INFO_INIT (
|
||||
"LoadConnections",
|
||||
|
|
|
|||
|
|
@ -82,6 +82,7 @@ typedef void (*NMSettingsAddCallback) (NMSettings *settings,
|
|||
void nm_settings_add_connection_dbus (NMSettings *self,
|
||||
NMConnection *connection,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
NMSettingsConnectionAddReason add_reason,
|
||||
NMSettingsConnectionIntFlags sett_flags,
|
||||
NMAuthSubject *subject,
|
||||
GDBusMethodInvocation *context,
|
||||
|
|
@ -100,6 +101,7 @@ NMSettingsConnection **nm_settings_get_connections_clone (NMSettings *self,
|
|||
gboolean nm_settings_add_connection (NMSettings *settings,
|
||||
NMConnection *connection,
|
||||
NMSettingsConnectionPersistMode persist_mode,
|
||||
NMSettingsConnectionAddReason add_reason,
|
||||
NMSettingsConnectionIntFlags sett_flags,
|
||||
NMSettingsConnection **out_sett_conn,
|
||||
GError **error);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue