mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-04 07:10:33 +01:00
merge: branch 'lr/sw-device-cleanup'
https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/2126
This commit is contained in:
commit
4a8e672506
6 changed files with 580 additions and 161 deletions
|
|
@ -2594,7 +2594,7 @@ nm_manager_remove_device(NMManager *self, const char *ifname, NMDeviceType devic
|
|||
* Returns: A #NMDevice that was just realized; %NULL if none
|
||||
*/
|
||||
static NMDevice *
|
||||
system_create_virtual_device(NMManager *self, NMConnection *connection)
|
||||
system_create_virtual_device(NMManager *self, NMConnection *connection, GError **error)
|
||||
{
|
||||
NMManagerPrivate *priv = NM_MANAGER_GET_PRIVATE(self);
|
||||
NMDeviceFactory *factory;
|
||||
|
|
@ -2605,20 +2605,20 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
|
|||
NMDevice *device = NULL;
|
||||
NMDevice *parent = NULL;
|
||||
NMDevice *dev_candidate;
|
||||
gs_free_error GError *error = NULL;
|
||||
NMLogLevel log_level;
|
||||
|
||||
g_return_val_if_fail(NM_IS_MANAGER(self), NULL);
|
||||
g_return_val_if_fail(NM_IS_CONNECTION(connection), NULL);
|
||||
|
||||
iface = nm_manager_get_connection_iface(self, connection, &parent, &parent_spec, &error);
|
||||
if (!iface) {
|
||||
_LOG3D(LOGD_DEVICE, connection, "can't get a name of a virtual device: %s", error->message);
|
||||
iface = nm_manager_get_connection_iface(self, connection, &parent, &parent_spec, error);
|
||||
if (!iface)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (parent_spec && !parent) {
|
||||
/* parent is not ready, wait */
|
||||
g_set_error(error,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_DEPENDENCY_FAILED,
|
||||
"Parent device for '%s' not available",
|
||||
iface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2626,7 +2626,11 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
|
|||
c_list_for_each_entry (dev_candidate, &priv->devices_lst_head, devices_lst) {
|
||||
if (nm_device_check_connection_compatible(dev_candidate, connection, FALSE, NULL)) {
|
||||
if (nm_device_is_real(dev_candidate)) {
|
||||
_LOG3D(LOGD_DEVICE, connection, "already created virtual interface name %s", iface);
|
||||
g_set_error(error,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
||||
"Device named '%s' already exists",
|
||||
iface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
@ -2640,27 +2644,22 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
|
|||
|
||||
factory = nm_device_factory_manager_find_factory_for_connection(connection);
|
||||
if (!factory) {
|
||||
_LOG3E(LOGD_DEVICE,
|
||||
connection,
|
||||
"(%s) NetworkManager plugin for '%s' unavailable",
|
||||
iface,
|
||||
nm_connection_get_connection_type(connection));
|
||||
g_set_error(error,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
||||
"'%s' plugin for '%s' unavailable",
|
||||
nm_connection_get_connection_type(connection),
|
||||
iface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device = nm_device_factory_create_device(factory, iface, NULL, connection, NULL, &error);
|
||||
if (!device) {
|
||||
_LOG3W(LOGD_DEVICE, connection, "factory can't create the device: %s", error->message);
|
||||
device = nm_device_factory_create_device(factory, iface, NULL, connection, NULL, error);
|
||||
if (!device)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
_LOG3D(LOGD_DEVICE, connection, "create virtual device %s", nm_device_get_iface(device));
|
||||
|
||||
if (!add_device(self, device, &error)) {
|
||||
_LOG3W(LOGD_DEVICE,
|
||||
connection,
|
||||
"can't register the device with manager: %s",
|
||||
error->message);
|
||||
if (!add_device(self, device, error)) {
|
||||
g_object_unref(device);
|
||||
return NULL;
|
||||
}
|
||||
|
|
@ -2679,10 +2678,8 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
|
|||
return device;
|
||||
}
|
||||
|
||||
if (!find_controller(self, connection, device, NULL, NULL, NULL, &error)) {
|
||||
_LOG3D(LOGD_DEVICE, connection, "skip activation: %s", error->message);
|
||||
if (!find_controller(self, connection, device, NULL, NULL, NULL, error))
|
||||
return device;
|
||||
}
|
||||
|
||||
/* Create backing resources if the device has any autoconnect connections */
|
||||
connections = nm_settings_get_connections_sorted_by_autoconnect_priority(priv->settings, NULL);
|
||||
|
|
@ -2699,18 +2696,8 @@ system_create_virtual_device(NMManager *self, NMConnection *connection)
|
|||
continue;
|
||||
|
||||
/* Create any backing resources the device needs */
|
||||
if (!nm_device_create_and_realize(device, connection, parent, &error)) {
|
||||
log_level =
|
||||
g_error_matches(error, NM_DEVICE_ERROR, NM_DEVICE_ERROR_MISSING_DEPENDENCIES)
|
||||
? LOGL_DEBUG
|
||||
: LOGL_ERR;
|
||||
_NMLOG3(log_level,
|
||||
LOGD_DEVICE,
|
||||
connection,
|
||||
"couldn't create the device: %s",
|
||||
error->message);
|
||||
if (!nm_device_create_and_realize(device, connection, parent, error))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
retry_connections_for_parent_device(self, device);
|
||||
break;
|
||||
|
|
@ -2751,8 +2738,9 @@ retry_connections_for_parent_device(NMManager *self, NMDevice *device)
|
|||
static void
|
||||
connection_changed(NMManager *self, NMSettingsConnection *sett_conn)
|
||||
{
|
||||
NMConnection *connection;
|
||||
NMDevice *device;
|
||||
NMConnection *connection;
|
||||
NMDevice *device;
|
||||
gs_free_error GError *error = NULL;
|
||||
|
||||
if (NM_FLAGS_ANY(nm_settings_connection_get_flags(sett_conn),
|
||||
NM_SETTINGS_CONNECTION_INT_FLAGS_VOLATILE
|
||||
|
|
@ -2764,9 +2752,11 @@ connection_changed(NMManager *self, NMSettingsConnection *sett_conn)
|
|||
if (!nm_connection_is_virtual(connection))
|
||||
return;
|
||||
|
||||
device = system_create_virtual_device(self, connection);
|
||||
if (!device)
|
||||
device = system_create_virtual_device(self, connection, &error);
|
||||
if (!device) {
|
||||
_LOG3D(LOGD_DEVICE, connection, "Can't create a virtual device: %s", error->message);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Maybe the device that was created was needed by some other
|
||||
* connection's device (parent of a VLAN). Let the connections
|
||||
|
|
@ -6548,18 +6538,9 @@ find_device_for_activation(NMManager *self,
|
|||
return FALSE;
|
||||
|
||||
device = find_device_by_iface(self, iface, connection, NULL, NULL);
|
||||
if (!device) {
|
||||
g_set_error_literal(error,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
||||
"Failed to find a compatible device for this connection");
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nm_assert(is_vpn || NM_IS_DEVICE(device));
|
||||
|
||||
*out_device = device;
|
||||
*out_is_vpn = is_vpn;
|
||||
|
||||
|
|
@ -6684,7 +6665,14 @@ impl_manager_activate_connection(NMDBusObject *obj,
|
|||
if (!subject)
|
||||
goto error;
|
||||
|
||||
if (!find_device_for_activation(self, sett_conn, NULL, device_path, &device, &is_vpn, &error)) {
|
||||
if (!find_device_for_activation(self, sett_conn, NULL, device_path, &device, &is_vpn, &error))
|
||||
goto error;
|
||||
|
||||
if (!device && !is_vpn) {
|
||||
g_set_error_literal(&error,
|
||||
NM_MANAGER_ERROR,
|
||||
NM_MANAGER_ERROR_UNKNOWN_DEVICE,
|
||||
"Failed to find a compatible device for this connection");
|
||||
goto error;
|
||||
}
|
||||
|
||||
|
|
@ -6807,6 +6795,7 @@ _add_and_activate_auth_done(NMManager *self,
|
|||
const char *error_desc)
|
||||
{
|
||||
NMManagerPrivate *priv;
|
||||
NMDevice *device;
|
||||
GError *error = NULL;
|
||||
|
||||
if (!success) {
|
||||
|
|
@ -6819,6 +6808,14 @@ _add_and_activate_auth_done(NMManager *self,
|
|||
nm_active_connection_get_subject(active),
|
||||
error->message);
|
||||
g_dbus_method_invocation_take_error(invocation, error);
|
||||
|
||||
device = nm_active_connection_get_device(active);
|
||||
if (device && nm_device_is_software(device)
|
||||
&& !nm_device_managed_type_is_external_or_assume(device)
|
||||
&& _check_remove_dev_on_link_deleted(self, device)) {
|
||||
remove_device(self, device, FALSE);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -6974,32 +6971,11 @@ impl_manager_add_and_activate_connection(NMDBusObject *obj,
|
|||
goto error;
|
||||
}
|
||||
|
||||
if (is_vpn) {
|
||||
/* Try to fill the VPN's connection setting and name at least */
|
||||
if (!nm_connection_get_setting_vpn(incompl_conn)) {
|
||||
error = g_error_new_literal(NM_CONNECTION_ERROR,
|
||||
NM_CONNECTION_ERROR_MISSING_SETTING,
|
||||
"VPN connections require a 'vpn' setting");
|
||||
g_prefix_error(&error, "%s: ", NM_SETTING_VPN_SETTING_NAME);
|
||||
goto error;
|
||||
}
|
||||
conns = nm_settings_connections_array_to_connections(
|
||||
nm_settings_get_connections(priv->settings, NULL),
|
||||
-1);
|
||||
|
||||
conns = nm_settings_connections_array_to_connections(
|
||||
nm_settings_get_connections(priv->settings, NULL),
|
||||
-1);
|
||||
|
||||
nm_utils_complete_generic(priv->platform,
|
||||
incompl_conn,
|
||||
NM_SETTING_VPN_SETTING_NAME,
|
||||
conns,
|
||||
NULL,
|
||||
_("VPN connection"),
|
||||
NULL,
|
||||
NULL);
|
||||
} else {
|
||||
conns = nm_settings_connections_array_to_connections(
|
||||
nm_settings_get_connections(priv->settings, NULL),
|
||||
-1);
|
||||
if (device) {
|
||||
/* Let each device subclass complete the connection */
|
||||
if (!nm_device_complete_connection(device,
|
||||
incompl_conn,
|
||||
|
|
@ -7007,9 +6983,27 @@ impl_manager_add_and_activate_connection(NMDBusObject *obj,
|
|||
conns,
|
||||
&error))
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
nm_utils_complete_generic(priv->platform,
|
||||
incompl_conn,
|
||||
nm_connection_get_connection_type(incompl_conn),
|
||||
conns,
|
||||
is_vpn ? _("VPN connection") : NULL,
|
||||
nm_connection_get_connection_type(incompl_conn),
|
||||
NULL,
|
||||
NULL);
|
||||
|
||||
nm_assert(_nm_connection_verify(incompl_conn, NULL) == NM_SETTING_VERIFY_SUCCESS);
|
||||
if (!nm_connection_verify(incompl_conn, &error))
|
||||
goto error;
|
||||
|
||||
if (!is_vpn && !device) {
|
||||
nm_assert(nm_connection_is_virtual(incompl_conn));
|
||||
|
||||
device = system_create_virtual_device(self, incompl_conn, &error);
|
||||
if (!device)
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
active = _new_active_connection(self,
|
||||
is_vpn,
|
||||
|
|
|
|||
|
|
@ -140,6 +140,8 @@ out:
|
|||
|
||||
/*****************************************************************************/
|
||||
|
||||
static const NMUtilsNamedValue *gl_interfaces_map = NULL;
|
||||
|
||||
static NMUtilsNamedValue *
|
||||
_map_interfaces_parse(void)
|
||||
{
|
||||
|
|
@ -200,46 +202,38 @@ _map_interfaces_parse(void)
|
|||
static const char *
|
||||
_device_get_hwaddr(NMDevice *device)
|
||||
{
|
||||
static const NMUtilsNamedValue *gl_map_interfaces_map = NULL;
|
||||
static gsize gl_initialized = 0;
|
||||
const NMUtilsNamedValue *map = NULL;
|
||||
const NMUtilsNamedValue *map = NULL;
|
||||
|
||||
nm_assert(NM_IS_DEVICE_ETHERNET(device) || NM_IS_DEVICE_MACVLAN(device)
|
||||
|| NM_IS_DEVICE_VLAN(device));
|
||||
|
||||
/* Network interfaces in cloud environments are identified by their permanent
|
||||
* MAC address.
|
||||
*
|
||||
* For testing, we can set NMCS_ENV_NM_CLOUD_SETUP_MAP_INTERFACES
|
||||
* to a ';' separate list of "$INTERFACE=$HWADDR", which means that we
|
||||
* pretend that device with ip-interface "$INTERFACE" has the specified permanent
|
||||
* MAC address. */
|
||||
if (NM_IS_DEVICE_ETHERNET(device)) {
|
||||
/* Ethernet interfaces in cloud environments are identified by their permanent
|
||||
* MAC address.
|
||||
*
|
||||
* For testing, we can set NMCS_ENV_NM_CLOUD_SETUP_MAP_INTERFACES
|
||||
* to a ';' separate list of "$INTERFACE=$HWADDR", which means that we
|
||||
* pretend that device with ip-interface "$INTERFACE" has the specified permanent
|
||||
* MAC address. */
|
||||
|
||||
if (g_once_init_enter(&gl_initialized)) {
|
||||
gl_map_interfaces_map = _map_interfaces_parse();
|
||||
g_once_init_leave(&gl_initialized, 1);
|
||||
}
|
||||
map = gl_interfaces_map;
|
||||
if (G_UNLIKELY(map)) {
|
||||
const char *const iface = nm_device_get_iface(NM_DEVICE(device));
|
||||
|
||||
map = gl_map_interfaces_map;
|
||||
if (G_UNLIKELY(map)) {
|
||||
const char *const iface = nm_device_get_iface(NM_DEVICE(device));
|
||||
/* For testing, the device<->hwaddr is remapped and the actual permanent
|
||||
* MAC address of the device ignored. This mapping is configured via
|
||||
* NMCS_ENV_NM_CLOUD_SETUP_MAP_INTERFACES environment variable. */
|
||||
if (!iface)
|
||||
return NULL;
|
||||
|
||||
/* For testing, the device<->hwaddr is remapped and the actual permanent
|
||||
* MAC address of the device ignored. This mapping is configured via
|
||||
* NMCS_ENV_NM_CLOUD_SETUP_MAP_INTERFACES environment variable. */
|
||||
for (; map->name; map++) {
|
||||
if (nm_streq(map->name, iface))
|
||||
return map->value_str;
|
||||
}
|
||||
|
||||
if (!iface)
|
||||
return NULL;
|
||||
|
||||
for (; map->name; map++) {
|
||||
if (nm_streq(map->name, iface))
|
||||
return map->value_str;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (NM_IS_DEVICE_ETHERNET(device)) {
|
||||
return nm_device_ethernet_get_permanent_hw_address(NM_DEVICE_ETHERNET(device));
|
||||
} else {
|
||||
return nm_device_get_hw_address(device);
|
||||
|
|
@ -295,7 +289,7 @@ _nmc_get_ethernet_hwaddrs(NMClient *nmc)
|
|||
}
|
||||
|
||||
static NMDevice *
|
||||
_nmc_get_device_by_hwaddr(NMClient *nmc, const char *hwaddr)
|
||||
_nmc_get_device_by_hwaddr(NMClient *nmc, const GType type_device, const char *hwaddr)
|
||||
{
|
||||
const GPtrArray *devices;
|
||||
guint i;
|
||||
|
|
@ -307,7 +301,7 @@ _nmc_get_device_by_hwaddr(NMClient *nmc, const char *hwaddr)
|
|||
const char *hwaddr_dev;
|
||||
gs_free char *s = NULL;
|
||||
|
||||
if (!NM_IS_DEVICE_ETHERNET(device))
|
||||
if (!G_TYPE_CHECK_INSTANCE_TYPE(device, type_device))
|
||||
continue;
|
||||
|
||||
hwaddr_dev = _device_get_hwaddr(device);
|
||||
|
|
@ -427,13 +421,22 @@ _nmc_mangle_connection(NMDevice *device,
|
|||
NM_SET_OUT(out_skipped_single_addr, FALSE);
|
||||
NM_SET_OUT(out_changed, FALSE);
|
||||
|
||||
if (nm_streq(nm_connection_get_connection_type(connection), NM_SETTING_MACVLAN_SETTING_NAME)) {
|
||||
/* The MACVLAN just sits in between, no L3 configuration on it */
|
||||
return;
|
||||
} else if (!nm_streq(nm_connection_get_connection_type(connection),
|
||||
NM_SETTING_VLAN_SETTING_NAME)) {
|
||||
/* Preserve existing L3 configuration if not a VLAN */
|
||||
if (device) {
|
||||
if ((ac = nm_device_get_active_connection(device))
|
||||
&& (remote_connection = NM_CONNECTION(nm_active_connection_get_connection(ac))))
|
||||
remote_s_ip = nm_connection_get_setting_ip4_config(remote_connection);
|
||||
}
|
||||
}
|
||||
|
||||
s_ip = nm_connection_get_setting_ip4_config(connection);
|
||||
nm_assert(NM_IS_SETTING_IP4_CONFIG(s_ip));
|
||||
|
||||
if ((ac = nm_device_get_active_connection(device))
|
||||
&& (remote_connection = NM_CONNECTION(nm_active_connection_get_connection(ac))))
|
||||
remote_s_ip = nm_connection_get_setting_ip4_config(remote_connection);
|
||||
|
||||
addrs_new = g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_address_unref);
|
||||
rules_new =
|
||||
g_ptr_array_new_full(config_data->ipv4s_len, (GDestroyNotify) nm_ip_routing_rule_unref);
|
||||
|
|
@ -566,54 +569,31 @@ _nmc_mangle_connection(NMDevice *device,
|
|||
/*****************************************************************************/
|
||||
|
||||
static gboolean
|
||||
_config_one(SigTermData *sigterm_data,
|
||||
NMClient *nmc,
|
||||
const NMCSProviderGetConfigResult *result,
|
||||
guint idx)
|
||||
_config_existing(SigTermData *sigterm_data,
|
||||
const NMCSProviderGetConfigIfaceData *config_data,
|
||||
NMClient *nmc,
|
||||
const NMCSProviderGetConfigResult *result,
|
||||
const char *connection_type,
|
||||
NMDevice *device)
|
||||
{
|
||||
const NMCSProviderGetConfigIfaceData *config_data = result->iface_datas_arr[idx];
|
||||
const char *hwaddr = config_data->hwaddr;
|
||||
gs_unref_object NMDevice *device = NULL;
|
||||
gs_unref_object NMConnection *applied_connection = NULL;
|
||||
guint64 applied_version_id;
|
||||
gs_free_error GError *error = NULL;
|
||||
gboolean changed;
|
||||
gboolean skipped_single_addr;
|
||||
gboolean version_id_changed;
|
||||
guint try_count;
|
||||
gboolean any_changes = FALSE;
|
||||
gboolean maybe_no_preserved_external_ip;
|
||||
|
||||
g_main_context_iteration(NULL, FALSE);
|
||||
|
||||
if (g_cancellable_is_cancelled(sigterm_data->cancellable))
|
||||
return FALSE;
|
||||
|
||||
device = nm_g_object_ref(_nmc_get_device_by_hwaddr(nmc, hwaddr));
|
||||
if (!device) {
|
||||
_LOGD("config device %s: skip because device not found", hwaddr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (!nmcs_provider_get_config_iface_data_is_valid(config_data)) {
|
||||
_LOGD("config device %s: skip because meta data not successfully fetched", hwaddr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (config_data->iface_idx >= 100) {
|
||||
/* since we use the iface_idx to select a table number, the range is limited from
|
||||
* 0 to 99. Note that the providers are required to provide increasing numbers,
|
||||
* so this means we bail out after the first 100 devices. */
|
||||
_LOGD("config device %s: skip because number of supported interfaces reached", hwaddr);
|
||||
return FALSE;
|
||||
}
|
||||
const char *hwaddr = config_data->hwaddr;
|
||||
gs_unref_object NMConnection *applied_connection = NULL;
|
||||
guint64 applied_version_id;
|
||||
gs_free_error GError *error = NULL;
|
||||
gboolean changed;
|
||||
gboolean skipped_single_addr;
|
||||
gboolean version_id_changed;
|
||||
guint try_count;
|
||||
gboolean any_changes;
|
||||
gboolean maybe_no_preserved_external_ip;
|
||||
|
||||
_LOGD("config device %s: configuring \"%s\" (%s)...",
|
||||
hwaddr,
|
||||
nm_device_get_iface(device) ?: "/unknown/",
|
||||
nm_object_get_path(NM_OBJECT(device)));
|
||||
|
||||
try_count = 0;
|
||||
try_count = 0;
|
||||
any_changes = FALSE;
|
||||
|
||||
try_again:
|
||||
g_clear_object(&applied_connection);
|
||||
|
|
@ -638,7 +618,7 @@ try_again:
|
|||
return any_changes;
|
||||
}
|
||||
|
||||
if (_nmc_skip_connection_by_type(applied_connection, NM_SETTING_WIRED_SETTING_NAME)) {
|
||||
if (_nmc_skip_connection_by_type(applied_connection, connection_type)) {
|
||||
_LOGD("config device %s: device has no suitable applied connection. Skip", hwaddr);
|
||||
return any_changes;
|
||||
}
|
||||
|
|
@ -705,7 +685,7 @@ try_again:
|
|||
nm_connection_get_uuid(applied_connection),
|
||||
error->message);
|
||||
}
|
||||
return any_changes;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
_LOGD("config device %s: connection \"%s\" (%s) reapplied",
|
||||
|
|
@ -713,17 +693,254 @@ try_again:
|
|||
nm_connection_get_id(applied_connection),
|
||||
nm_connection_get_uuid(applied_connection));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_config_ethernet(SigTermData *sigterm_data,
|
||||
const NMCSProviderGetConfigIfaceData *config_data,
|
||||
NMClient *nmc,
|
||||
const NMCSProviderGetConfigResult *result)
|
||||
{
|
||||
gs_unref_object NMDevice *device = NULL;
|
||||
|
||||
device = nm_g_object_ref(
|
||||
_nmc_get_device_by_hwaddr(nmc, NM_TYPE_DEVICE_ETHERNET, config_data->hwaddr));
|
||||
if (!device) {
|
||||
_LOGD("config device %s: skip because device not found", config_data->hwaddr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return _config_existing(sigterm_data,
|
||||
config_data,
|
||||
nmc,
|
||||
result,
|
||||
NM_SETTING_WIRED_SETTING_NAME,
|
||||
device);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_oci_new_vlan_dev(SigTermData *sigterm_data,
|
||||
const NMCSProviderGetConfigIfaceData *config_data,
|
||||
NMClient *nmc,
|
||||
const NMCSProviderGetConfigResult *result,
|
||||
const char *connection_type,
|
||||
const char *parent_hwaddr)
|
||||
{
|
||||
const char *hwaddr = config_data->hwaddr;
|
||||
gs_unref_object NMConnection *connection = NULL;
|
||||
gs_unref_object NMActiveConnection *active_connection = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
gs_free char *macvlan_name = NULL;
|
||||
gs_free char *connection_id = NULL;
|
||||
char *ifname = NULL;
|
||||
const char *macvlan_parent = NULL;
|
||||
const char *wired_mac_addr = NULL;
|
||||
const NMUtilsNamedValue *map = NULL;
|
||||
const char *ip4_config_method;
|
||||
NMSetting *s_user;
|
||||
|
||||
connection = nm_simple_connection_new();
|
||||
|
||||
macvlan_name = g_strdup_printf("macvlan%ld", config_data->iface_idx);
|
||||
connection_id = g_strdup_printf("%s%ld", connection_type, config_data->iface_idx);
|
||||
|
||||
wired_mac_addr = parent_hwaddr;
|
||||
if (nm_streq(connection_type, NM_SETTING_MACVLAN_SETTING_NAME)) {
|
||||
/* In NM-ci, use macvlan.parent instead of wired.mac-address for parent matching
|
||||
* because we are faking the MAC addresses via NM_CLOUD_SETUP_MAP_INTERFACES.
|
||||
* The daemon still needs the real MAC, not the mapped one, so it won't work. */
|
||||
map = gl_interfaces_map;
|
||||
if (G_UNLIKELY(map)) {
|
||||
for (; map->name; map++) {
|
||||
if (nm_streq(map->value_str, parent_hwaddr)) {
|
||||
macvlan_parent = map->name;
|
||||
wired_mac_addr = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
nm_connection_add_setting(connection,
|
||||
g_object_new(NM_TYPE_SETTING_MACVLAN,
|
||||
NM_SETTING_MACVLAN_MODE,
|
||||
NM_SETTING_MACVLAN_MODE_VEPA,
|
||||
NM_SETTING_MACVLAN_PARENT,
|
||||
macvlan_parent,
|
||||
NULL));
|
||||
nm_connection_add_setting(connection,
|
||||
g_object_new(NM_TYPE_SETTING_IP6_CONFIG,
|
||||
NM_SETTING_IP_CONFIG_METHOD,
|
||||
NM_SETTING_IP6_CONFIG_METHOD_DISABLED,
|
||||
NULL));
|
||||
ip4_config_method = NM_SETTING_IP4_CONFIG_METHOD_DISABLED;
|
||||
ifname = macvlan_name;
|
||||
} else if (nm_streq(connection_type, NM_SETTING_VLAN_SETTING_NAME)) {
|
||||
nm_connection_add_setting(connection,
|
||||
g_object_new(NM_TYPE_SETTING_VLAN,
|
||||
NM_SETTING_VLAN_PARENT,
|
||||
macvlan_name,
|
||||
NM_SETTING_VLAN_ID,
|
||||
config_data->priv.oci.vlan_tag,
|
||||
NULL));
|
||||
ip4_config_method = NM_SETTING_IP4_CONFIG_METHOD_MANUAL;
|
||||
} else {
|
||||
g_return_val_if_reached(FALSE);
|
||||
}
|
||||
|
||||
nm_connection_add_setting(connection,
|
||||
g_object_new(NM_TYPE_SETTING_CONNECTION,
|
||||
NM_SETTING_CONNECTION_ID,
|
||||
connection_id,
|
||||
NM_SETTING_CONNECTION_TYPE,
|
||||
connection_type,
|
||||
NM_SETTING_CONNECTION_INTERFACE_NAME,
|
||||
ifname,
|
||||
NULL));
|
||||
nm_connection_add_setting(connection,
|
||||
g_object_new(NM_TYPE_SETTING_IP4_CONFIG,
|
||||
NM_SETTING_IP_CONFIG_METHOD,
|
||||
ip4_config_method,
|
||||
NULL));
|
||||
|
||||
nm_connection_add_setting(connection,
|
||||
g_object_new(NM_TYPE_SETTING_WIRED,
|
||||
NM_SETTING_WIRED_MAC_ADDRESS,
|
||||
wired_mac_addr,
|
||||
NM_SETTING_WIRED_CLONED_MAC_ADDRESS,
|
||||
hwaddr,
|
||||
NULL));
|
||||
|
||||
s_user = nm_setting_user_new();
|
||||
nm_connection_add_setting(connection, s_user);
|
||||
nm_setting_user_set_data(NM_SETTING_USER(s_user),
|
||||
"org.freedesktop.NetworkManager.origin",
|
||||
"nm-cloud-setup",
|
||||
NULL);
|
||||
|
||||
_nmc_mangle_connection(NULL, connection, result, config_data, NULL, NULL);
|
||||
|
||||
_LOGD("config device %s: creating %s connection for VLAN %d on %s...",
|
||||
hwaddr,
|
||||
ifname ?: connection_type,
|
||||
config_data->priv.oci.vlan_tag,
|
||||
parent_hwaddr);
|
||||
|
||||
active_connection = nmcs_add_and_activate(nmc, NULL, connection, &error);
|
||||
if (active_connection == NULL) {
|
||||
if (!nm_utils_error_is_cancelled(error)) {
|
||||
_LOGD("config device %s: failure to activate connection: %s", hwaddr, error->message);
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
_LOGD("config device %s: connection \"%s\" (%s) created",
|
||||
hwaddr,
|
||||
nm_active_connection_get_id(active_connection),
|
||||
nm_active_connection_get_uuid(active_connection));
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_oci_config_vnic_dev(SigTermData *sigterm_data,
|
||||
const NMCSProviderGetConfigIfaceData *config_data,
|
||||
NMClient *nmc,
|
||||
const NMCSProviderGetConfigResult *result,
|
||||
const GType device_type,
|
||||
const char *connection_type,
|
||||
const char *parent_hwaddr)
|
||||
{
|
||||
gs_unref_object NMDevice *device = NULL;
|
||||
|
||||
device = nm_g_object_ref(_nmc_get_device_by_hwaddr(nmc, device_type, config_data->hwaddr));
|
||||
if (device) {
|
||||
/* There is a device. Modify and reapply the currently applied connection. */
|
||||
return _config_existing(sigterm_data, config_data, nmc, result, connection_type, device);
|
||||
} else {
|
||||
/* There is no device, but we're configuring a VLAN.
|
||||
* We can just go ahead and create one with a new connection. */
|
||||
return _oci_new_vlan_dev(sigterm_data,
|
||||
config_data,
|
||||
nmc,
|
||||
result,
|
||||
connection_type,
|
||||
parent_hwaddr);
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_config_one(SigTermData *sigterm_data,
|
||||
NMCSProvider *provider,
|
||||
NMClient *nmc,
|
||||
const NMCSProviderGetConfigResult *result,
|
||||
guint idx)
|
||||
{
|
||||
const NMCSProviderGetConfigIfaceData *config_data = result->iface_datas_arr[idx];
|
||||
gboolean any_changes;
|
||||
|
||||
g_main_context_iteration(NULL, FALSE);
|
||||
|
||||
if (g_cancellable_is_cancelled(sigterm_data->cancellable))
|
||||
return FALSE;
|
||||
|
||||
if (!nmcs_provider_get_config_iface_data_is_valid(config_data)) {
|
||||
_LOGD("config device %s: skip because meta data not successfully fetched",
|
||||
config_data->hwaddr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (config_data->iface_idx >= 100) {
|
||||
/* since we use the iface_idx to select a table number, the range is limited from
|
||||
* 0 to 99. Note that the providers are required to provide increasing numbers,
|
||||
* so this means we bail out after the first 100 devices. */
|
||||
_LOGD("config device %s: skip because number of supported interfaces reached",
|
||||
config_data->hwaddr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (NMCS_IS_PROVIDER_OCI(provider) && config_data->priv.oci.vlan_tag != 0) {
|
||||
if (config_data->priv.oci.parent_hwaddr == NULL) {
|
||||
_LOGW("config device %s: has vlan id %d but no parent device",
|
||||
config_data->hwaddr,
|
||||
config_data->priv.oci.vlan_tag);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* MACVLAN first, because VLAN is on top of it. */
|
||||
any_changes = _oci_config_vnic_dev(sigterm_data,
|
||||
config_data,
|
||||
nmc,
|
||||
result,
|
||||
NM_TYPE_DEVICE_MACVLAN,
|
||||
NM_SETTING_MACVLAN_SETTING_NAME,
|
||||
config_data->priv.oci.parent_hwaddr);
|
||||
any_changes += _oci_config_vnic_dev(sigterm_data,
|
||||
config_data,
|
||||
nmc,
|
||||
result,
|
||||
NM_TYPE_DEVICE_VLAN,
|
||||
NM_SETTING_VLAN_SETTING_NAME,
|
||||
config_data->hwaddr);
|
||||
|
||||
} else {
|
||||
any_changes = _config_ethernet(sigterm_data, config_data, nmc, result);
|
||||
}
|
||||
|
||||
return any_changes;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
_config_all(SigTermData *sigterm_data, NMClient *nmc, const NMCSProviderGetConfigResult *result)
|
||||
_config_all(SigTermData *sigterm_data,
|
||||
NMCSProvider *provider,
|
||||
NMClient *nmc,
|
||||
const NMCSProviderGetConfigResult *result)
|
||||
{
|
||||
gboolean any_changes = FALSE;
|
||||
guint i;
|
||||
|
||||
for (i = 0; i < result->n_iface_datas; i++) {
|
||||
if (_config_one(sigterm_data, nmc, result, i))
|
||||
if (_config_one(sigterm_data, provider, nmc, result, i))
|
||||
any_changes = TRUE;
|
||||
}
|
||||
|
||||
|
|
@ -804,11 +1021,14 @@ main(int argc, const char *const *argv)
|
|||
goto done;
|
||||
}
|
||||
|
||||
/* Initialize map used in test scenarios. */
|
||||
gl_interfaces_map = _map_interfaces_parse();
|
||||
|
||||
result = _get_config(sigterm_cancellable, provider, nmc);
|
||||
if (!result)
|
||||
goto done;
|
||||
|
||||
if (_config_all(&sigterm_data, nmc, result))
|
||||
if (_config_all(&sigterm_data, provider, nmc, result))
|
||||
_LOGI("some changes were applied for provider %s", nmcs_provider_get_name(provider));
|
||||
else
|
||||
_LOGD("no changes were applied for provider %s", nmcs_provider_get_name(provider));
|
||||
|
|
|
|||
|
|
@ -92,6 +92,9 @@ _get_config_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||
gs_unref_bytes GBytes *response = NULL;
|
||||
gs_free_error GError *error = NULL;
|
||||
nm_auto_decref_json json_t *vnics = NULL;
|
||||
gboolean is_baremetal;
|
||||
gs_unref_ptrarray GPtrArray *phys_nic_macs = NULL;
|
||||
GHashTableIter h_iter;
|
||||
size_t i;
|
||||
|
||||
nm_http_client_poll_req_finish(NM_HTTP_CLIENT(source), result, NULL, &response, &error);
|
||||
|
|
@ -112,12 +115,24 @@ _get_config_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||
goto out;
|
||||
}
|
||||
|
||||
if (json_array_size(vnics) > 0) {
|
||||
is_baremetal = NULL != json_object_get(json_array_get(vnics, 0), "nicIndex");
|
||||
_LOGI("get-config: detected %s instance", is_baremetal ? "baremetal" : "VM");
|
||||
} else {
|
||||
is_baremetal = FALSE;
|
||||
_LOGI("get-config: empty VNICs metadata, cannot detect instance type");
|
||||
}
|
||||
|
||||
if (is_baremetal)
|
||||
phys_nic_macs = g_ptr_array_sized_new(16);
|
||||
|
||||
for (i = 0; i < json_array_size(vnics); i++) {
|
||||
json_t *vnic, *field;
|
||||
const char *vnic_id = "", *val;
|
||||
gs_free char *mac = NULL;
|
||||
in_addr_t addr;
|
||||
int prefix;
|
||||
json_int_t nic_index = -1, vlan_tag = -1;
|
||||
|
||||
vnic = json_array_get(vnics, i);
|
||||
if (!json_is_object(vnic)) {
|
||||
|
|
@ -130,12 +145,28 @@ _get_config_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||
|
||||
field = json_object_get(vnic, "macAddr");
|
||||
val = field && json_is_string(field) ? json_string_value(field) : NULL;
|
||||
if (!val) {
|
||||
mac = val ? nmcs_utils_hwaddr_normalize(val, json_string_length(field)) : NULL;
|
||||
if (!mac) {
|
||||
_VNIC_WARN("missing or invalid 'macAddr', ignoring VNIC");
|
||||
continue;
|
||||
}
|
||||
|
||||
mac = nmcs_utils_hwaddr_normalize(val, json_string_length(field));
|
||||
if (is_baremetal) {
|
||||
field = json_object_get(vnic, "nicIndex");
|
||||
nic_index = field && json_is_integer(field) ? json_integer_value(field) : -1;
|
||||
if (nic_index < 0 || nic_index >= 1024) { /* 1024 = random limit to prevent abuse*/
|
||||
_VNIC_WARN("missing or invalid 'nicIndex', ignoring VNIC");
|
||||
continue;
|
||||
}
|
||||
|
||||
field = json_object_get(vnic, "vlanTag");
|
||||
vlan_tag = field && json_is_integer(field) ? json_integer_value(field) : -1;
|
||||
if (vlan_tag < 0) {
|
||||
_VNIC_WARN("missing or invalid 'vlanTag', ignoring VNIC");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
config_iface_data = nmcs_provider_get_config_iface_data_create(get_config_data, FALSE, mac);
|
||||
config_iface_data->iface_idx = i;
|
||||
|
||||
|
|
@ -168,6 +199,48 @@ _get_config_done_cb(GObject *source, GAsyncResult *result, gpointer user_data)
|
|||
} else {
|
||||
_VNIC_WARN("missing or invalid 'subnetCidrBlock'");
|
||||
}
|
||||
|
||||
if (is_baremetal) {
|
||||
gboolean is_phys_nic = vlan_tag == 0;
|
||||
|
||||
/* In baremetal instances, configure VNICs' VLAN (physical NICs don't need it) */
|
||||
if (is_phys_nic) {
|
||||
config_iface_data->priv.oci.vlan_tag = 0;
|
||||
config_iface_data->priv.oci.parent_hwaddr = NULL;
|
||||
if (nic_index >= phys_nic_macs->len)
|
||||
g_ptr_array_set_size(phys_nic_macs,
|
||||
NM_MAX((guint) (nic_index + 1), phys_nic_macs->len * 2));
|
||||
phys_nic_macs->pdata[nic_index] = (gpointer) config_iface_data->hwaddr;
|
||||
} else {
|
||||
/* We might not have all the physical NICs' MACs yet, save nicIndex for later */
|
||||
config_iface_data->priv.oci.parent_hwaddr = GINT_TO_POINTER((int) nic_index);
|
||||
config_iface_data->priv.oci.vlan_tag = vlan_tag;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (is_baremetal) {
|
||||
g_hash_table_iter_init(&h_iter, get_config_data->result_dict);
|
||||
|
||||
/* Now that all the metadata is processed we should have all the physical NICs' MACs */
|
||||
while (g_hash_table_iter_next(&h_iter, NULL, (gpointer *) &config_iface_data)) {
|
||||
bool is_phys_nic = config_iface_data->priv.oci.vlan_tag == 0;
|
||||
int nic_index = GPOINTER_TO_INT(config_iface_data->priv.oci.parent_hwaddr);
|
||||
|
||||
if (is_phys_nic)
|
||||
continue;
|
||||
|
||||
if (nic_index >= phys_nic_macs->len || phys_nic_macs->pdata[nic_index] == NULL) {
|
||||
_LOGW("get-config: physical NIC for nicIndex=%d not found, ignoring VNIC "
|
||||
"(VNIC macAddr=%s)",
|
||||
nic_index,
|
||||
config_iface_data->hwaddr);
|
||||
g_hash_table_iter_remove(&h_iter);
|
||||
continue;
|
||||
}
|
||||
|
||||
config_iface_data->priv.oci.parent_hwaddr = g_strdup(phys_nic_macs->pdata[nic_index]);
|
||||
}
|
||||
}
|
||||
|
||||
out:
|
||||
|
|
|
|||
|
|
@ -188,6 +188,7 @@ nmcs_provider_get_config_iface_data_create(NMCSProviderGetConfigTaskData *get_co
|
|||
|
||||
iface_data = g_slice_new(NMCSProviderGetConfigIfaceData);
|
||||
*iface_data = (NMCSProviderGetConfigIfaceData) {
|
||||
.provider = g_object_ref(get_config_data->self),
|
||||
.get_config_data = get_config_data,
|
||||
.hwaddr = g_strdup(hwaddr),
|
||||
.iface_idx = -1,
|
||||
|
|
@ -203,6 +204,11 @@ nmcs_provider_get_config_iface_data_create(NMCSProviderGetConfigTaskData *get_co
|
|||
iface_data->priv.aliyun = (typeof(iface_data->priv.aliyun)) {
|
||||
.has_primary_ip_address = FALSE,
|
||||
};
|
||||
} else if (G_OBJECT_TYPE(get_config_data->self) == nmcs_provider_oci_get_type()) {
|
||||
iface_data->priv.oci = (typeof(iface_data->priv.oci)) {
|
||||
.vlan_tag = 0,
|
||||
.parent_hwaddr = NULL,
|
||||
};
|
||||
}
|
||||
|
||||
/* the has does not own the key (iface_datta->hwaddr), the lifetime of the
|
||||
|
|
@ -220,6 +226,9 @@ _iface_data_free(gpointer data)
|
|||
g_free(iface_data->ipv4s_arr);
|
||||
nm_g_ptr_array_unref(iface_data->iproutes);
|
||||
g_free((char *) iface_data->hwaddr);
|
||||
if (G_OBJECT_TYPE(iface_data->provider) == nmcs_provider_oci_get_type())
|
||||
g_free((char *) iface_data->priv.oci.parent_hwaddr);
|
||||
g_clear_object(&iface_data->provider);
|
||||
|
||||
nm_g_slice_free(iface_data);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ typedef struct {
|
|||
* dictionary. */
|
||||
const char *hwaddr;
|
||||
|
||||
struct _NMCSProvider *provider;
|
||||
|
||||
struct _NMCSProviderGetConfigTaskData *get_config_data;
|
||||
|
||||
in_addr_t *ipv4s_arr;
|
||||
|
|
@ -51,6 +53,10 @@ typedef struct {
|
|||
bool has_primary_ip_address : 1;
|
||||
bool ipv4s_arr_ordered : 1;
|
||||
} aliyun;
|
||||
struct {
|
||||
guint32 vlan_tag; /* 0 if no VLAN is needed */
|
||||
const char *parent_hwaddr;
|
||||
} oci;
|
||||
} priv;
|
||||
|
||||
} NMCSProviderGetConfigIfaceData;
|
||||
|
|
|
|||
|
|
@ -2907,6 +2907,123 @@ class TestNmCloudSetup(unittest.TestCase):
|
|||
)
|
||||
self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status")
|
||||
|
||||
@cloud_setup_test
|
||||
def test_oci_vlans(self):
|
||||
self._mock_devices()
|
||||
|
||||
oci_meta = "/opc/v2/"
|
||||
self._mock_path(oci_meta + "instance", "{}")
|
||||
self._mock_path(
|
||||
oci_meta + "vnics",
|
||||
"""
|
||||
[
|
||||
{
|
||||
"macAddr": "%s",
|
||||
"privateIp": "%s",
|
||||
"subnetCidrBlock": "172.31.16.0/20",
|
||||
"virtualRouterIp": "172.31.16.1",
|
||||
"vlanTag": 0,
|
||||
"nicIndex": 0,
|
||||
"vnicId": "ocid1.vnic.oc1.cz-adamov1.foobarbaz"
|
||||
},
|
||||
{
|
||||
"macAddr": "%s",
|
||||
"privateIp": "%s",
|
||||
"subnetCidrBlock": "172.31.166.0/20",
|
||||
"virtualRouterIp": "172.31.166.1",
|
||||
"vlanTag": 0,
|
||||
"nicIndex": 1,
|
||||
"vnicId": "ocid1.vnic.oc1.uk-hogwarts.expelliarmus"
|
||||
},
|
||||
{
|
||||
"macAddr": "C0:00:00:00:00:10",
|
||||
"privateIp": "172.31.10.10",
|
||||
"subnetCidrBlock": "172.31.10.0/20",
|
||||
"virtualRouterIp": "172.31.10.1",
|
||||
"vlanTag": 700,
|
||||
"nicIndex": 0,
|
||||
"vnicId": "ocid1.vnic.oc1.uk-hogwarts.keka"
|
||||
}
|
||||
]
|
||||
"""
|
||||
% (
|
||||
TestNmCloudSetup._mac1,
|
||||
TestNmCloudSetup._ip1,
|
||||
TestNmCloudSetup._mac2,
|
||||
TestNmCloudSetup._ip2,
|
||||
),
|
||||
)
|
||||
|
||||
# Run nm-cloud-setup for the first time
|
||||
pexp = self.ctx.cmd_call_pexpect(
|
||||
ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH,
|
||||
[],
|
||||
{
|
||||
"NM_CLOUD_SETUP_OCI_HOST": self.md_url,
|
||||
"NM_CLOUD_SETUP_LOG": "trace",
|
||||
"NM_CLOUD_SETUP_OCI": "yes",
|
||||
},
|
||||
)
|
||||
|
||||
pexp.expect("provider oci detected")
|
||||
pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02")
|
||||
pexp.expect("get-config: starting")
|
||||
pexp.expect("get-config: success")
|
||||
pexp.expect("meta data received")
|
||||
|
||||
# No configuration for the ethernets
|
||||
pexp.expect('configuring "eth0"')
|
||||
pexp.expect("device has no suitable applied connection. Skip")
|
||||
|
||||
# Setting up the VLAN
|
||||
pexp.expect("creating macvlan2 connection for VLAN 700 on CC:00:00:00:00:01...")
|
||||
pexp.expect("creating vlan connection for VLAN 700 on C0:00:00:00:00:10...")
|
||||
pexp.expect("some changes were applied for provider oci")
|
||||
|
||||
(exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp)
|
||||
Util.valgrind_check_log(valgrind_log, "test_oci_vlans")
|
||||
self.assertIsNone(
|
||||
signalstatus,
|
||||
"Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0),
|
||||
)
|
||||
self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status")
|
||||
|
||||
# TODO: Actually check the contents of the connection
|
||||
# Probably needs changes to the mock service API
|
||||
conn_macvlan = self.ctx.srv.findConnections(con_id="connection-3")
|
||||
assert conn_macvlan is not None
|
||||
conn_vlan = self.ctx.srv.findConnections(con_id="connection-4")
|
||||
assert conn_vlan is not None
|
||||
|
||||
# Run nm-cloud-setup for the second time
|
||||
pexp = self.ctx.cmd_call_pexpect(
|
||||
ENV_NM_TEST_CLIENT_CLOUD_SETUP_PATH,
|
||||
[],
|
||||
{
|
||||
"NM_CLOUD_SETUP_OCI_HOST": self.md_url,
|
||||
"NM_CLOUD_SETUP_LOG": "trace",
|
||||
"NM_CLOUD_SETUP_OCI": "yes",
|
||||
},
|
||||
)
|
||||
|
||||
# Just the same ol' thing, just no changes this time
|
||||
pexp.expect("provider oci detected")
|
||||
pexp.expect("found interfaces: CC:00:00:00:00:01, CC:00:00:00:00:02")
|
||||
pexp.expect("get-config: starting")
|
||||
pexp.expect("get-config: success")
|
||||
pexp.expect("meta data received")
|
||||
pexp.expect('configuring "eth0"')
|
||||
pexp.expect("device has no suitable applied connection. Skip")
|
||||
pexp.expect("no changes were applied for provider oci")
|
||||
|
||||
(exitstatus, signalstatus, valgrind_log) = self.ctx.cmd_close_pexpect(pexp)
|
||||
Util.valgrind_check_log(valgrind_log, "test_oci_vlans")
|
||||
self.assertIsNone(
|
||||
signalstatus,
|
||||
"Unexpectedly got " + Util.signal_no_to_str(signalstatus or 0),
|
||||
)
|
||||
self.assertEqual(exitstatus, 0, "Unexpectedly returned a non-zero status")
|
||||
|
||||
|
||||
###############################################################################
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue