mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager
synced 2024-10-03 06:45:26 +00:00
team: normalize invalid configuration during load
Now that we validate the JSON syntax of a team/team-port configuration, any existing connection with invalid JSON configuration would fail to load and disappear upon upgrade. Instead, modify the setting plugins to emit a warning but still load the connection with empty configuration.
This commit is contained in:
parent
39ad134b0c
commit
d6ec009afd
|
@ -326,4 +326,9 @@ gboolean _nm_setting_bond_option_supported (const char *option, NMBondMode mode)
|
||||||
|
|
||||||
gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr);
|
gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr);
|
||||||
|
|
||||||
|
/***********************************************************/
|
||||||
|
|
||||||
|
gboolean _nm_utils_check_valid_json (const char *json, GError **error);
|
||||||
|
gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, gboolean port);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1167,6 +1167,24 @@ parity_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
||||||
g_object_set (setting, key, parity, NULL);
|
g_object_set (setting, key, parity, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
team_config_parser (KeyfileReaderInfo *info, NMSetting *setting, const char *key)
|
||||||
|
{
|
||||||
|
const char *setting_name = nm_setting_get_name (setting);
|
||||||
|
gs_free char *conf = NULL;
|
||||||
|
gs_free_error GError *error = NULL;
|
||||||
|
|
||||||
|
conf = nm_keyfile_plugin_kf_get_string (info->keyfile, setting_name, key, NULL);
|
||||||
|
if (conf && conf[0] && !_nm_utils_check_valid_json (conf, &error)) {
|
||||||
|
handle_warn (info, key, NM_KEYFILE_WARN_SEVERITY_WARN,
|
||||||
|
_("ignoring invalid team configuration: %s"),
|
||||||
|
error->message);
|
||||||
|
g_clear_pointer (&conf, g_free);
|
||||||
|
}
|
||||||
|
|
||||||
|
g_object_set (G_OBJECT (setting), key, conf, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
const char *setting_name;
|
const char *setting_name;
|
||||||
const char *key;
|
const char *key;
|
||||||
|
@ -1285,6 +1303,14 @@ static KeyParser key_parsers[] = {
|
||||||
NM_SETTING_SERIAL_PARITY,
|
NM_SETTING_SERIAL_PARITY,
|
||||||
TRUE,
|
TRUE,
|
||||||
parity_parser },
|
parity_parser },
|
||||||
|
{ NM_SETTING_TEAM_SETTING_NAME,
|
||||||
|
NM_SETTING_TEAM_CONFIG,
|
||||||
|
TRUE,
|
||||||
|
team_config_parser },
|
||||||
|
{ NM_SETTING_TEAM_PORT_SETTING_NAME,
|
||||||
|
NM_SETTING_TEAM_CONFIG,
|
||||||
|
TRUE,
|
||||||
|
team_config_parser },
|
||||||
{ NULL, NULL, FALSE }
|
{ NULL, NULL, FALSE }
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -31,9 +31,6 @@
|
||||||
gboolean _nm_utils_string_slist_validate (GSList *list,
|
gboolean _nm_utils_string_slist_validate (GSList *list,
|
||||||
const char **valid_values);
|
const char **valid_values);
|
||||||
|
|
||||||
gboolean _nm_utils_check_valid_json (const char *json, GError **error);
|
|
||||||
gboolean _nm_utils_team_config_equal (const char *conf1, const char *conf2, gboolean port);
|
|
||||||
|
|
||||||
/* D-Bus transform funcs */
|
/* D-Bus transform funcs */
|
||||||
|
|
||||||
GVariant *_nm_utils_hwaddr_cloned_get (NMSetting *setting,
|
GVariant *_nm_utils_hwaddr_cloned_get (NMSetting *setting,
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
#include "nm-setting-connection.h"
|
#include "nm-setting-connection.h"
|
||||||
#include "nm-setting-wired.h"
|
#include "nm-setting-wired.h"
|
||||||
#include "nm-setting-8021x.h"
|
#include "nm-setting-8021x.h"
|
||||||
|
#include "nm-setting-team.h"
|
||||||
|
|
||||||
#include "nm-utils/nm-test-utils.h"
|
#include "nm-utils/nm-test-utils.h"
|
||||||
|
|
||||||
|
@ -518,6 +519,52 @@ test_8021x_cert_read (void)
|
||||||
CLEAR (&con, &keyfile);
|
CLEAR (&con, &keyfile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_team_conf_read_valid (void)
|
||||||
|
{
|
||||||
|
GKeyFile *keyfile = NULL;
|
||||||
|
gs_unref_object NMConnection *con = NULL;
|
||||||
|
NMSettingTeam *s_team;
|
||||||
|
|
||||||
|
con = nmtst_create_connection_from_keyfile (
|
||||||
|
"[connection]\n"
|
||||||
|
"type=team\n"
|
||||||
|
"interface-name=nm-team1\n"
|
||||||
|
"[team]\n"
|
||||||
|
"config={\"foo\":\"bar\"}",
|
||||||
|
"/test_team_conf_read/valid", NULL);
|
||||||
|
|
||||||
|
g_assert (con);
|
||||||
|
s_team = nm_connection_get_setting_team (con);
|
||||||
|
g_assert (s_team);
|
||||||
|
g_assert_cmpstr (nm_setting_team_get_config (s_team), ==, "{\"foo\":\"bar\"}");
|
||||||
|
|
||||||
|
CLEAR (&con, &keyfile);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_team_conf_read_invalid (void)
|
||||||
|
{
|
||||||
|
GKeyFile *keyfile = NULL;
|
||||||
|
gs_unref_object NMConnection *con = NULL;
|
||||||
|
NMSettingTeam *s_team;
|
||||||
|
|
||||||
|
con = nmtst_create_connection_from_keyfile (
|
||||||
|
"[connection]\n"
|
||||||
|
"type=team\n"
|
||||||
|
"interface-name=nm-team1\n"
|
||||||
|
"[team]\n"
|
||||||
|
"config={foobar}",
|
||||||
|
"/test_team_conf_read/invalid", NULL);
|
||||||
|
|
||||||
|
g_assert (con);
|
||||||
|
s_team = nm_connection_get_setting_team (con);
|
||||||
|
g_assert (s_team);
|
||||||
|
g_assert (nm_setting_team_get_config (s_team) == NULL);
|
||||||
|
|
||||||
|
CLEAR (&con, &keyfile);
|
||||||
|
}
|
||||||
|
|
||||||
/******************************************************************************/
|
/******************************************************************************/
|
||||||
|
|
||||||
NMTST_DEFINE ();
|
NMTST_DEFINE ();
|
||||||
|
@ -528,6 +575,8 @@ int main (int argc, char **argv)
|
||||||
|
|
||||||
g_test_add_func ("/core/keyfile/test_8021x_cert", test_8021x_cert);
|
g_test_add_func ("/core/keyfile/test_8021x_cert", test_8021x_cert);
|
||||||
g_test_add_func ("/core/keyfile/test_8021x_cert_read", test_8021x_cert_read);
|
g_test_add_func ("/core/keyfile/test_8021x_cert_read", test_8021x_cert_read);
|
||||||
|
g_test_add_func ("/core/keyfile/test_team_conf_read/valid", test_team_conf_read_valid);
|
||||||
|
g_test_add_func ("/core/keyfile/test_team_conf_read/invalid", test_team_conf_read_invalid);
|
||||||
|
|
||||||
return g_test_run ();
|
return g_test_run ();
|
||||||
}
|
}
|
||||||
|
|
|
@ -4238,6 +4238,7 @@ bond_connection_from_ifcfg (const char *file,
|
||||||
static char *
|
static char *
|
||||||
read_team_config (shvarFile *ifcfg, const char *key, GError **error)
|
read_team_config (shvarFile *ifcfg, const char *key, GError **error)
|
||||||
{
|
{
|
||||||
|
gs_free_error GError *local_error = NULL;
|
||||||
char *value;
|
char *value;
|
||||||
size_t l;
|
size_t l;
|
||||||
|
|
||||||
|
@ -4258,6 +4259,12 @@ read_team_config (shvarFile *ifcfg, const char *key, GError **error)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
svUnescape (value);
|
svUnescape (value);
|
||||||
|
|
||||||
|
if (value && value[0] && !_nm_utils_check_valid_json (value, &local_error)) {
|
||||||
|
PARSE_WARNING ("ignoring invalid team configuration: %s", local_error->message);
|
||||||
|
g_clear_pointer (&value, g_free);
|
||||||
|
}
|
||||||
|
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,7 @@ EXTRA_DIST = \
|
||||||
ifcfg-test-fcoe-vn2vn \
|
ifcfg-test-fcoe-vn2vn \
|
||||||
ifcfg-test-team-master-1 \
|
ifcfg-test-team-master-1 \
|
||||||
ifcfg-test-team-master-2 \
|
ifcfg-test-team-master-2 \
|
||||||
|
ifcfg-test-team-master-invalid \
|
||||||
ifcfg-test-team-port-1 \
|
ifcfg-test-team-port-1 \
|
||||||
ifcfg-test-team-port-2 \
|
ifcfg-test-team-port-2 \
|
||||||
ifcfg-test-team-port-empty-config \
|
ifcfg-test-team-port-empty-config \
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
DEVICE=team0
|
||||||
|
ONBOOT=no
|
||||||
|
BOOTPROTO=dhcp
|
||||||
|
TEAM_CONFIG="{ foobar }"
|
|
@ -8453,6 +8453,31 @@ test_read_team_master (gconstpointer user_data)
|
||||||
g_object_unref (connection);
|
g_object_unref (connection);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_read_team_master_invalid (gconstpointer user_data)
|
||||||
|
{
|
||||||
|
const char *const PATH_NAME = user_data;
|
||||||
|
NMConnection *connection;
|
||||||
|
NMSettingConnection *s_con;
|
||||||
|
NMSettingTeam *s_team;
|
||||||
|
|
||||||
|
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE, "*ignoring invalid team configuration*");
|
||||||
|
connection = _connection_from_file (PATH_NAME, NULL, TYPE_ETHERNET, NULL);
|
||||||
|
g_test_assert_expected_messages ();
|
||||||
|
|
||||||
|
g_assert_cmpstr (nm_connection_get_interface_name (connection), ==, "team0");
|
||||||
|
|
||||||
|
s_con = nm_connection_get_setting_connection (connection);
|
||||||
|
g_assert (s_con);
|
||||||
|
g_assert_cmpstr (nm_setting_connection_get_connection_type (s_con), ==, NM_SETTING_TEAM_SETTING_NAME);
|
||||||
|
|
||||||
|
s_team = nm_connection_get_setting_team (connection);
|
||||||
|
g_assert (s_team);
|
||||||
|
g_assert (nm_setting_team_get_config (s_team) == NULL);
|
||||||
|
|
||||||
|
g_object_unref (connection);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_write_team_master (void)
|
test_write_team_master (void)
|
||||||
{
|
{
|
||||||
|
@ -9050,6 +9075,7 @@ int main (int argc, char **argv)
|
||||||
|
|
||||||
g_test_add_data_func (TPATH "team/read-master-1", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master-1", test_read_team_master);
|
g_test_add_data_func (TPATH "team/read-master-1", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master-1", test_read_team_master);
|
||||||
g_test_add_data_func (TPATH "team/read-master-2", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master-2", test_read_team_master);
|
g_test_add_data_func (TPATH "team/read-master-2", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master-2", test_read_team_master);
|
||||||
|
g_test_add_data_func (TPATH "team/read-master-invalid", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-master-invalid", test_read_team_master_invalid);
|
||||||
g_test_add_func (TPATH "team/write-master", test_write_team_master);
|
g_test_add_func (TPATH "team/write-master", test_write_team_master);
|
||||||
g_test_add_data_func (TPATH "team/read-port-1", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port-1", test_read_team_port);
|
g_test_add_data_func (TPATH "team/read-port-1", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port-1", test_read_team_port);
|
||||||
g_test_add_data_func (TPATH "team/read-port-2", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port-2", test_read_team_port);
|
g_test_add_data_func (TPATH "team/read-port-2", TEST_IFCFG_DIR"/network-scripts/ifcfg-test-team-port-2", test_read_team_port);
|
||||||
|
|
Loading…
Reference in a new issue