mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-07-21 02:04:17 +00:00
cli: add "connection migrate" subcommand
This is used to move a connection to a different settings plugin.
This commit is contained in:
parent
c7ab380a5c
commit
1aa9c80b9b
|
@ -659,6 +659,7 @@
|
|||
<arg choice='plain'><command>load</command></arg>
|
||||
<arg choice='plain'><command>import</command></arg>
|
||||
<arg choice='plain'><command>export</command></arg>
|
||||
<arg choice='plain'><command>migrate</command></arg>
|
||||
</group>
|
||||
<arg rep='repeat'><replaceable>ARGUMENTS</replaceable></arg>
|
||||
</cmdsynopsis>
|
||||
|
@ -1312,6 +1313,40 @@
|
|||
data will be printed to standard output.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term>
|
||||
<command>migrate</command>
|
||||
<arg>
|
||||
<option>--plugin</option>
|
||||
<arg choice='plain' rep='repeat'><replaceable>plugin</replaceable></arg>
|
||||
</arg>
|
||||
<group>
|
||||
<arg choice='plain'><option>id</option></arg>
|
||||
<arg choice='plain'><option>uuid</option></arg>
|
||||
<arg choice='plain'><option>path</option></arg>
|
||||
</group>
|
||||
<arg rep='repeat'><replaceable>ID</replaceable></arg>
|
||||
</term>
|
||||
<listitem>
|
||||
<para>Migrate connection profiles to a different settings plugin, such
|
||||
as <literal>keyfile</literal> (default) or <literal>ifcfg-rh</literal>.</para>
|
||||
|
||||
<para>The connection to be migrated is identified by its name, UUID or D-Bus path.
|
||||
If <replaceable>ID</replaceable> is ambiguous, a keyword <option>id</option>,
|
||||
<option>uuid</option> or <option>path</option> can be used. See <command>connection
|
||||
show</command> above for the description of the
|
||||
<replaceable>ID</replaceable>-specifying keywords.</para>
|
||||
|
||||
<para>If no connections are specified, the command acts on all available
|
||||
connections. Therefore, with no arguments, the command migrates all connection
|
||||
profiles to the <literal>keyfile</literal> plugin.</para>
|
||||
|
||||
<para>If <option>--wait</option> option is not specified, the default timeout will be 10
|
||||
seconds.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
|
|
@ -1294,6 +1294,17 @@ usage_connection_export(void)
|
|||
"The data are directed to standard output or to a file if a name is given.\n\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
usage_connection_migrate(void)
|
||||
{
|
||||
g_printerr(_("Usage: nmcli connection migrate { ARGUMENTS | help }\n"
|
||||
"\n"
|
||||
"ARGUMENTS := [--plugin <plugin>] [id | uuid | path] <ID>, ...\n"
|
||||
"\n"
|
||||
"Migrate connection profiles to a different settings plugin,\n"
|
||||
"such as \"keyfile\" (default) or \"ifcfg-rh\".\n\n"));
|
||||
}
|
||||
|
||||
static void
|
||||
quit(void)
|
||||
{
|
||||
|
@ -9641,6 +9652,154 @@ finish:
|
|||
unlink(path);
|
||||
}
|
||||
|
||||
static void
|
||||
migrate_cb(GObject *obj, GAsyncResult *result, gpointer user_data)
|
||||
{
|
||||
ConnectionCbInfo *info = (ConnectionCbInfo *) user_data;
|
||||
NMConnection *connection = NM_CONNECTION(obj);
|
||||
gs_unref_variant GVariant *res = NULL;
|
||||
GError *error = NULL;
|
||||
|
||||
res = nm_remote_connection_update2_finish(NM_REMOTE_CONNECTION(obj), result, &error);
|
||||
if (!res) {
|
||||
g_string_printf(info->nmc->return_text, _("Error: not all connections migrated."));
|
||||
g_printerr(_("Error: Connection migration failed: %s\n"), error->message);
|
||||
g_error_free(error);
|
||||
info->nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
||||
} else {
|
||||
g_print(_("Connection '%s' (%s) successfully migrated.\n"),
|
||||
nm_connection_get_id(connection),
|
||||
nm_connection_get_uuid(connection));
|
||||
}
|
||||
connection_cb_info_finish(info, obj);
|
||||
}
|
||||
|
||||
static void
|
||||
do_connection_migrate(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv)
|
||||
{
|
||||
NMConnection *connection;
|
||||
ConnectionCbInfo *info = NULL;
|
||||
gs_strfreev char **arg_arr = NULL;
|
||||
const char *const *arg_ptr;
|
||||
guint i;
|
||||
int arg_num;
|
||||
nm_auto_free_gstring GString *invalid_cons = NULL;
|
||||
gs_unref_ptrarray GPtrArray *found_cons = NULL;
|
||||
GError *error = NULL;
|
||||
const char *plugin = "keyfile";
|
||||
const GPtrArray *connections = NULL;
|
||||
int option;
|
||||
|
||||
if (nmc->timeout == -1)
|
||||
nmc->timeout = 10;
|
||||
|
||||
while ((option = next_arg(nmc, &argc, &argv, "--plugin", NULL)) > 0) {
|
||||
switch (option) {
|
||||
case 1: /* --plugin */
|
||||
argc--;
|
||||
argv++;
|
||||
if (!argc) {
|
||||
g_set_error_literal(&error, NMCLI_ERROR, 0, _("'--plugin' argument is missing"));
|
||||
goto finish;
|
||||
}
|
||||
plugin = *argv;
|
||||
break;
|
||||
default:
|
||||
g_return_if_reached();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
arg_ptr = argv;
|
||||
arg_num = argc;
|
||||
if (argc == 0) {
|
||||
if (nmc->ask) {
|
||||
gs_free char *line = NULL;
|
||||
|
||||
/* nmc_do_cmd() should not call this with argc=0. */
|
||||
g_assert(!nmc->complete);
|
||||
|
||||
line = nmc_readline(&nmc->nmc_config, PROMPT_CONNECTIONS);
|
||||
nmc_string_to_arg_array(line, NULL, TRUE, &arg_arr, &arg_num);
|
||||
arg_ptr = (const char *const *) arg_arr;
|
||||
}
|
||||
}
|
||||
|
||||
while (arg_num > 0) {
|
||||
const char *cur_selector, *cur_value;
|
||||
|
||||
connection =
|
||||
get_connection(nmc, &arg_num, &arg_ptr, &cur_selector, &cur_value, &found_cons, &error);
|
||||
if (!connection) {
|
||||
if (!nmc->complete)
|
||||
g_printerr(_("Error: %s.\n"), error->message);
|
||||
g_string_printf(nmc->return_text, _("Error: not all connections found."));
|
||||
nmc->return_value = error->code;
|
||||
g_clear_error(&error);
|
||||
|
||||
if (nmc->return_value != NMC_RESULT_ERROR_NOT_FOUND) {
|
||||
g_string_free(invalid_cons, TRUE);
|
||||
invalid_cons = NULL;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!invalid_cons)
|
||||
invalid_cons = g_string_new(NULL);
|
||||
if (cur_selector)
|
||||
g_string_append_printf(invalid_cons, "%s '%s', ", cur_selector, cur_value);
|
||||
else
|
||||
g_string_append_printf(invalid_cons, "'%s', ", cur_value);
|
||||
}
|
||||
}
|
||||
|
||||
if (nmc->complete)
|
||||
goto finish;
|
||||
|
||||
if (invalid_cons)
|
||||
goto finish;
|
||||
|
||||
if (!found_cons) {
|
||||
/* No connections specified explicitly? Fine, add all. */
|
||||
found_cons = g_ptr_array_new();
|
||||
connections = nm_client_get_connections(nmc->client);
|
||||
for (i = 0; i < connections->len; i++) {
|
||||
connection = connections->pdata[i];
|
||||
g_ptr_array_add(found_cons, connection);
|
||||
}
|
||||
}
|
||||
|
||||
info = g_slice_new0(ConnectionCbInfo);
|
||||
info->nmc = nmc;
|
||||
info->obj_list = g_ptr_array_sized_new(found_cons->len);
|
||||
for (i = 0; i < found_cons->len; i++) {
|
||||
connection = found_cons->pdata[i];
|
||||
g_ptr_array_add(info->obj_list, g_object_ref(connection));
|
||||
}
|
||||
info->timeout_id = g_timeout_add_seconds(nmc->timeout, connection_op_timeout_cb, info);
|
||||
info->cancellable = g_cancellable_new();
|
||||
|
||||
nmc->nowait_flag = (nmc->timeout == 0);
|
||||
nmc->should_wait++;
|
||||
|
||||
for (i = 0; i < found_cons->len; i++) {
|
||||
nm_remote_connection_update2(NM_REMOTE_CONNECTION(found_cons->pdata[i]),
|
||||
NULL,
|
||||
0,
|
||||
g_variant_new_parsed("{'plugin': <%s>}", plugin),
|
||||
info->cancellable,
|
||||
migrate_cb,
|
||||
info);
|
||||
}
|
||||
|
||||
finish:
|
||||
if (invalid_cons) {
|
||||
g_string_truncate(invalid_cons, invalid_cons->len - 2); /* truncate trailing ", " */
|
||||
g_string_printf(nmc->return_text,
|
||||
_("Error: cannot migrate unknown connection(s): %s."),
|
||||
invalid_cons->str);
|
||||
}
|
||||
}
|
||||
|
||||
static char *
|
||||
gen_func_connection_names(const char *text, int state)
|
||||
{
|
||||
|
@ -9748,6 +9907,7 @@ nmc_command_func_connection(const NMCCommand *cmd, NmCli *nmc, int argc, const c
|
|||
{"clone", do_connection_clone, usage_connection_clone, TRUE, TRUE},
|
||||
{"import", do_connection_import, usage_connection_import, TRUE, TRUE},
|
||||
{"export", do_connection_export, usage_connection_export, TRUE, TRUE},
|
||||
{"migrate", do_connection_migrate, usage_connection_migrate, TRUE, TRUE},
|
||||
{"monitor", do_connection_monitor, usage_connection_monitor, TRUE, TRUE},
|
||||
{NULL, do_connections_show, usage, TRUE, TRUE},
|
||||
};
|
||||
|
|
Loading…
Reference in a new issue