nm.device: Deletion: Assume removed interface as success
Instead of making various and wrong assumption in `_delete_device_callback()` which errors mean that the interface is removed, just check if the interface is not there anymore. This will also handle failures like `nm-device-error-quark: This device is not a software device or is not realized (5)` or `error=nm-client-error-quark: Object is no longer in the client cache (0)` that were not caught by the previous code. When these errors happened or probably when `NMDevice.is_real()` returns `False`, `NMDevice.get_iface()` returns `None`. Therefore get the interface earlier to have it available in the callback. A better solution might be to refactor Nmstate to properly pass a context about which part of the desired state is handled in each async call to ensure the interface name and possibly other useful information is always present. Signed-off-by: Till Maas <opensource@till.name>
This commit is contained in:
parent
5096f56d64
commit
82574ec3a4
@ -1,5 +1,5 @@
|
||||
#
|
||||
# Copyright (c) 2018-2019 Red Hat, Inc.
|
||||
# Copyright (c) 2018-2020 Red Hat, Inc.
|
||||
#
|
||||
# This file is part of nmstate
|
||||
#
|
||||
@ -173,62 +173,37 @@ def delete_device(nmdev):
|
||||
|
||||
def _safe_delete_device_async(nmdev):
|
||||
mainloop = nmclient.mainloop()
|
||||
user_data = mainloop, nmdev
|
||||
user_data = mainloop, nmdev, nmdev.get_iface()
|
||||
nmdev.delete_async(
|
||||
mainloop.cancellable, _delete_device_callback, user_data
|
||||
)
|
||||
|
||||
|
||||
def _delete_device_callback(src_object, result, user_data):
|
||||
mainloop, nmdev = user_data
|
||||
mainloop, nmdev, iface = user_data
|
||||
error = None
|
||||
try:
|
||||
success = src_object.delete_finish(result)
|
||||
# pylint: disable=catching-non-exception
|
||||
except nmclient.GLib.GError as e:
|
||||
# pylint: enable=catching-non-exception
|
||||
if e.matches(
|
||||
nmclient.Gio.DBusError.quark(),
|
||||
nmclient.Gio.DBusError.UNKNOWN_METHOD,
|
||||
) or (
|
||||
e.matches(
|
||||
nmclient.NM.DeviceError.quark(),
|
||||
nmclient.NM.DeviceError.NOTSOFTWARE,
|
||||
)
|
||||
and nmdev.is_software()
|
||||
):
|
||||
logging.debug(
|
||||
"Device %s has been already deleted: error=%s",
|
||||
nmdev.get_iface(),
|
||||
e,
|
||||
)
|
||||
mainloop.execute_next_action()
|
||||
else:
|
||||
mainloop.quit(
|
||||
"Device deletion failed on {}: error={}".format(
|
||||
nmdev.get_iface(), e
|
||||
)
|
||||
)
|
||||
return
|
||||
src_object.delete_finish(result)
|
||||
except Exception as e:
|
||||
if mainloop.is_action_canceled(e):
|
||||
error = e
|
||||
if mainloop.is_action_canceled(error):
|
||||
logging.debug(
|
||||
"Device deletion aborted on %s: error=%s", nmdev.get_iface(), e
|
||||
"Device deletion aborted on %s: error=%s", iface, error
|
||||
)
|
||||
return
|
||||
|
||||
if not nmdev.is_real():
|
||||
logging.debug("Interface is not real anymore: iface=%s", iface)
|
||||
if error:
|
||||
logging.debug(
|
||||
"Ignored error: %s", error,
|
||||
)
|
||||
else:
|
||||
mainloop.quit(
|
||||
"Device deletion failed on {}: error={}".format(
|
||||
nmdev.get_iface(), e
|
||||
)
|
||||
)
|
||||
return
|
||||
|
||||
devname = src_object.get_iface()
|
||||
if success:
|
||||
logging.debug("Device deletion succeeded: dev=%s", devname)
|
||||
mainloop.execute_next_action()
|
||||
else:
|
||||
mainloop.quit(
|
||||
"Device deletion failed: dev={}, error=unknown".format(devname)
|
||||
f"Device deletion failed on {iface} ({nmdev.get_path()}): "
|
||||
f"error={error or 'unknown'}"
|
||||
)
|
||||
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user