mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-05-09 07:08:02 +02:00
merge: branch 'lr/nmcli-offline'
https://bugzilla.redhat.com/show_bug.cgi?id=1361145 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1183
This commit is contained in:
commit
e95482dfd0
10 changed files with 724 additions and 116 deletions
|
|
@ -5318,6 +5318,7 @@ EXTRA_DIST += \
|
||||||
src/tests/client/test-client.check-on-disk/test_002.expected \
|
src/tests/client/test-client.check-on-disk/test_002.expected \
|
||||||
src/tests/client/test-client.check-on-disk/test_003.expected \
|
src/tests/client/test-client.check-on-disk/test_003.expected \
|
||||||
src/tests/client/test-client.check-on-disk/test_004.expected \
|
src/tests/client/test-client.check-on-disk/test_004.expected \
|
||||||
|
src/tests/client/test-client.check-on-disk/test_offline.expected \
|
||||||
\
|
\
|
||||||
src/tests/client/meson.build \
|
src/tests/client/meson.build \
|
||||||
$(NULL)
|
$(NULL)
|
||||||
|
|
|
||||||
3
NEWS
3
NEWS
|
|
@ -10,6 +10,9 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE!
|
||||||
|
|
||||||
* Drop unused, internal systemd DHCPv4 client. This is long
|
* Drop unused, internal systemd DHCPv4 client. This is long
|
||||||
replaced by nettools' n-dhcp4 implementation.
|
replaced by nettools' n-dhcp4 implementation.
|
||||||
|
* The nmcli command now supports --offline argument with "add" and
|
||||||
|
"modify" commands, allowing operation on keyfile-formatted connection
|
||||||
|
profiles without the service running (e.g. during system provisioning).
|
||||||
|
|
||||||
=============================================
|
=============================================
|
||||||
NetworkManager-1.38
|
NetworkManager-1.38
|
||||||
|
|
|
||||||
|
|
@ -614,6 +614,32 @@ Connection 'ethernet-4' (de89cdeb-a3e1-4d53-8fa0-c22546c775f4) successfully
|
||||||
<screen><prompt>$ </prompt><userinput>nmcli connection add type bluetooth con-name "My Bluetooth Hotspot" autoconnect no ifname btnap0 bluetooth.type nap ipv4.method shared ipv6.method shared</userinput></screen>
|
<screen><prompt>$ </prompt><userinput>nmcli connection add type bluetooth con-name "My Bluetooth Hotspot" autoconnect no ifname btnap0 bluetooth.type nap ipv4.method shared ipv6.method shared</userinput></screen>
|
||||||
</example>
|
</example>
|
||||||
|
|
||||||
|
<example><title>Offline use</title>
|
||||||
|
<screen><prompt>$ </prompt><userinput>nmcli --offline con add type ethernet '
|
||||||
|
conn.id eth0 \
|
||||||
|
conn.interface-name eth0 \
|
||||||
|
>/sysroot/etc/NetworkManager/system-connections/eth0.nmconnection</userinput></screen>
|
||||||
|
<para>
|
||||||
|
Creates a connection file in keyfile format without using the NetworkManager service.
|
||||||
|
This allows for use of familiar <command>nmcli</command> syntax in situations
|
||||||
|
where the service is not running, such as during system installation of image
|
||||||
|
provisioning and ensures the resulting file is correctly formatted.
|
||||||
|
</para>
|
||||||
|
<screen><prompt>$ </prompt><userinput>nmcli --offline con modify type ethernet '
|
||||||
|
conn.id eth0-ipv6 \
|
||||||
|
ipv4.method disabled \
|
||||||
|
</sysroot/etc/NetworkManager/system-connections/eth0.nmconnection \
|
||||||
|
>/sysroot/etc/NetworkManager/system-connections/eth0-ipv6.nmconnection</userinput></screen>
|
||||||
|
<para>
|
||||||
|
Read and write a connection file without using the NetworkManager service, modifying
|
||||||
|
some properties along the way.
|
||||||
|
</para>
|
||||||
|
<para>
|
||||||
|
This allows templating of the connection profiles using familiar
|
||||||
|
<command>nmcli</command> syntax in situations where the service is not running.
|
||||||
|
</para>
|
||||||
|
</example>
|
||||||
|
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
<refsect1>
|
<refsect1>
|
||||||
|
|
|
||||||
|
|
@ -314,6 +314,23 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
<varlistentry>
|
||||||
|
<term><group choice='plain'>
|
||||||
|
<arg choice='plain'><option>--offline</option></arg>
|
||||||
|
</group></term>
|
||||||
|
|
||||||
|
<listitem>
|
||||||
|
<para>Work without a daemon. Makes <command>connection add</command> and
|
||||||
|
<command>connection modify</command> commands accept and produce connection
|
||||||
|
data via standard input/output. Ordinarily, nmcli would communicate with
|
||||||
|
the NetworkManager service.</para>
|
||||||
|
|
||||||
|
<para>The connection data format (keyfile) is described in
|
||||||
|
<citerefentry><refentrytitle>nm-settings-keyfile</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||||
|
manual.</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><group choice='plain'>
|
<term><group choice='plain'>
|
||||||
<arg choice='plain'><option>-v</option></arg>
|
<arg choice='plain'><option>-v</option></arg>
|
||||||
|
|
@ -928,7 +945,7 @@
|
||||||
<arg choice='plain'><option>uuid</option></arg>
|
<arg choice='plain'><option>uuid</option></arg>
|
||||||
<arg choice='plain'><option>path</option></arg>
|
<arg choice='plain'><option>path</option></arg>
|
||||||
</group>
|
</group>
|
||||||
<arg choice='plain'><replaceable>ID</replaceable></arg>
|
<arg><replaceable>ID</replaceable></arg>
|
||||||
<arg rep='repeat' choice='plain'>
|
<arg rep='repeat' choice='plain'>
|
||||||
<group choice='req'>
|
<group choice='req'>
|
||||||
<arg choice='plain'><replaceable>option</replaceable> <replaceable>value</replaceable></arg>
|
<arg choice='plain'><replaceable>option</replaceable> <replaceable>value</replaceable></arg>
|
||||||
|
|
@ -962,7 +979,14 @@
|
||||||
|
|
||||||
<para>The connection is identified by its name, UUID or D-Bus path. If
|
<para>The connection is identified by its name, UUID or D-Bus path. If
|
||||||
<replaceable>ID</replaceable> is ambiguous, a keyword <option>id</option>,
|
<replaceable>ID</replaceable> is ambiguous, a keyword <option>id</option>,
|
||||||
<option>uuid</option> or <option>path</option> can be used.</para>
|
<option>uuid</option> or <option>path</option> can be used.
|
||||||
|
The <replaceable>ID</replaceable> is not used with the global
|
||||||
|
<option>--offline</option> option.</para>
|
||||||
|
|
||||||
|
<para>When the global <option>--offline</option> is used, the
|
||||||
|
command reads the connection from the standard input and prints the
|
||||||
|
modified connection to standard output instead of making the
|
||||||
|
the NetworkManager daemon act upon specified connection.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
@ -1096,6 +1120,10 @@
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
|
||||||
|
<para>When the global <option>--offline</option> is used, the
|
||||||
|
command prints the resulting connection to standard output instead of
|
||||||
|
actually adding the connection via the NetworkManager daemon.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -16,6 +16,8 @@
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#include <readline/readline.h>
|
#include <readline/readline.h>
|
||||||
#endif
|
#endif
|
||||||
|
#include <gio/gunixinputstream.h>
|
||||||
|
|
||||||
#include "libnm-client-aux-extern/nm-libnm-aux.h"
|
#include "libnm-client-aux-extern/nm-libnm-aux.h"
|
||||||
|
|
||||||
#include "libnmc-base/nm-vpn-helpers.h"
|
#include "libnmc-base/nm-vpn-helpers.h"
|
||||||
|
|
@ -469,7 +471,8 @@ nmc_find_connection(const GPtrArray *connections,
|
||||||
goto found;
|
goto found;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (NM_IN_STRSET(filter_type, NULL, "filename")) {
|
if (NM_IS_REMOTE_CONNECTION(connections->pdata[i])
|
||||||
|
&& NM_IN_STRSET(filter_type, NULL, "filename")) {
|
||||||
v = nm_remote_connection_get_filename(NM_REMOTE_CONNECTION(connections->pdata[i]));
|
v = nm_remote_connection_get_filename(NM_REMOTE_CONNECTION(connections->pdata[i]));
|
||||||
if (complete && (filter_type || *filter_val))
|
if (complete && (filter_type || *filter_val))
|
||||||
nmc_complete_strings(filter_val, v);
|
nmc_complete_strings(filter_val, v);
|
||||||
|
|
@ -1273,12 +1276,157 @@ got_client(GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||||
nm_g_slice_free(call);
|
nm_g_slice_free(call);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
GString *str;
|
||||||
|
char buf[512];
|
||||||
|
CmdCall *call;
|
||||||
|
} CmdStdinData;
|
||||||
|
|
||||||
|
static void read_offline_connection_next(GInputStream *stream, CmdStdinData *data);
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_offline_connection_chunk(GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||||
|
{
|
||||||
|
GInputStream *stream = G_INPUT_STREAM(source_object);
|
||||||
|
CmdStdinData *data = user_data;
|
||||||
|
CmdCall *call = data->call;
|
||||||
|
gs_unref_object GTask *task = NULL;
|
||||||
|
nm_auto_unref_keyfile GKeyFile *keyfile = NULL;
|
||||||
|
gs_free char *base_dir = NULL;
|
||||||
|
GError *error = NULL;
|
||||||
|
gssize bytes_read;
|
||||||
|
NMConnection *connection;
|
||||||
|
NmCli *nmc;
|
||||||
|
|
||||||
|
bytes_read = g_input_stream_read_finish(stream, res, &error);
|
||||||
|
if (bytes_read > 0) {
|
||||||
|
/* We need to read more. */
|
||||||
|
g_string_append_len(data->str, data->buf, bytes_read);
|
||||||
|
read_offline_connection_next(stream, data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* End reached. */
|
||||||
|
|
||||||
|
task = g_steal_pointer(&call->task);
|
||||||
|
nmc = g_task_get_task_data(task);
|
||||||
|
nmc->should_wait--;
|
||||||
|
|
||||||
|
if (bytes_read == -1) {
|
||||||
|
g_task_return_error(task, error);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
keyfile = g_key_file_new();
|
||||||
|
if (!g_key_file_load_from_data(keyfile,
|
||||||
|
data->str->str,
|
||||||
|
data->str->len,
|
||||||
|
G_KEY_FILE_NONE,
|
||||||
|
&error)) {
|
||||||
|
g_task_return_error(task, error);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
base_dir = g_get_current_dir();
|
||||||
|
connection =
|
||||||
|
nm_keyfile_read(keyfile, base_dir, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error);
|
||||||
|
if (!connection) {
|
||||||
|
g_task_return_error(task, error);
|
||||||
|
goto finish;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_add(nmc->offline_connections, connection);
|
||||||
|
call->cmd->func(call->cmd, nmc, call->argc, (const char *const *) call->argv);
|
||||||
|
g_task_return_boolean(task, TRUE);
|
||||||
|
|
||||||
|
finish:
|
||||||
|
g_strfreev(call->argv);
|
||||||
|
nm_g_slice_free(call);
|
||||||
|
g_string_free(data->str, TRUE);
|
||||||
|
nm_g_slice_free(data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_offline_connection_next(GInputStream *stream, CmdStdinData *data)
|
||||||
|
{
|
||||||
|
g_input_stream_read_async(stream,
|
||||||
|
data->buf,
|
||||||
|
sizeof(data->buf),
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
NULL,
|
||||||
|
read_offline_connection_chunk,
|
||||||
|
data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
read_offline_connection(CmdCall *call)
|
||||||
|
{
|
||||||
|
gs_unref_object GInputStream *stream = NULL;
|
||||||
|
CmdStdinData *data;
|
||||||
|
|
||||||
|
stream = g_unix_input_stream_new(STDIN_FILENO, TRUE);
|
||||||
|
data = g_slice_new(CmdStdinData);
|
||||||
|
data->call = call;
|
||||||
|
data->str = g_string_new_len(NULL, sizeof(data->buf));
|
||||||
|
|
||||||
|
read_offline_connection_next(stream, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static NMConnection *
|
||||||
|
dummy_offline_connection(void)
|
||||||
|
{
|
||||||
|
NMConnection *connection;
|
||||||
|
|
||||||
|
connection = nm_simple_connection_new();
|
||||||
|
nm_connection_add_setting(connection, nm_setting_connection_new());
|
||||||
|
return connection;
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
call_cmd(NmCli *nmc, GTask *task, const NMCCommand *cmd, int argc, const char *const *argv)
|
call_cmd(NmCli *nmc, GTask *task, const NMCCommand *cmd, int argc, const char *const *argv)
|
||||||
{
|
{
|
||||||
CmdCall *call;
|
CmdCall *call;
|
||||||
|
|
||||||
if (nmc->client || !cmd->needs_client) {
|
if (nmc->offline) {
|
||||||
|
if (!cmd->supports_offline) {
|
||||||
|
g_task_return_new_error(task,
|
||||||
|
NMCLI_ERROR,
|
||||||
|
NMC_RESULT_ERROR_USER_INPUT,
|
||||||
|
_("Error: command doesn't support --offline mode."));
|
||||||
|
g_object_unref(task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!nmc->offline_connections)
|
||||||
|
nmc->offline_connections = g_ptr_array_new_full(1, g_object_unref);
|
||||||
|
|
||||||
|
if (cmd->needs_offline_conn) {
|
||||||
|
g_return_if_fail(nmc->offline_connections->len == 0);
|
||||||
|
|
||||||
|
if (nmc->complete) {
|
||||||
|
g_ptr_array_add(nmc->offline_connections, dummy_offline_connection());
|
||||||
|
cmd->func(cmd, nmc, argc, argv);
|
||||||
|
g_task_return_boolean(task, TRUE);
|
||||||
|
g_object_unref(task);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
nmc->should_wait++;
|
||||||
|
call = g_slice_new(CmdCall);
|
||||||
|
*call = (CmdCall){
|
||||||
|
.cmd = cmd,
|
||||||
|
.argc = argc,
|
||||||
|
.argv = nm_strv_dup(argv, argc, TRUE),
|
||||||
|
.task = task,
|
||||||
|
};
|
||||||
|
read_offline_connection(call);
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
cmd->func(cmd, nmc, argc, argv);
|
||||||
|
g_task_return_boolean(task, TRUE);
|
||||||
|
g_object_unref(task);
|
||||||
|
}
|
||||||
|
} else if (nmc->client || !cmd->needs_client) {
|
||||||
/* Check whether NetworkManager is running */
|
/* Check whether NetworkManager is running */
|
||||||
if (cmd->needs_nm_running && !nm_client_get_nm_running(nmc->client)) {
|
if (cmd->needs_nm_running && !nm_client_get_nm_running(nmc->client)) {
|
||||||
g_task_return_new_error(task,
|
g_task_return_new_error(task,
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 - 2018 Red Hat, Inc.
|
* Copyright (C) 2010 - 2022 Red Hat, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "libnm-client-aux-extern/nm-default-client.h"
|
#include "libnm-client-aux-extern/nm-default-client.h"
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include <readline/history.h>
|
#include <readline/history.h>
|
||||||
#endif
|
#endif
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
|
#include <gio/gunixoutputstream.h>
|
||||||
|
|
||||||
#include "libnm-glib-aux/nm-dbus-aux.h"
|
#include "libnm-glib-aux/nm-dbus-aux.h"
|
||||||
#include "libnmc-base/nm-client-utils.h"
|
#include "libnmc-base/nm-client-utils.h"
|
||||||
|
|
@ -137,6 +138,131 @@ NM_AUTO_DEFINE_FCN(AddConnectionInfo *,
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
static guint progress_id = 0; /* ID of event source for displaying progress */
|
||||||
|
|
||||||
|
static void
|
||||||
|
quit(void)
|
||||||
|
{
|
||||||
|
if (nm_clear_g_source(&progress_id))
|
||||||
|
nmc_terminal_erase_line();
|
||||||
|
g_main_loop_quit(loop);
|
||||||
|
}
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *data;
|
||||||
|
gsize written;
|
||||||
|
gsize length;
|
||||||
|
NmCli *nmc;
|
||||||
|
} PrintConnData;
|
||||||
|
|
||||||
|
static void print_connection_chunk(GOutputStream *stream, PrintConnData *print_conn_data);
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_connection_done(GObject *source_object, GAsyncResult *res, gpointer user_data)
|
||||||
|
{
|
||||||
|
GOutputStream *stream = G_OUTPUT_STREAM(source_object);
|
||||||
|
PrintConnData *print_conn_data = user_data;
|
||||||
|
NmCli *nmc = print_conn_data->nmc;
|
||||||
|
GError *error = NULL;
|
||||||
|
gssize written;
|
||||||
|
|
||||||
|
written = g_output_stream_write_finish(stream, res, &error);
|
||||||
|
if (written == -1) {
|
||||||
|
g_string_printf(nmc->return_text,
|
||||||
|
_("Error: Error writting connection: %s"),
|
||||||
|
error->message);
|
||||||
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
||||||
|
nmc->should_wait--;
|
||||||
|
quit();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_conn_data->written += written;
|
||||||
|
if (print_conn_data->written != print_conn_data->length) {
|
||||||
|
g_return_if_fail(written);
|
||||||
|
g_return_if_fail(print_conn_data->written < print_conn_data->length);
|
||||||
|
|
||||||
|
print_connection_chunk(stream, print_conn_data);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_free(print_conn_data->data);
|
||||||
|
g_slice_free(PrintConnData, print_conn_data);
|
||||||
|
|
||||||
|
nmc->should_wait--;
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
print_connection_chunk(GOutputStream *stream, PrintConnData *print_conn_data)
|
||||||
|
{
|
||||||
|
g_output_stream_write_async(stream,
|
||||||
|
print_conn_data->data + print_conn_data->written,
|
||||||
|
print_conn_data->length - print_conn_data->written,
|
||||||
|
G_PRIORITY_DEFAULT,
|
||||||
|
NULL,
|
||||||
|
print_connection_done,
|
||||||
|
print_conn_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nmc_print_connection_and_quit(NmCli *nmc, NMConnection *connection)
|
||||||
|
{
|
||||||
|
gs_free_error GError *error = NULL;
|
||||||
|
nm_auto_unref_keyfile GKeyFile *keyfile = NULL;
|
||||||
|
gs_unref_object GOutputStream *stream = NULL;
|
||||||
|
PrintConnData *print_conn_data;
|
||||||
|
|
||||||
|
if (!nm_connection_normalize(connection, NULL, NULL, &error))
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
keyfile = nm_keyfile_write(connection, NM_KEYFILE_HANDLER_FLAGS_NONE, NULL, NULL, &error);
|
||||||
|
if (!keyfile)
|
||||||
|
goto error;
|
||||||
|
|
||||||
|
stream = g_unix_output_stream_new(STDOUT_FILENO, FALSE);
|
||||||
|
print_conn_data = g_slice_new(PrintConnData);
|
||||||
|
print_conn_data->data = g_key_file_to_data(keyfile, &print_conn_data->length, NULL);
|
||||||
|
print_conn_data->written = 0;
|
||||||
|
print_conn_data->nmc = nmc;
|
||||||
|
print_connection_chunk(stream, print_conn_data);
|
||||||
|
return;
|
||||||
|
|
||||||
|
error:
|
||||||
|
g_string_printf(nmc->return_text, _("Error: Error writting connection: %s"), error->message);
|
||||||
|
nmc->return_value = NMC_RESULT_ERROR_UNKNOWN;
|
||||||
|
nmc->should_wait--;
|
||||||
|
quit();
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GPtrArray *
|
||||||
|
nmc_get_connections(const NmCli *nmc)
|
||||||
|
{
|
||||||
|
if (nmc->offline) {
|
||||||
|
g_return_val_if_fail(!nmc->client, nmc->offline_connections);
|
||||||
|
return nmc->offline_connections;
|
||||||
|
} else {
|
||||||
|
g_return_val_if_fail(nmc->client, NULL);
|
||||||
|
return nm_client_get_connections(nmc->client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const GPtrArray *
|
||||||
|
nmc_get_active_connections(const NmCli *nmc)
|
||||||
|
{
|
||||||
|
static const GPtrArray offline_active_connections = {.len = 0};
|
||||||
|
|
||||||
|
if (nmc->offline) {
|
||||||
|
g_return_val_if_fail(!nmc->client, &offline_active_connections);
|
||||||
|
return &offline_active_connections;
|
||||||
|
} else {
|
||||||
|
g_return_val_if_fail(nmc->client, &offline_active_connections);
|
||||||
|
return nm_client_get_active_connections(nmc->client);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
/* Essentially a version of nm_setting_connection_get_connection_type() that
|
/* Essentially a version of nm_setting_connection_get_connection_type() that
|
||||||
* prefers an alias instead of the settings name when in pretty print mode.
|
* 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". */
|
* That is so that we print "wifi" instead of "802-11-wireless" in "nmcli c". */
|
||||||
|
|
@ -942,8 +1068,6 @@ const NmcMetaGenericInfo *const nmc_fields_con_active_details_groups[] = {
|
||||||
#define CON_SHOW_DETAIL_GROUP_PROFILE "profile"
|
#define CON_SHOW_DETAIL_GROUP_PROFILE "profile"
|
||||||
#define CON_SHOW_DETAIL_GROUP_ACTIVE "active"
|
#define CON_SHOW_DETAIL_GROUP_ACTIVE "active"
|
||||||
|
|
||||||
static guint progress_id = 0; /* ID of event source for displaying progress */
|
|
||||||
|
|
||||||
/* for readline TAB completion in editor */
|
/* for readline TAB completion in editor */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
NmCli *nmc;
|
NmCli *nmc;
|
||||||
|
|
@ -1305,14 +1429,6 @@ usage_connection_migrate(void)
|
||||||
"such as \"keyfile\" (default) or \"ifcfg-rh\".\n\n"));
|
"such as \"keyfile\" (default) or \"ifcfg-rh\".\n\n"));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
quit(void)
|
|
||||||
{
|
|
||||||
if (nm_clear_g_source(&progress_id))
|
|
||||||
nmc_terminal_erase_line();
|
|
||||||
g_main_loop_quit(loop);
|
|
||||||
}
|
|
||||||
|
|
||||||
static char *
|
static char *
|
||||||
construct_header_name(const char *base, const char *spec)
|
construct_header_name(const char *base, const char *spec)
|
||||||
{
|
{
|
||||||
|
|
@ -1951,7 +2067,7 @@ con_show_get_items(NmCli *nmc, gboolean active_only, gboolean show_active_fields
|
||||||
|
|
||||||
row_hash = g_hash_table_new(nm_direct_hash, NULL);
|
row_hash = g_hash_table_new(nm_direct_hash, NULL);
|
||||||
|
|
||||||
arr = nm_client_get_connections(nmc->client);
|
arr = nmc_get_connections(nmc);
|
||||||
for (i = 0; i < arr->len; i++) {
|
for (i = 0; i < arr->len; i++) {
|
||||||
/* Note: libnm will not expose connection that are invisible
|
/* Note: libnm will not expose connection that are invisible
|
||||||
* to the user but currently inactive.
|
* to the user but currently inactive.
|
||||||
|
|
@ -1970,7 +2086,7 @@ con_show_get_items(NmCli *nmc, gboolean active_only, gboolean show_active_fields
|
||||||
_metagen_con_show_row_data_new_for_connection(c, show_active_fields));
|
_metagen_con_show_row_data_new_for_connection(c, show_active_fields));
|
||||||
}
|
}
|
||||||
|
|
||||||
arr = nm_client_get_active_connections(nmc->client);
|
arr = nmc_get_active_connections(nmc);
|
||||||
for (i = 0; i < arr->len; i++) {
|
for (i = 0; i < arr->len; i++) {
|
||||||
NMActiveConnection *ac = arr->pdata[i];
|
NMActiveConnection *ac = arr->pdata[i];
|
||||||
|
|
||||||
|
|
@ -2118,6 +2234,11 @@ get_connection(NmCli *nmc,
|
||||||
NM_SET_OUT(out_selector, NULL);
|
NM_SET_OUT(out_selector, NULL);
|
||||||
NM_SET_OUT(out_value, NULL);
|
NM_SET_OUT(out_value, NULL);
|
||||||
|
|
||||||
|
if (nmc->offline_connections && nmc->offline_connections->len)
|
||||||
|
return nmc->offline_connections->pdata[0];
|
||||||
|
|
||||||
|
g_return_val_if_fail(!nmc->offline, NULL);
|
||||||
|
|
||||||
if (*argc == 0) {
|
if (*argc == 0) {
|
||||||
g_set_error_literal(error,
|
g_set_error_literal(error,
|
||||||
NMCLI_ERROR,
|
NMCLI_ERROR,
|
||||||
|
|
@ -2258,7 +2379,7 @@ do_connections_show(const NMCCommand *cmd, NmCli *nmc, int argc, const char *con
|
||||||
} else {
|
} else {
|
||||||
gboolean new_line = FALSE;
|
gboolean new_line = FALSE;
|
||||||
gboolean without_fields = (nmc->required_fields == NULL);
|
gboolean without_fields = (nmc->required_fields == NULL);
|
||||||
const GPtrArray *active_cons = nm_client_get_active_connections(nmc->client);
|
const GPtrArray *active_cons = nmc_get_active_connections(nmc);
|
||||||
|
|
||||||
/* multiline mode is default for 'connection show <ID>' */
|
/* multiline mode is default for 'connection show <ID>' */
|
||||||
if (!nmc->mode_specified)
|
if (!nmc->mode_specified)
|
||||||
|
|
@ -2314,7 +2435,7 @@ do_connections_show(const NMCCommand *cmd, NmCli *nmc, int argc, const char *con
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Try to find connection by id, uuid or path first */
|
/* Try to find connection by id, uuid or path first */
|
||||||
connections = nm_client_get_connections(nmc->client);
|
connections = nmc_get_connections(nmc);
|
||||||
con = nmc_find_connection(connections,
|
con = nmc_find_connection(connections,
|
||||||
selector,
|
selector,
|
||||||
*argv,
|
*argv,
|
||||||
|
|
@ -2451,7 +2572,7 @@ get_default_active_connection(NmCli *nmc, NMDevice **device)
|
||||||
g_return_val_if_fail(device, NULL);
|
g_return_val_if_fail(device, NULL);
|
||||||
g_return_val_if_fail(*device == NULL, NULL);
|
g_return_val_if_fail(*device == NULL, NULL);
|
||||||
|
|
||||||
connections = nm_client_get_active_connections(nmc->client);
|
connections = nmc_get_active_connections(nmc);
|
||||||
for (i = 0; i < connections->len; i++) {
|
for (i = 0; i < connections->len; i++) {
|
||||||
NMActiveConnection *candidate = g_ptr_array_index(connections, i);
|
NMActiveConnection *candidate = g_ptr_array_index(connections, i);
|
||||||
const GPtrArray *devices;
|
const GPtrArray *devices;
|
||||||
|
|
@ -3275,7 +3396,7 @@ do_connection_down(const NMCCommand *cmd, NmCli *nmc, int argc, const char *cons
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Get active connections */
|
/* Get active connections */
|
||||||
active_cons = nm_client_get_active_connections(nmc->client);
|
active_cons = nmc_get_active_connections(nmc);
|
||||||
while (arg_num > 0) {
|
while (arg_num > 0) {
|
||||||
const char *selector = NULL;
|
const char *selector = NULL;
|
||||||
|
|
||||||
|
|
@ -3925,7 +4046,7 @@ set_default_interface_name(NmCli *nmc, NMSettingConnection *s_con)
|
||||||
const GPtrArray *connections;
|
const GPtrArray *connections;
|
||||||
gs_free char *ifname = NULL;
|
gs_free char *ifname = NULL;
|
||||||
|
|
||||||
connections = nm_client_get_connections(nmc->client);
|
connections = nmc_get_connections(nmc);
|
||||||
ifname = unique_master_iface_ifname(connections, default_name);
|
ifname = unique_master_iface_ifname(connections, default_name);
|
||||||
g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, NULL);
|
g_object_set(s_con, NM_SETTING_CONNECTION_INTERFACE_NAME, ifname, NULL);
|
||||||
}
|
}
|
||||||
|
|
@ -4488,7 +4609,7 @@ set_connection_master(NmCli *nmc,
|
||||||
}
|
}
|
||||||
|
|
||||||
slave_type = nm_setting_connection_get_slave_type(s_con);
|
slave_type = nm_setting_connection_get_slave_type(s_con);
|
||||||
connections = nm_client_get_connections(nmc->client);
|
connections = nmc_get_connections(nmc);
|
||||||
value = normalized_master_for_slave(connections, value, slave_type, &slave_type);
|
value = normalized_master_for_slave(connections, value, slave_type, &slave_type);
|
||||||
|
|
||||||
if (!set_property(nmc->client,
|
if (!set_property(nmc->client,
|
||||||
|
|
@ -5264,12 +5385,9 @@ connection_warnings(NmCli *nmc, NMConnection *connection)
|
||||||
if (deprecated)
|
if (deprecated)
|
||||||
g_printerr(_("Warning: %s.\n"), deprecated);
|
g_printerr(_("Warning: %s.\n"), deprecated);
|
||||||
|
|
||||||
connections = nm_client_get_connections(nmc->client);
|
connections = nmc_get_connections(nmc);
|
||||||
if (!connections)
|
id = nm_connection_get_id(connection);
|
||||||
return;
|
found = 0;
|
||||||
|
|
||||||
id = nm_connection_get_id(connection);
|
|
||||||
found = 0;
|
|
||||||
for (i = 0; i < connections->len; i++) {
|
for (i = 0; i < connections->len; i++) {
|
||||||
NMConnection *candidate = NM_CONNECTION(connections->pdata[i]);
|
NMConnection *candidate = NM_CONNECTION(connections->pdata[i]);
|
||||||
|
|
||||||
|
|
@ -5347,15 +5465,6 @@ add_connection(NMClient *client,
|
||||||
user_data);
|
user_data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
|
||||||
update_connection(NMRemoteConnection *connection,
|
|
||||||
gboolean temporary,
|
|
||||||
GAsyncReadyCallback callback,
|
|
||||||
gpointer user_data)
|
|
||||||
{
|
|
||||||
nm_remote_connection_commit_changes_async(connection, !temporary, NULL, callback, user_data);
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
is_single_word(const char *line)
|
is_single_word(const char *line)
|
||||||
{
|
{
|
||||||
|
|
@ -5660,6 +5769,20 @@ again:
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nmc_add_connection(NmCli *nmc, NMConnection *connection, gboolean temporary)
|
||||||
|
{
|
||||||
|
if (nmc->offline) {
|
||||||
|
nmc_print_connection_and_quit(nmc, connection);
|
||||||
|
} else {
|
||||||
|
add_connection(nmc->client,
|
||||||
|
connection,
|
||||||
|
temporary,
|
||||||
|
add_connection_cb,
|
||||||
|
_add_connection_info_new(nmc, NULL, connection));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_connection_add(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv)
|
do_connection_add(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv)
|
||||||
{
|
{
|
||||||
|
|
@ -5747,7 +5870,7 @@ read_properties:
|
||||||
gs_free char *default_name = NULL;
|
gs_free char *default_name = NULL;
|
||||||
const GPtrArray *connections;
|
const GPtrArray *connections;
|
||||||
|
|
||||||
connections = nm_client_get_connections(nmc->client);
|
connections = nmc_get_connections(nmc);
|
||||||
try_name =
|
try_name =
|
||||||
ifname ? g_strdup_printf("%s-%s", get_name_alias_toplevel(type, slave_type), ifname)
|
ifname ? g_strdup_printf("%s-%s", get_name_alias_toplevel(type, slave_type), ifname)
|
||||||
: g_strdup(get_name_alias_toplevel(type, slave_type));
|
: g_strdup(get_name_alias_toplevel(type, slave_type));
|
||||||
|
|
@ -5812,11 +5935,7 @@ read_properties:
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
add_connection(nmc->client,
|
nmc_add_connection(nmc, connection, !save_bool);
|
||||||
connection,
|
|
||||||
!save_bool,
|
|
||||||
add_connection_cb,
|
|
||||||
_add_connection_info_new(nmc, NULL, connection));
|
|
||||||
nmc->should_wait++;
|
nmc->should_wait++;
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
|
|
@ -5838,7 +5957,7 @@ uuid_display_hook(char **array, int len, int max_len)
|
||||||
char *tmp;
|
char *tmp;
|
||||||
const char *id;
|
const char *id;
|
||||||
for (i = 1; i <= len; i++) {
|
for (i = 1; i <= len; i++) {
|
||||||
connections = nm_client_get_connections(nmc_tab_completion.nmc->client);
|
connections = nmc_get_connections(nmc_tab_completion.nmc);
|
||||||
con = nmc_find_connection(connections, "uuid", array[i], NULL, FALSE);
|
con = nmc_find_connection(connections, "uuid", array[i], NULL, FALSE);
|
||||||
id = con ? nm_connection_get_id(con) : NULL;
|
id = con ? nm_connection_get_id(con) : NULL;
|
||||||
if (id) {
|
if (id) {
|
||||||
|
|
@ -6172,7 +6291,7 @@ gen_vpn_uuids(const char *text, int state)
|
||||||
const char **uuids;
|
const char **uuids;
|
||||||
char *ret;
|
char *ret;
|
||||||
|
|
||||||
connections = nm_client_get_connections(nm_cli_global_readline->client);
|
connections = nmc_get_connections(nm_cli_global_readline);
|
||||||
if (connections->len < 1)
|
if (connections->len < 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
@ -6189,7 +6308,7 @@ gen_vpn_ids(const char *text, int state)
|
||||||
const char **ids;
|
const char **ids;
|
||||||
char *ret;
|
char *ret;
|
||||||
|
|
||||||
connections = nm_client_get_connections(nm_cli_global_readline->client);
|
connections = nmc_get_connections(nm_cli_global_readline);
|
||||||
if (connections->len < 1)
|
if (connections->len < 1)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
@ -8335,7 +8454,11 @@ editor_menu_main(NmCli *nmc, NMConnection *connection, const char *connection_ty
|
||||||
/* Save/update already saved (existing) connection */
|
/* Save/update already saved (existing) connection */
|
||||||
nm_connection_replace_settings_from_connection(NM_CONNECTION(rem_con),
|
nm_connection_replace_settings_from_connection(NM_CONNECTION(rem_con),
|
||||||
connection);
|
connection);
|
||||||
update_connection(rem_con, temporary, update_connection_editor_cb, NULL);
|
nm_remote_connection_commit_changes_async(rem_con,
|
||||||
|
!temporary,
|
||||||
|
NULL,
|
||||||
|
update_connection_editor_cb,
|
||||||
|
NULL);
|
||||||
|
|
||||||
handler_id = g_signal_connect(rem_con,
|
handler_id = g_signal_connect(rem_con,
|
||||||
NM_CONNECTION_CHANGED,
|
NM_CONNECTION_CHANGED,
|
||||||
|
|
@ -8749,7 +8872,7 @@ do_connection_edit(const NMCCommand *cmd, NmCli *nmc, int argc, const char *cons
|
||||||
/* Use ' ' and '.' as word break characters */
|
/* Use ' ' and '.' as word break characters */
|
||||||
rl_completer_word_break_characters = ". ";
|
rl_completer_word_break_characters = ". ";
|
||||||
|
|
||||||
connections = nm_client_get_connections(nmc->client);
|
connections = nmc_get_connections(nmc);
|
||||||
|
|
||||||
if (!con) {
|
if (!con) {
|
||||||
if (con_id && !con_uuid && !con_path && !con_filename) {
|
if (con_id && !con_uuid && !con_path && !con_filename) {
|
||||||
|
|
@ -8930,11 +9053,24 @@ modify_connection_cb(GObject *connection, GAsyncResult *result, gpointer user_da
|
||||||
quit();
|
quit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
nmc_update_connection(NmCli *nmc, NMConnection *connection, gboolean temporary)
|
||||||
|
{
|
||||||
|
if (nmc->offline) {
|
||||||
|
nmc_print_connection_and_quit(nmc, connection);
|
||||||
|
} else {
|
||||||
|
nm_remote_connection_commit_changes_async(NM_REMOTE_CONNECTION(connection),
|
||||||
|
!temporary,
|
||||||
|
NULL,
|
||||||
|
modify_connection_cb,
|
||||||
|
nmc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_connection_modify(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv)
|
do_connection_modify(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv)
|
||||||
{
|
{
|
||||||
NMConnection *connection = NULL;
|
NMConnection *connection = NULL;
|
||||||
NMRemoteConnection *rc = NULL;
|
|
||||||
gs_free_error GError *error = NULL;
|
gs_free_error GError *error = NULL;
|
||||||
gboolean temporary = FALSE;
|
gboolean temporary = FALSE;
|
||||||
|
|
||||||
|
|
@ -8950,25 +9086,19 @@ do_connection_modify(const NMCCommand *cmd, NmCli *nmc, int argc, const char *co
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rc = nm_client_get_connection_by_uuid(nmc->client, nm_connection_get_uuid(connection));
|
/* Don't insist on having argument if we're running in offline mode. */
|
||||||
if (!rc) {
|
if (!nmc->offline || argc > 0) {
|
||||||
g_string_printf(nmc->return_text,
|
if (!nmc_process_connection_properties(nmc, connection, &argc, &argv, TRUE, &error)) {
|
||||||
_("Error: Unknown connection '%s'."),
|
g_string_assign(nmc->return_text, error->message);
|
||||||
nm_connection_get_uuid(connection));
|
nmc->return_value = error->code;
|
||||||
nmc->return_value = NMC_RESULT_ERROR_NOT_FOUND;
|
return;
|
||||||
return;
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (!nmc_process_connection_properties(nmc, NM_CONNECTION(rc), &argc, &argv, TRUE, &error)) {
|
|
||||||
g_string_assign(nmc->return_text, error->message);
|
|
||||||
nmc->return_value = error->code;
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nmc->complete)
|
if (nmc->complete)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
update_connection(rc, temporary, modify_connection_cb, nmc);
|
nmc_update_connection(nmc, connection, temporary);
|
||||||
nmc->should_wait++;
|
nmc->should_wait++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -9266,7 +9396,7 @@ do_connection_monitor(const NMCCommand *cmd, NmCli *nmc, int argc, const char *c
|
||||||
/* nmc_do_cmd() should not call this with argc=0. */
|
/* nmc_do_cmd() should not call this with argc=0. */
|
||||||
g_return_if_fail(!nmc->complete);
|
g_return_if_fail(!nmc->complete);
|
||||||
|
|
||||||
connections = nm_client_get_connections(nmc->client);
|
connections = nmc_get_connections(nmc);
|
||||||
} else {
|
} else {
|
||||||
while (argc > 0) {
|
while (argc > 0) {
|
||||||
if (!get_connection(nmc, &argc, &argv, NULL, NULL, &found_cons, &error)) {
|
if (!get_connection(nmc, &argc, &argv, NULL, NULL, &found_cons, &error)) {
|
||||||
|
|
@ -9767,7 +9897,7 @@ do_connection_migrate(const NMCCommand *cmd, NmCli *nmc, int argc, const char *c
|
||||||
if (!found_cons) {
|
if (!found_cons) {
|
||||||
/* No connections specified explicitly? Fine, add all. */
|
/* No connections specified explicitly? Fine, add all. */
|
||||||
found_cons = g_ptr_array_new();
|
found_cons = g_ptr_array_new();
|
||||||
connections = nm_client_get_connections(nmc->client);
|
connections = nmc_get_connections(nmc);
|
||||||
for (i = 0; i < connections->len; i++) {
|
for (i = 0; i < connections->len; i++) {
|
||||||
connection = connections->pdata[i];
|
connection = connections->pdata[i];
|
||||||
g_ptr_array_add(found_cons, connection);
|
g_ptr_array_add(found_cons, connection);
|
||||||
|
|
@ -9814,7 +9944,7 @@ gen_func_connection_names(const char *text, int state)
|
||||||
const char **connection_names;
|
const char **connection_names;
|
||||||
char *ret;
|
char *ret;
|
||||||
|
|
||||||
connections = nm_client_get_connections(nm_cli_global_readline->client);
|
connections = nmc_get_connections(nm_cli_global_readline);
|
||||||
if (connections->len == 0)
|
if (connections->len == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
@ -9840,7 +9970,7 @@ gen_func_active_connection_names(const char *text, int state)
|
||||||
if (!nm_cli_global_readline->client)
|
if (!nm_cli_global_readline->client)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
acs = nm_client_get_active_connections(nm_cli_global_readline->client);
|
acs = nmc_get_active_connections(nm_cli_global_readline);
|
||||||
if (!acs || acs->len == 0)
|
if (!acs || acs->len == 0)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
@ -9904,12 +10034,12 @@ nmc_command_func_connection(const NMCCommand *cmd, NmCli *nmc, int argc, const c
|
||||||
{"show", do_connections_show, usage_connection_show, TRUE, TRUE},
|
{"show", do_connections_show, usage_connection_show, TRUE, TRUE},
|
||||||
{"up", do_connection_up, usage_connection_up, TRUE, TRUE},
|
{"up", do_connection_up, usage_connection_up, TRUE, TRUE},
|
||||||
{"down", do_connection_down, usage_connection_down, TRUE, TRUE},
|
{"down", do_connection_down, usage_connection_down, TRUE, TRUE},
|
||||||
{"add", do_connection_add, usage_connection_add, TRUE, TRUE},
|
{"add", do_connection_add, usage_connection_add, TRUE, TRUE, TRUE},
|
||||||
{"edit", do_connection_edit, usage_connection_edit, TRUE, TRUE},
|
{"edit", do_connection_edit, usage_connection_edit, TRUE, TRUE},
|
||||||
{"delete", do_connection_delete, usage_connection_delete, TRUE, TRUE},
|
{"delete", do_connection_delete, usage_connection_delete, TRUE, TRUE},
|
||||||
{"reload", do_connection_reload, usage_connection_reload, FALSE, FALSE},
|
{"reload", do_connection_reload, usage_connection_reload, FALSE, FALSE},
|
||||||
{"load", do_connection_load, usage_connection_load, TRUE, TRUE},
|
{"load", do_connection_load, usage_connection_load, TRUE, TRUE},
|
||||||
{"modify", do_connection_modify, usage_connection_modify, TRUE, TRUE},
|
{"modify", do_connection_modify, usage_connection_modify, TRUE, TRUE, TRUE, TRUE},
|
||||||
{"clone", do_connection_clone, usage_connection_clone, TRUE, TRUE},
|
{"clone", do_connection_clone, usage_connection_clone, TRUE, TRUE},
|
||||||
{"import", do_connection_import, usage_connection_import, TRUE, TRUE},
|
{"import", do_connection_import, usage_connection_import, TRUE, TRUE},
|
||||||
{"export", do_connection_export, usage_connection_export, TRUE, TRUE},
|
{"export", do_connection_export, usage_connection_export, TRUE, TRUE},
|
||||||
|
|
|
||||||
|
|
@ -726,7 +726,7 @@ process_command_line(NmCli *nmc, int argc, char **argv_orig)
|
||||||
{"monitor", nmc_command_func_monitor, NULL, TRUE, FALSE},
|
{"monitor", nmc_command_func_monitor, NULL, TRUE, FALSE},
|
||||||
{"networking", nmc_command_func_networking, NULL, FALSE, FALSE},
|
{"networking", nmc_command_func_networking, NULL, FALSE, FALSE},
|
||||||
{"radio", nmc_command_func_radio, NULL, FALSE, FALSE},
|
{"radio", nmc_command_func_radio, NULL, FALSE, FALSE},
|
||||||
{"connection", nmc_command_func_connection, NULL, FALSE, FALSE},
|
{"connection", nmc_command_func_connection, NULL, FALSE, FALSE, TRUE},
|
||||||
{"device", nmc_command_func_device, NULL, FALSE, FALSE},
|
{"device", nmc_command_func_device, NULL, FALSE, FALSE},
|
||||||
{"agent", nmc_command_func_agent, NULL, FALSE, FALSE},
|
{"agent", nmc_command_func_agent, NULL, FALSE, FALSE},
|
||||||
{NULL, nmc_command_func_overview, usage, TRUE, TRUE},
|
{NULL, nmc_command_func_overview, usage, TRUE, TRUE},
|
||||||
|
|
@ -761,15 +761,16 @@ process_command_line(NmCli *nmc, int argc, char **argv_orig)
|
||||||
|
|
||||||
if (argc == 1 && nmc->complete) {
|
if (argc == 1 && nmc->complete) {
|
||||||
nmc_complete_strings(argv[0],
|
nmc_complete_strings(argv[0],
|
||||||
|
"--overview",
|
||||||
|
"--offline",
|
||||||
"--terse",
|
"--terse",
|
||||||
"--pretty",
|
"--pretty",
|
||||||
"--mode",
|
"--mode",
|
||||||
"--overview",
|
|
||||||
"--colors",
|
"--colors",
|
||||||
"--escape",
|
"--escape",
|
||||||
"--fields",
|
"--fields",
|
||||||
"--nocheck",
|
|
||||||
"--get-values",
|
"--get-values",
|
||||||
|
"--nocheck",
|
||||||
"--wait",
|
"--wait",
|
||||||
"--version",
|
"--version",
|
||||||
"--help");
|
"--help");
|
||||||
|
|
@ -783,6 +784,8 @@ process_command_line(NmCli *nmc, int argc, char **argv_orig)
|
||||||
|
|
||||||
if (matches_arg(nmc, &argc, &argv, "-overview", NULL)) {
|
if (matches_arg(nmc, &argc, &argv, "-overview", NULL)) {
|
||||||
nmc->nmc_config_mutable.overview = TRUE;
|
nmc->nmc_config_mutable.overview = TRUE;
|
||||||
|
} else if (matches_arg(nmc, &argc, &argv, "-offline", NULL)) {
|
||||||
|
nmc->offline = TRUE;
|
||||||
} else if (matches_arg(nmc, &argc, &argv, "-terse", NULL)) {
|
} else if (matches_arg(nmc, &argc, &argv, "-terse", NULL)) {
|
||||||
if (nmc->nmc_config.print_output == NMC_PRINT_TERSE) {
|
if (nmc->nmc_config.print_output == NMC_PRINT_TERSE) {
|
||||||
g_string_printf(nmc->return_text,
|
g_string_printf(nmc->return_text,
|
||||||
|
|
@ -1011,6 +1014,8 @@ nmc_cleanup(NmCli *nmc)
|
||||||
|
|
||||||
nm_clear_g_free(&nmc->palette_buffer);
|
nm_clear_g_free(&nmc->palette_buffer);
|
||||||
|
|
||||||
|
nm_clear_pointer(&nmc->offline_connections, g_ptr_array_unref);
|
||||||
|
|
||||||
nmc_polkit_agent_fini(nmc);
|
nmc_polkit_agent_fini(nmc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
/*
|
/*
|
||||||
* Copyright (C) 2010 - 2018 Red Hat, Inc.
|
* Copyright (C) 2010 - 2022 Red Hat, Inc.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#ifndef NMC_NMCLI_H
|
#ifndef NMC_NMCLI_H
|
||||||
|
|
@ -84,23 +84,26 @@ typedef struct _NmcMetaGenericInfo NmcMetaGenericInfo;
|
||||||
|
|
||||||
struct _NmcOutputField {
|
struct _NmcOutputField {
|
||||||
const NMMetaAbstractInfo *info;
|
const NMMetaAbstractInfo *info;
|
||||||
int width; /* Width in screen columns */
|
|
||||||
void *value; /* Value of current field - char* or char** (NULL-terminated array) */
|
int width; /* Width in screen columns */
|
||||||
gboolean value_is_array; /* Whether value is char** instead of char* */
|
void *value; /* Value of current field - char* or
|
||||||
gboolean free_value; /* Whether to free the value */
|
* char** (NULL-terminated array) */
|
||||||
NmcOfFlags flags; /* Flags - whether and how to print values/field names/headers */
|
bool value_is_array : 1; /* Whether value is char** instead of char* */
|
||||||
NMMetaColor color; /* Use this color to print value */
|
bool free_value : 1; /* Whether to free the value */
|
||||||
|
|
||||||
|
NmcOfFlags flags; /* Flags - whether and how to print values/field names/headers */
|
||||||
|
NMMetaColor color; /* Use this color to print value */
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef struct _NmcConfig {
|
typedef struct _NmcConfig {
|
||||||
NMCPrintOutput print_output; /* Output mode */
|
NMCPrintOutput print_output; /* Output mode */
|
||||||
bool use_colors; /* Whether to use colors for output: option '--color' */
|
bool use_colors; /* Whether to use colors for output: option '--color' */
|
||||||
bool multiline_output; /* Multiline output instead of default tabular */
|
bool multiline_output : 1; /* Multiline output instead of default tabular */
|
||||||
bool escape_values; /* Whether to escape ':' and '\' in terse tabular mode */
|
bool escape_values : 1; /* Whether to escape ':' and '\' in terse tabular mode */
|
||||||
bool in_editor; /* Whether running the editor - nmcli con edit' */
|
bool in_editor : 1; /* Whether running the editor - nmcli con edit' */
|
||||||
bool
|
bool show_secrets : 1; /* Whether to display secrets (both input
|
||||||
show_secrets; /* Whether to display secrets (both input and output): option '--show-secrets' */
|
* and output): option '--show-secrets' */
|
||||||
bool overview; /* Overview mode (hide default values) */
|
bool overview : 1; /* Overview mode (hide default values) */
|
||||||
NmcColorPalette palette;
|
NmcColorPalette palette;
|
||||||
} NmcConfig;
|
} NmcConfig;
|
||||||
|
|
||||||
|
|
@ -128,21 +131,27 @@ typedef struct _NmCli {
|
||||||
GHashTable *pwds_hash; /* Hash table with passwords in passwd-file */
|
GHashTable *pwds_hash; /* Hash table with passwords in passwd-file */
|
||||||
struct _NMPolkitListener *pk_listener; /* polkit agent listener */
|
struct _NMPolkitListener *pk_listener; /* polkit agent listener */
|
||||||
|
|
||||||
int should_wait; /* Semaphore indicating whether nmcli should not end or not yet */
|
int should_wait; /* Semaphore indicating whether nmcli should not end or not yet */
|
||||||
gboolean nowait_flag; /* '--nowait' option; used for passing to callbacks */
|
|
||||||
gboolean mode_specified; /* Whether tabular/multiline mode was specified via '--mode' option */
|
bool nowait_flag : 1; /* '--nowait' option; used for passing to callbacks */
|
||||||
|
bool mode_specified : 1; /* Whether tabular/multiline mode was specified via '--mode' option */
|
||||||
|
bool offline : 1; /* Communicate the connection data over stdin/stdout
|
||||||
|
* instead of talking to the daemon. */
|
||||||
|
bool ask : 1; /* Ask for missing parameters: option '--ask' */
|
||||||
|
bool complete : 1; /* Autocomplete the command line */
|
||||||
|
bool editor_status_line : 1; /* Whether to display status line in connection editor */
|
||||||
|
bool editor_save_confirmation : 1; /* Whether to ask for confirmation on
|
||||||
|
* saving connections with 'autoconnect=yes' */
|
||||||
|
|
||||||
union {
|
union {
|
||||||
const NmcConfig nmc_config;
|
const NmcConfig nmc_config;
|
||||||
NmcConfig nmc_config_mutable;
|
NmcConfig nmc_config_mutable;
|
||||||
};
|
};
|
||||||
char *required_fields; /* Required fields in output: '--fields' option */
|
char *required_fields; /* Required fields in output: '--fields' option */
|
||||||
gboolean ask; /* Ask for missing parameters: option '--ask' */
|
|
||||||
gboolean complete; /* Autocomplete the command line */
|
|
||||||
gboolean editor_status_line; /* Whether to display status line in connection editor */
|
|
||||||
gboolean
|
|
||||||
editor_save_confirmation; /* Whether to ask for confirmation on saving connections with 'autoconnect=yes' */
|
|
||||||
|
|
||||||
char *palette_buffer; /* Buffer with sequences for terminal-colors.d(5)-based coloring. */
|
char *palette_buffer; /* Buffer with sequences for terminal-colors.d(5)-based coloring. */
|
||||||
|
|
||||||
|
GPtrArray *offline_connections;
|
||||||
} NmCli;
|
} NmCli;
|
||||||
|
|
||||||
extern const NmCli *const nm_cli_global_readline;
|
extern const NmCli *const nm_cli_global_readline;
|
||||||
|
|
@ -176,8 +185,15 @@ typedef struct _NMCCommand {
|
||||||
const char *cmd;
|
const char *cmd;
|
||||||
void (*func)(const struct _NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv);
|
void (*func)(const struct _NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv);
|
||||||
void (*usage)(void);
|
void (*usage)(void);
|
||||||
bool needs_client;
|
|
||||||
bool needs_nm_running;
|
bool needs_client : 1; /* Ensure a client instance is there before calling
|
||||||
|
* the handler (unless --offline has been given). */
|
||||||
|
bool needs_nm_running : 1; /* Client instance exists *and* the service is
|
||||||
|
* actually present on the bus. */
|
||||||
|
bool supports_offline : 1; /* Run the handler without a client even if the
|
||||||
|
* comand usually requires one if --offline option was used. */
|
||||||
|
bool needs_offline_conn : 1; /* With --online, read in a keyfile from
|
||||||
|
* standard input before dispatching the handler. */
|
||||||
} NMCCommand;
|
} NMCCommand;
|
||||||
|
|
||||||
void nmc_command_func_agent(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv);
|
void nmc_command_func_agent(const NMCCommand *cmd, NmCli *nmc, int argc, const char *const *argv);
|
||||||
|
|
|
||||||
137
src/tests/client/test-client.check-on-disk/test_offline.expected
Normal file
137
src/tests/client/test-client.check-on-disk/test_offline.expected
Normal file
|
|
@ -0,0 +1,137 @@
|
||||||
|
size: 258
|
||||||
|
location: src/tests/client/test-client.py:test_offline()/1
|
||||||
|
cmd: $NMCLI g
|
||||||
|
lang: C
|
||||||
|
returncode: 1
|
||||||
|
stderr: 136 bytes
|
||||||
|
>>>
|
||||||
|
Error: Could not create NMClient object: Key/Value pair 0, ?invalid?, in address element ?very:invalid? does not contain an equal sign.
|
||||||
|
|
||||||
|
<<<
|
||||||
|
size: 319
|
||||||
|
location: src/tests/client/test-client.py:test_offline()/2
|
||||||
|
cmd: $NMCLI --offline c add type ethernet
|
||||||
|
lang: C
|
||||||
|
returncode: 0
|
||||||
|
stdout: 169 bytes
|
||||||
|
>>>
|
||||||
|
[connection]
|
||||||
|
id=ethernet
|
||||||
|
uuid=UUID-WAS-HERE-BUT-IS-NO-MORE-SADLY
|
||||||
|
type=ethernet
|
||||||
|
|
||||||
|
[ethernet]
|
||||||
|
|
||||||
|
[ipv4]
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
[ipv6]
|
||||||
|
addr-gen-mode=stable-privacy
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
[proxy]
|
||||||
|
|
||||||
|
<<<
|
||||||
|
size: 183
|
||||||
|
location: src/tests/client/test-client.py:test_offline()/3
|
||||||
|
cmd: $NMCLI --offline c show
|
||||||
|
lang: C
|
||||||
|
returncode: 2
|
||||||
|
stderr: 47 bytes
|
||||||
|
>>>
|
||||||
|
Error: command doesn't support --offline mode.
|
||||||
|
|
||||||
|
<<<
|
||||||
|
size: 178
|
||||||
|
location: src/tests/client/test-client.py:test_offline()/4
|
||||||
|
cmd: $NMCLI --offline g
|
||||||
|
lang: C
|
||||||
|
returncode: 2
|
||||||
|
stderr: 47 bytes
|
||||||
|
>>>
|
||||||
|
Error: command doesn't support --offline mode.
|
||||||
|
|
||||||
|
<<<
|
||||||
|
size: 176
|
||||||
|
location: src/tests/client/test-client.py:test_offline()/5
|
||||||
|
cmd: $NMCLI --offline
|
||||||
|
lang: C
|
||||||
|
returncode: 2
|
||||||
|
stderr: 47 bytes
|
||||||
|
>>>
|
||||||
|
Error: command doesn't support --offline mode.
|
||||||
|
|
||||||
|
<<<
|
||||||
|
size: 443
|
||||||
|
location: src/tests/client/test-client.py:test_offline()/6
|
||||||
|
cmd: $NMCLI --offline c add type wifi ssid lala 802-1x.eap pwd 802-1x.identity foo 802-1x.password bar
|
||||||
|
lang: C
|
||||||
|
returncode: 0
|
||||||
|
stdout: 232 bytes
|
||||||
|
>>>
|
||||||
|
[connection]
|
||||||
|
id=wifi
|
||||||
|
uuid=UUID-WAS-HERE-BUT-IS-NO-MORE-SADLY
|
||||||
|
type=wifi
|
||||||
|
|
||||||
|
[wifi]
|
||||||
|
mode=infrastructure
|
||||||
|
ssid=lala
|
||||||
|
|
||||||
|
[802-1x]
|
||||||
|
eap=pwd;
|
||||||
|
identity=foo
|
||||||
|
password=bar
|
||||||
|
|
||||||
|
[ipv4]
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
[ipv6]
|
||||||
|
addr-gen-mode=stable-privacy
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
[proxy]
|
||||||
|
|
||||||
|
<<<
|
||||||
|
size: 481
|
||||||
|
location: src/tests/client/test-client.py:test_offline()/7
|
||||||
|
cmd: $NMCLI --offline c add type wifi ssid lala 802-1x.eap pwd 802-1x.identity foo 802-1x.password bar 802-1x.password-flags agent-owned
|
||||||
|
lang: C
|
||||||
|
returncode: 0
|
||||||
|
stdout: 236 bytes
|
||||||
|
>>>
|
||||||
|
[connection]
|
||||||
|
id=wifi
|
||||||
|
uuid=UUID-WAS-HERE-BUT-IS-NO-MORE-SADLY
|
||||||
|
type=wifi
|
||||||
|
|
||||||
|
[wifi]
|
||||||
|
mode=infrastructure
|
||||||
|
ssid=lala
|
||||||
|
|
||||||
|
[802-1x]
|
||||||
|
eap=pwd;
|
||||||
|
identity=foo
|
||||||
|
password-flags=1
|
||||||
|
|
||||||
|
[ipv4]
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
[ipv6]
|
||||||
|
addr-gen-mode=stable-privacy
|
||||||
|
method=auto
|
||||||
|
|
||||||
|
[proxy]
|
||||||
|
|
||||||
|
<<<
|
||||||
|
size: 199
|
||||||
|
location: src/tests/client/test-client.py:test_offline()/8
|
||||||
|
cmd: $NMCLI --complete-args --offline conn modify ipv6.ad
|
||||||
|
lang: C
|
||||||
|
returncode: 0
|
||||||
|
stdout: 34 bytes
|
||||||
|
>>>
|
||||||
|
ipv6.addresses
|
||||||
|
ipv6.addr-gen-mode
|
||||||
|
|
||||||
|
<<<
|
||||||
|
|
@ -202,6 +202,14 @@ class Util:
|
||||||
t = basestring
|
t = basestring
|
||||||
return isinstance(s, t)
|
return isinstance(s, t)
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def is_regex_pattern(s):
|
||||||
|
if Util.python_has_version(3):
|
||||||
|
t = re.Pattern
|
||||||
|
else:
|
||||||
|
t = re._pattern_type
|
||||||
|
return isinstance(s, t)
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def memoize_nullary(nullary_func):
|
def memoize_nullary(nullary_func):
|
||||||
result = []
|
result = []
|
||||||
|
|
@ -347,12 +355,21 @@ class Util:
|
||||||
v_search = replace[0]()
|
v_search = replace[0]()
|
||||||
except TypeError:
|
except TypeError:
|
||||||
v_search = replace[0]
|
v_search = replace[0]
|
||||||
|
|
||||||
|
v_replace = replace[1]
|
||||||
|
v_replace = v_replace.encode("utf-8")
|
||||||
|
|
||||||
|
if Util.is_regex_pattern(v_search):
|
||||||
|
text2 = []
|
||||||
|
for t in text:
|
||||||
|
text2.append(v_search.sub(v_replace, t))
|
||||||
|
text = text2
|
||||||
|
continue
|
||||||
|
|
||||||
assert v_search is None or Util.is_string(v_search)
|
assert v_search is None or Util.is_string(v_search)
|
||||||
if not v_search:
|
if not v_search:
|
||||||
continue
|
continue
|
||||||
v_replace = replace[1]
|
|
||||||
v_search = v_search.encode("utf-8")
|
v_search = v_search.encode("utf-8")
|
||||||
v_replace = v_replace.encode("utf-8")
|
|
||||||
text2 = []
|
text2 = []
|
||||||
for t in text:
|
for t in text:
|
||||||
if isinstance(t, tuple):
|
if isinstance(t, tuple):
|
||||||
|
|
@ -657,7 +674,13 @@ class AsyncProcess:
|
||||||
|
|
||||||
|
|
||||||
class NmTestBase(unittest.TestCase):
|
class NmTestBase(unittest.TestCase):
|
||||||
pass
|
def __init__(self, *args, **kwargs):
|
||||||
|
self._calling_num = {}
|
||||||
|
self._skip_test_for_l10n_diff = []
|
||||||
|
self._async_jobs = []
|
||||||
|
self._results = []
|
||||||
|
self.srv = None
|
||||||
|
return unittest.TestCase.__init__(self, *args, **kwargs)
|
||||||
|
|
||||||
|
|
||||||
MAX_JOBS = 15
|
MAX_JOBS = 15
|
||||||
|
|
@ -837,9 +860,6 @@ class TestNmcli(NmTestBase):
|
||||||
self.fail("invalid language %s" % (lang))
|
self.fail("invalid language %s" % (lang))
|
||||||
|
|
||||||
env = {}
|
env = {}
|
||||||
if extra_env is not None:
|
|
||||||
for k, v in extra_env.items():
|
|
||||||
env[k] = v
|
|
||||||
for k in ["LD_LIBRARY_PATH", "DBUS_SESSION_BUS_ADDRESS"]:
|
for k in ["LD_LIBRARY_PATH", "DBUS_SESSION_BUS_ADDRESS"]:
|
||||||
val = os.environ.get(k, None)
|
val = os.environ.get(k, None)
|
||||||
if val is not None:
|
if val is not None:
|
||||||
|
|
@ -856,6 +876,9 @@ class TestNmcli(NmTestBase):
|
||||||
env["NM_TEST_CALLING_NUM"] = str(calling_num)
|
env["NM_TEST_CALLING_NUM"] = str(calling_num)
|
||||||
if fatal_warnings is _DEFAULT_ARG or fatal_warnings:
|
if fatal_warnings is _DEFAULT_ARG or fatal_warnings:
|
||||||
env["G_DEBUG"] = "fatal-warnings"
|
env["G_DEBUG"] = "fatal-warnings"
|
||||||
|
if extra_env is not None:
|
||||||
|
for k, v in extra_env.items():
|
||||||
|
env[k] = v
|
||||||
|
|
||||||
args = [conf.get(ENV_NM_TEST_CLIENT_NMCLI_PATH)] + list(args)
|
args = [conf.get(ENV_NM_TEST_CLIENT_NMCLI_PATH)] + list(args)
|
||||||
|
|
||||||
|
|
@ -1012,20 +1035,13 @@ class TestNmcli(NmTestBase):
|
||||||
def async_wait(self):
|
def async_wait(self):
|
||||||
return self.async_start(wait_all=True)
|
return self.async_start(wait_all=True)
|
||||||
|
|
||||||
def _nm_test_pre(self):
|
|
||||||
self._calling_num = {}
|
|
||||||
self._skip_test_for_l10n_diff = []
|
|
||||||
self._async_jobs = []
|
|
||||||
self._results = []
|
|
||||||
|
|
||||||
self.srv = NMStubServer(self._testMethodName)
|
|
||||||
|
|
||||||
def _nm_test_post(self):
|
def _nm_test_post(self):
|
||||||
|
|
||||||
self.async_wait()
|
self.async_wait()
|
||||||
|
|
||||||
self.srv.shutdown()
|
if self.srv is not None:
|
||||||
self.srv = None
|
self.srv.shutdown()
|
||||||
|
self.srv = None
|
||||||
|
|
||||||
self._calling_num = None
|
self._calling_num = None
|
||||||
|
|
||||||
|
|
@ -1130,7 +1146,14 @@ class TestNmcli(NmTestBase):
|
||||||
|
|
||||||
def nm_test(func):
|
def nm_test(func):
|
||||||
def f(self):
|
def f(self):
|
||||||
self._nm_test_pre()
|
self.srv = NMStubServer(self._testMethodName)
|
||||||
|
func(self)
|
||||||
|
self._nm_test_post()
|
||||||
|
|
||||||
|
return f
|
||||||
|
|
||||||
|
def nm_test_no_dbus(func):
|
||||||
|
def f(self):
|
||||||
func(self)
|
func(self)
|
||||||
self._nm_test_post()
|
self._nm_test_post()
|
||||||
|
|
||||||
|
|
@ -1672,6 +1695,97 @@ class TestNmcli(NmTestBase):
|
||||||
replace_cmd=replace_uuids,
|
replace_cmd=replace_uuids,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@nm_test_no_dbus
|
||||||
|
def test_offline(self):
|
||||||
|
|
||||||
|
# Make sure we're not using D-Bus
|
||||||
|
no_dbus_env = {
|
||||||
|
"DBUS_SYSTEM_BUS_ADDRESS": "very:invalid",
|
||||||
|
"DBUS_SESSION_BUS_ADDRESS": "very:invalid",
|
||||||
|
}
|
||||||
|
|
||||||
|
# This check just makes sure the above works and the
|
||||||
|
# "nmcli g" command indeed fails talking to D-Bus
|
||||||
|
self.call_nmcli(
|
||||||
|
["g"],
|
||||||
|
extra_env=no_dbus_env,
|
||||||
|
)
|
||||||
|
|
||||||
|
replace_uuids = [
|
||||||
|
(
|
||||||
|
re.compile(b"uuid=.*"),
|
||||||
|
"uuid=UUID-WAS-HERE-BUT-IS-NO-MORE-SADLY",
|
||||||
|
)
|
||||||
|
]
|
||||||
|
|
||||||
|
self.call_nmcli(
|
||||||
|
["--offline", "c", "add", "type", "ethernet"],
|
||||||
|
extra_env=no_dbus_env,
|
||||||
|
replace_stdout=replace_uuids,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.call_nmcli(
|
||||||
|
["--offline", "c", "show"],
|
||||||
|
extra_env=no_dbus_env,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.call_nmcli(
|
||||||
|
["--offline", "g"],
|
||||||
|
extra_env=no_dbus_env,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.call_nmcli(
|
||||||
|
["--offline"],
|
||||||
|
extra_env=no_dbus_env,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.call_nmcli(
|
||||||
|
[
|
||||||
|
"--offline",
|
||||||
|
"c",
|
||||||
|
"add",
|
||||||
|
"type",
|
||||||
|
"wifi",
|
||||||
|
"ssid",
|
||||||
|
"lala",
|
||||||
|
"802-1x.eap",
|
||||||
|
"pwd",
|
||||||
|
"802-1x.identity",
|
||||||
|
"foo",
|
||||||
|
"802-1x.password",
|
||||||
|
"bar",
|
||||||
|
],
|
||||||
|
extra_env=no_dbus_env,
|
||||||
|
replace_stdout=replace_uuids,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.call_nmcli(
|
||||||
|
[
|
||||||
|
"--offline",
|
||||||
|
"c",
|
||||||
|
"add",
|
||||||
|
"type",
|
||||||
|
"wifi",
|
||||||
|
"ssid",
|
||||||
|
"lala",
|
||||||
|
"802-1x.eap",
|
||||||
|
"pwd",
|
||||||
|
"802-1x.identity",
|
||||||
|
"foo",
|
||||||
|
"802-1x.password",
|
||||||
|
"bar",
|
||||||
|
"802-1x.password-flags",
|
||||||
|
"agent-owned",
|
||||||
|
],
|
||||||
|
extra_env=no_dbus_env,
|
||||||
|
replace_stdout=replace_uuids,
|
||||||
|
)
|
||||||
|
|
||||||
|
self.call_nmcli(
|
||||||
|
["--complete-args", "--offline", "conn", "modify", "ipv6.ad"],
|
||||||
|
extra_env=no_dbus_env,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
###############################################################################
|
###############################################################################
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue