Blame libnmstate/nm/connection.py

Packit Service 0535c1
#
Packit Service 0535c1
# Copyright (c) 2018-2020 Red Hat, Inc.
Packit Service 0535c1
#
Packit Service 0535c1
# This file is part of nmstate
Packit Service 0535c1
#
Packit Service 0535c1
# This program is free software: you can redistribute it and/or modify
Packit Service 0535c1
# it under the terms of the GNU Lesser General Public License as published by
Packit Service 0535c1
# the Free Software Foundation, either version 2.1 of the License, or
Packit Service 0535c1
# (at your option) any later version.
Packit Service 0535c1
#
Packit Service 0535c1
# This program is distributed in the hope that it will be useful,
Packit Service 0535c1
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit Service 0535c1
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit Service 0535c1
# GNU Lesser General Public License for more details.
Packit Service 0535c1
#
Packit Service 0535c1
# You should have received a copy of the GNU Lesser General Public License
Packit Service 0535c1
# along with this program. If not, see <https://www.gnu.org/licenses/>.
Packit Service 0535c1
#
Packit Service 0535c1
Packit Service 0535c1
import logging
Packit Service 0535c1
import uuid
Packit Service 0535c1
Packit Service 0535c1
from libnmstate.error import NmstateLibnmError
Packit Service 0535c1
from libnmstate.error import NmstateInternalError
Packit Service 0535c1
from libnmstate.error import NmstateValueError
Packit Service 0535c1
Packit Service 0535c1
from .common import NM
Packit Service 0535c1
from . import ipv4
Packit Service 0535c1
from . import ipv6
Packit Service 0535c1
Packit Service 0535c1
ACTIVATION_TIMEOUT_FOR_BRIDGE = 35  # Bridge STP requires 30 seconds.
Packit Service 0535c1
Packit Service 0535c1
Packit Service 0535c1
class ConnectionProfile:
Packit Service 0535c1
    def __init__(self, context, profile=None):
Packit Service 0535c1
        self._ctx = context
Packit Service 0535c1
        self._con_profile = profile
Packit Service 0535c1
        self._nm_dev = None
Packit Service 0535c1
        self._con_id = None
Packit Service 0535c1
        self._nm_ac = None
Packit Service 0535c1
        self._ac_handlers = set()
Packit Service 0535c1
        self._dev_handlers = set()
Packit Service 0535c1
Packit Service 0535c1
    def create(self, settings):
Packit Service 0535c1
        self.profile = NM.SimpleConnection.new()
Packit Service 0535c1
        for setting in settings:
Packit Service 0535c1
            self.profile.add_setting(setting)
Packit Service 0535c1
Packit Service 0535c1
    def import_by_device(self, nmdev=None):
Packit Service 0535c1
        ac = get_device_active_connection(nmdev or self.nmdevice)
Packit Service 0535c1
        if ac:
Packit Service 0535c1
            if nmdev:
Packit Service 0535c1
                self.nmdevice = nmdev
Packit Service 0535c1
            self.profile = ac.props.connection
Packit Service 0535c1
Packit Service 0535c1
    def import_by_id(self, con_id=None):
Packit Service 0535c1
        if con_id:
Packit Service 0535c1
            self.con_id = con_id
Packit Service 0535c1
        if self.con_id:
Packit Service 0535c1
            self.profile = self._ctx.client.get_connection_by_id(self.con_id)
Packit Service 0535c1
Packit Service 0535c1
    def update(self, con_profile, save_to_disk=True):
Packit Service 0535c1
        flags = NM.SettingsUpdate2Flags.BLOCK_AUTOCONNECT
Packit Service 0535c1
        if save_to_disk:
Packit Service 0535c1
            flags |= NM.SettingsUpdate2Flags.TO_DISK
Packit Service 0535c1
        else:
Packit Service 0535c1
            flags |= NM.SettingsUpdate2Flags.IN_MEMORY
Packit Service 0535c1
        action = f"Update profile: {self.profile.get_id()}"
Packit Service 0535c1
        user_data = action
Packit Service 0535c1
        args = None
Packit Service 0535c1
Packit Service 0535c1
        self._ctx.register_async(action, fast=True)
Packit Service 0535c1
        self.profile.update2(
Packit Service 0535c1
            con_profile.profile.to_dbus(NM.ConnectionSerializationFlags.ALL),
Packit Service 0535c1
            flags,
Packit Service 0535c1
            args,
Packit Service 0535c1
            self._ctx.cancellable,
Packit Service 0535c1
            self._update2_callback,
Packit Service 0535c1
            user_data,
Packit Service 0535c1
        )
Packit Service 0535c1
Packit Service 0535c1
    def add(self, save_to_disk=True):
Packit Service 0535c1
        nm_add_conn2_flags = NM.SettingsAddConnection2Flags
Packit Service 0535c1
        flags = nm_add_conn2_flags.BLOCK_AUTOCONNECT
Packit Service 0535c1
        if save_to_disk:
Packit Service 0535c1
            flags |= nm_add_conn2_flags.TO_DISK
Packit Service 0535c1
        else:
Packit Service 0535c1
            flags |= nm_add_conn2_flags.IN_MEMORY
Packit Service 0535c1
Packit Service 0535c1
        action = f"Add profile: {self.profile.get_id()}"
Packit Service 0535c1
        self._ctx.register_async(action, fast=True)
Packit Service 0535c1
Packit Service 0535c1
        user_data = action
Packit Service 0535c1
        args = None
Packit Service 0535c1
        ignore_out_result = False  # Don't fall back to old AddConnection()
Packit Service 0535c1
        self._ctx.client.add_connection2(
Packit Service 0535c1
            self.profile.to_dbus(NM.ConnectionSerializationFlags.ALL),
Packit Service 0535c1
            flags,
Packit Service 0535c1
            args,
Packit Service 0535c1
            ignore_out_result,
Packit Service 0535c1
            self._ctx.cancellable,
Packit Service 0535c1
            self._add_connection2_callback,
Packit Service 0535c1
            user_data,
Packit Service 0535c1
        )
Packit Service 0535c1
Packit Service 0535c1
    def delete(self):
Packit Service 0535c1
        if not self.profile:
Packit Service 0535c1
            self.import_by_id()
Packit Service 0535c1
            if not self.profile:
Packit Service 0535c1
                self.import_by_device()
Packit Service 0535c1
        if self.profile:
Packit Service 0535c1
            action = (
Packit Service 0535c1
                f"Delete profile: id:{self.profile.get_id()}, "
Packit Service 0535c1
                f"uuid:{self.profile.get_uuid()}"
Packit Service 0535c1
            )
Packit Service 0535c1
            user_data = action
Packit Service 0535c1
            self._ctx.register_async(action, fast=True)
Packit Service 0535c1
            self.profile.delete_async(
Packit Service 0535c1
                self._ctx.cancellable,
Packit Service 0535c1
                self._delete_connection_callback,
Packit Service 0535c1
                user_data,
Packit Service 0535c1
            )
Packit Service 0535c1
Packit Service 0535c1
    def activate(self):
Packit Service 0535c1
        if self.con_id:
Packit Service 0535c1
            self.import_by_id()
Packit Service 0535c1
        elif self.nmdevice:
Packit Service 0535c1
            self.import_by_device()
Packit Service 0535c1
        elif not self.profile:
Packit Service 0535c1
            raise NmstateInternalError(
Packit Service 0535c1
                "BUG: Failed  to find valid profile to activate: "
Packit Service 0535c1
                f"id={self.con_id}, dev={self.devname}"
Packit Service 0535c1
            )
Packit Service 0535c1
Packit Service 0535c1
        specific_object = None
Packit Service 0535c1
        if self.profile:
Packit Service 0535c1
            action = f"Activate profile: {self.profile.get_id()}"
Packit Service 0535c1
        elif self.nmdevice:
Packit Service 0535c1
            action = f"Activate profile: {self.nmdevice.get_iface()}"
Packit Service 0535c1
        else:
Packit Service 0535c1
            raise NmstateInternalError(
Packit Service 0535c1
                "BUG: Cannot activate a profile with empty profile id and "
Packit Service 0535c1
                "empty NM.Device"
Packit Service 0535c1
            )
Packit Service 0535c1
        user_data = action
Packit Service 0535c1
        self._ctx.register_async(action)
Packit Service 0535c1
        self._ctx.client.activate_connection_async(
Packit Service 0535c1
            self.profile,
Packit Service 0535c1
            self.nmdevice,
Packit Service 0535c1
            specific_object,
Packit Service 0535c1
            self._ctx.cancellable,
Packit Service 0535c1
            self._active_connection_callback,
Packit Service 0535c1
            user_data,
Packit Service 0535c1
        )
Packit Service 0535c1
Packit Service 0535c1
    @property
Packit Service 0535c1
    def profile(self):
Packit Service 0535c1
        return self._con_profile
Packit Service 0535c1
Packit Service 0535c1
    @profile.setter
Packit Service 0535c1
    def profile(self, con_profile):
Packit Service 0535c1
        assert self._con_profile is None
Packit Service 0535c1
        self._con_profile = con_profile
Packit Service 0535c1
Packit Service 0535c1
    @property
Packit Service 0535c1
    def devname(self):
Packit Service 0535c1
        if self._con_profile:
Packit Service 0535c1
            return self._con_profile.get_interface_name()
Packit Service 0535c1
        return None
Packit Service 0535c1
Packit Service 0535c1
    @property
Packit Service 0535c1
    def nmdevice(self):
Packit Service 0535c1
        return self._nm_dev
Packit Service 0535c1
Packit Service 0535c1
    @nmdevice.setter
Packit Service 0535c1
    def nmdevice(self, dev):
Packit Service 0535c1
        assert self._nm_dev is None
Packit Service 0535c1
        self._nm_dev = dev
Packit Service 0535c1
Packit Service 0535c1
    @property
Packit Service 0535c1
    def con_id(self):
Packit Service 0535c1
        con_id = self._con_profile.get_id() if self._con_profile else None
Packit Service 0535c1
        return self._con_id or con_id
Packit Service 0535c1
Packit Service 0535c1
    @con_id.setter
Packit Service 0535c1
    def con_id(self, connection_id):
Packit Service 0535c1
        assert self._con_id is None
Packit Service 0535c1
        self._con_id = connection_id
Packit Service 0535c1
Packit Service 0535c1
    def get_setting_duplicate(self, setting_name):
Packit Service 0535c1
        setting = None
Packit Service 0535c1
        if self.profile:
Packit Service 0535c1
            setting = self.profile.get_setting_by_name(setting_name)
Packit Service 0535c1
            if setting:
Packit Service 0535c1
                setting = setting.duplicate()
Packit Service 0535c1
        return setting
Packit Service 0535c1
Packit Service 0535c1
    def _active_connection_callback(self, src_object, result, user_data):
Packit Service 0535c1
        if self._ctx.is_cancelled():
Packit Service 0535c1
            self._activation_clean_up()
Packit Service 0535c1
            return
Packit Service 0535c1
        action = user_data
Packit Service 0535c1
Packit Service 0535c1
        try:
Packit Service 0535c1
            nm_act_con = src_object.activate_connection_finish(result)
Packit Service 0535c1
        except Exception as e:
Packit Service 0535c1
            self._ctx.fail(NmstateLibnmError(f"{action} failed: error={e}"))
Packit Service 0535c1
            return
Packit Service 0535c1
Packit Service 0535c1
        if nm_act_con is None:
Packit Service 0535c1
            self._ctx.fail(
Packit Service 0535c1
                NmstateLibnmError(
Packit Service 0535c1
                    f"{action} failed: "
Packit Service 0535c1
                    "error='None return from activate_connection_finish()'"
Packit Service 0535c1
                )
Packit Service 0535c1
            )
Packit Service 0535c1
        else:
Packit Service 0535c1
            devname = self.devname
Packit Service 0535c1
            logging.debug(
Packit Service 0535c1
                "Connection activation initiated: dev=%s, con-state=%s",
Packit Service 0535c1
                devname,
Packit Service 0535c1
                nm_act_con.props.state,
Packit Service 0535c1
            )
Packit Service 0535c1
            self._nm_ac = nm_act_con
Packit Service 0535c1
            self._nm_dev = self._ctx.get_nm_dev(devname)
Packit Service 0535c1
Packit Service 0535c1
            if is_activated(self._nm_ac, self._nm_dev):
Packit Service 0535c1
                self._ctx.finish_async(action)
Packit Service 0535c1
            elif self._is_activating():
Packit Service 0535c1
                self._wait_ac_activation(action)
Packit Service 0535c1
                if self._nm_dev:
Packit Service 0535c1
                    self.wait_dev_activation(action)
Packit Service 0535c1
            else:
Packit Service 0535c1
                if self._nm_dev:
Packit Service 0535c1
                    error_msg = (
Packit Service 0535c1
                        f"Connection {self.profile.get_id()} failed: "
Packit Service 0535c1
                        f"state={self._nm_ac.get_state()} "
Packit Service 0535c1
                        f"reason={self._nm_ac.get_state_reason()} "
Packit Service 0535c1
                        f"dev_state={self._nm_dev.get_state()} "
Packit Service 0535c1
                        f"dev_reason={self._nm_dev.get_state_reason()}"
Packit Service 0535c1
                    )
Packit Service 0535c1
                else:
Packit Service 0535c1
                    error_msg = (
Packit Service 0535c1
                        f"Connection {self.profile.get_id()} failed: "
Packit Service 0535c1
                        f"state={self._nm_ac.get_state()} "
Packit Service 0535c1
                        f"reason={self._nm_ac.get_state_reason()} dev=None"
Packit Service 0535c1
                    )
Packit Service 0535c1
                logging.error(error_msg)
Packit Service 0535c1
                self._ctx.fail(
Packit Service 0535c1
                    NmstateLibnmError(f"{action} failed: {error_msg}")
Packit Service 0535c1
                )
Packit Service 0535c1
Packit Service 0535c1
    def _wait_ac_activation(self, action):
Packit Service 0535c1
        self._ac_handlers.add(
Packit Service 0535c1
            self._nm_ac.connect(
Packit Service 0535c1
                "state-changed", self._ac_state_change_callback, action
Packit Service 0535c1
            )
Packit Service 0535c1
        )
Packit Service 0535c1
        self._ac_handlers.add(
Packit Service 0535c1
            self._nm_ac.connect(
Packit Service 0535c1
                "notify::state-flags",
Packit Service 0535c1
                self._ac_state_flags_change_callback,
Packit Service 0535c1
                action,
Packit Service 0535c1
            )
Packit Service 0535c1
        )
Packit Service 0535c1
Packit Service 0535c1
    def wait_dev_activation(self, action):
Packit Service 0535c1
        if self._nm_dev:
Packit Service 0535c1
            self._dev_handlers.add(
Packit Service 0535c1
                self._nm_dev.connect(
Packit Service 0535c1
                    "state-changed", self._dev_state_change_callback, action
Packit Service 0535c1
                )
Packit Service 0535c1
            )
Packit Service 0535c1
Packit Service 0535c1
    def _dev_state_change_callback(
Packit Service 0535c1
        self, _dev, _new_state, _old_state, _reason, action,
Packit Service 0535c1
    ):
Packit Service 0535c1
        if self._ctx.is_cancelled():
Packit Service 0535c1
            self._activation_clean_up()
Packit Service 0535c1
            return
Packit Service 0535c1
        self._activation_progress_check(action)
Packit Service 0535c1
Packit Service 0535c1
    def _ac_state_flags_change_callback(self, _nm_act_con, _state, action):
Packit Service 0535c1
        if self._ctx.is_cancelled():
Packit Service 0535c1
            self._activation_clean_up()
Packit Service 0535c1
            return
Packit Service 0535c1
        self._activation_progress_check(action)
Packit Service 0535c1
Packit Service 0535c1
    def _ac_state_change_callback(self, _nm_act_con, _state, _reason, action):
Packit Service 0535c1
        if self._ctx.is_cancelled():
Packit Service 0535c1
            self._activation_clean_up()
Packit Service 0535c1
            return
Packit Service 0535c1
        self._activation_progress_check(action)
Packit Service 0535c1
Packit Service 0535c1
    def _activation_progress_check(self, action):
Packit Service 0535c1
        if self._ctx.is_cancelled():
Packit Service 0535c1
            self._activation_clean_up()
Packit Service 0535c1
            return
Packit Service 0535c1
        devname = self._nm_dev.get_iface()
Packit Service 0535c1
        cur_nm_dev = self._ctx.get_nm_dev(devname)
Packit Service 0535c1
        if cur_nm_dev and cur_nm_dev != self._nm_dev:
Packit Service 0535c1
            logging.debug(f"The NM.Device of profile {devname} changed")
Packit Service 0535c1
            self._remove_dev_handlers()
Packit Service 0535c1
            self._nm_dev = cur_nm_dev
Packit Service 0535c1
            self.wait_dev_activation(action)
Packit Service 0535c1
Packit Service 0535c1
        cur_nm_ac = get_device_active_connection(self.nmdevice)
Packit Service 0535c1
        if cur_nm_ac and cur_nm_ac != self._nm_ac:
Packit Service 0535c1
            logging.debug(
Packit Service 0535c1
                "Active connection of device {} has been replaced".format(
Packit Service 0535c1
                    self.devname
Packit Service 0535c1
                )
Packit Service 0535c1
            )
Packit Service 0535c1
            self._remove_ac_handlers()
Packit Service 0535c1
            self._nm_ac = cur_nm_ac
Packit Service 0535c1
            self._wait_ac_activation(action)
Packit Service 0535c1
        if is_activated(self._nm_ac, self._nm_dev):
Packit Service 0535c1
            logging.debug(
Packit Service 0535c1
                "Connection activation succeeded: dev=%s, con-state=%s, "
Packit Service 0535c1
                "dev-state=%s, state-flags=%s",
Packit Service 0535c1
                devname,
Packit Service 0535c1
                self._nm_ac.get_state(),
Packit Service 0535c1
                self._nm_dev.get_state(),
Packit Service 0535c1
                self._nm_ac.get_state_flags(),
Packit Service 0535c1
            )
Packit Service 0535c1
            self._activation_clean_up()
Packit Service 0535c1
            self._ctx.finish_async(action)
Packit Service 0535c1
        elif (
Packit Service 0535c1
            not self._is_activating()
Packit Service 0535c1
            and self._is_sriov_parameter_not_supported_by_driver()
Packit Service 0535c1
        ):
Packit Service 0535c1
            reason = (
Packit Service 0535c1
                f"The device={self.devname} does not support one or "
Packit Service 0535c1
                "more of the SR-IOV parameters set."
Packit Service 0535c1
            )
Packit Service 0535c1
            self._activation_clean_up()
Packit Service 0535c1
            self._ctx.fail(
Packit Service 0535c1
                NmstateValueError(f"{action} failed: reason={reason}")
Packit Service 0535c1
            )
Packit Service 0535c1
        elif not self._is_activating():
Packit Service 0535c1
            reason = f"{self._nm_ac.get_state_reason()}"
Packit Service 0535c1
            if self.nmdevice:
Packit Service 0535c1
                reason += f" {self.nmdevice.get_state_reason()}"
Packit Service 0535c1
            self._activation_clean_up()
Packit Service 0535c1
            self._ctx.fail(
Packit Service 0535c1
                NmstateLibnmError(f"{action} failed: reason={reason}")
Packit Service 0535c1
            )
Packit Service 0535c1
Packit Service 0535c1
    def _is_sriov_parameter_not_supported_by_driver(self):
Packit Service 0535c1
        return (
Packit Service 0535c1
            self.nmdevice
Packit Service 0535c1
            and self.nmdevice.props.state_reason
Packit Service 0535c1
            == NM.DeviceStateReason.SRIOV_CONFIGURATION_FAILED
Packit Service 0535c1
        )
Packit Service 0535c1
Packit Service 0535c1
    def _activation_clean_up(self):
Packit Service 0535c1
        self._remove_ac_handlers()
Packit Service 0535c1
        self._remove_dev_handlers()
Packit Service 0535c1
Packit Service 0535c1
    def _is_activating(self):
Packit Service 0535c1
        if not self._nm_ac or not self._nm_dev:
Packit Service 0535c1
            return True
Packit Service 0535c1
        if (
Packit Service 0535c1
            self._nm_dev.get_state_reason()
Packit Service 0535c1
            == NM.DeviceStateReason.NEW_ACTIVATION
Packit Service 0535c1
        ):
Packit Service 0535c1
            return True
Packit Service 0535c1
Packit Service 0535c1
        return (
Packit Service 0535c1
            self._nm_ac.get_state() == NM.ActiveConnectionState.ACTIVATING
Packit Service 0535c1
        ) and not is_activated(self._nm_ac, self._nm_dev)
Packit Service 0535c1
Packit Service 0535c1
    def _remove_dev_handlers(self):
Packit Service 0535c1
        for handler_id in self._dev_handlers:
Packit Service 0535c1
            self._nm_dev.handler_disconnect(handler_id)
Packit Service 0535c1
        self._dev_handlers = set()
Packit Service 0535c1
Packit Service 0535c1
    def _remove_ac_handlers(self):
Packit Service 0535c1
        for handler_id in self._ac_handlers:
Packit Service 0535c1
            self._nm_ac.handler_disconnect(handler_id)
Packit Service 0535c1
        self._ac_handlers = set()
Packit Service 0535c1
Packit Service 0535c1
    def _add_connection2_callback(self, src_object, result, user_data):
Packit Service 0535c1
        if self._ctx.is_cancelled():
Packit Service 0535c1
            return
Packit Service 0535c1
        action = user_data
Packit Service 0535c1
        try:
Packit Service 0535c1
            profile = src_object.add_connection2_finish(result)[0]
Packit Service 0535c1
        except Exception as e:
Packit Service 0535c1
            self._ctx.fail(
Packit Service 0535c1
                NmstateLibnmError(f"{action} failed with error: {e}")
Packit Service 0535c1
            )
Packit Service 0535c1
            return
Packit Service 0535c1
Packit Service 0535c1
        if profile is None:
Packit Service 0535c1
            self._ctx.fail(
Packit Service 0535c1
                NmstateLibnmError(
Packit Service 0535c1
                    f"{action} failed with error: 'None returned from "
Packit Service 0535c1
                    "add_connection2_finish()"
Packit Service 0535c1
                )
Packit Service 0535c1
            )
Packit Service 0535c1
        else:
Packit Service 0535c1
            self._ctx.finish_async(action)
Packit Service 0535c1
Packit Service 0535c1
    def _update2_callback(self, src_object, result, user_data):
Packit Service 0535c1
        if self._ctx.is_cancelled():
Packit Service 0535c1
            return
Packit Service 0535c1
        action = user_data
Packit Service 0535c1
        try:
Packit Service 0535c1
            ret = src_object.update2_finish(result)
Packit Service 0535c1
        except Exception as e:
Packit Service 0535c1
            self._ctx.fail(
Packit Service 0535c1
                NmstateLibnmError(f"{action} failed with error={e}")
Packit Service 0535c1
            )
Packit Service 0535c1
            return
Packit Service 0535c1
        if ret is None:
Packit Service 0535c1
            self._ctx.fail(
Packit Service 0535c1
                NmstateLibnmError(
Packit Service 0535c1
                    f"{action} failed with error='None returned from "
Packit Service 0535c1
                    "update2_finish()'"
Packit Service 0535c1
                )
Packit Service 0535c1
            )
Packit Service 0535c1
        else:
Packit Service 0535c1
            self._ctx.finish_async(action)
Packit Service 0535c1
Packit Service 0535c1
    def _delete_connection_callback(self, src_object, result, user_data):
Packit Service 0535c1
        if self._ctx.is_cancelled():
Packit Service 0535c1
            return
Packit Service 0535c1
        action = user_data
Packit Service 0535c1
        try:
Packit Service 0535c1
            success = src_object.delete_finish(result)
Packit Service 0535c1
        except Exception as e:
Packit Service 0535c1
            self._ctx.fail(NmstateLibnmError(f"{action} failed: error={e}"))
Packit Service 0535c1
            return
Packit Service 0535c1
Packit Service 0535c1
        if success:
Packit Service 0535c1
            self._ctx.finish_async(action)
Packit Service 0535c1
        else:
Packit Service 0535c1
            self._ctx.fail(
Packit Service 0535c1
                NmstateLibnmError(
Packit Service 0535c1
                    f"{action} failed: "
Packit Service 0535c1
                    "error='None returned from delete_finish()'"
Packit Service 0535c1
                )
Packit Service 0535c1
            )
Packit Service 0535c1
Packit Service 0535c1
    def _reset_profile(self):
Packit Service 0535c1
        self._con_profile = None
Packit Service 0535c1
Packit Service 0535c1
Packit Service 0535c1
class ConnectionSetting:
Packit Service 0535c1
    def __init__(self, con_setting=None):
Packit Service 0535c1
        self._setting = con_setting
Packit Service 0535c1
Packit Service 0535c1
    def create(self, con_name, iface_name, iface_type):
Packit Service 0535c1
        con_setting = NM.SettingConnection.new()
Packit Service 0535c1
        con_setting.props.id = con_name
Packit Service 0535c1
        con_setting.props.interface_name = iface_name
Packit Service 0535c1
        con_setting.props.uuid = str(uuid.uuid4())
Packit Service 0535c1
        con_setting.props.type = iface_type
Packit Service 0535c1
        con_setting.props.autoconnect = True
Packit Service 0535c1
        con_setting.props.autoconnect_slaves = (
Packit Service 0535c1
            NM.SettingConnectionAutoconnectSlaves.YES
Packit Service 0535c1
        )
Packit Service 0535c1
Packit Service 0535c1
        self._setting = con_setting
Packit Service 0535c1
Packit Service 0535c1
    def import_by_profile(self, con_profile):
Packit Service 0535c1
        base = con_profile.profile.get_setting_connection()
Packit Service 0535c1
        new = NM.SettingConnection.new()
Packit Service 0535c1
        new.props.id = base.props.id
Packit Service 0535c1
        new.props.interface_name = base.props.interface_name
Packit Service 0535c1
        new.props.uuid = base.props.uuid
Packit Service 0535c1
        new.props.type = base.props.type
Packit Service 0535c1
        new.props.autoconnect = True
Packit Service 0535c1
        new.props.autoconnect_slaves = base.props.autoconnect_slaves
Packit Service 0535c1
Packit Service 0535c1
        self._setting = new
Packit Service 0535c1
Packit Service 0535c1
    def set_master(self, master, slave_type):
Packit Service 0535c1
        if master is not None:
Packit Service 0535c1
            self._setting.props.master = master
Packit Service 0535c1
            self._setting.props.slave_type = slave_type
Packit Service 0535c1
Packit Service 0535c1
    def set_profile_name(self, con_name):
Packit Service 0535c1
        self._setting.props.id = con_name
Packit Service 0535c1
Packit Service 0535c1
    @property
Packit Service 0535c1
    def setting(self):
Packit Service 0535c1
        return self._setting
Packit Service 0535c1
Packit Service 0535c1
Packit Service 0535c1
def get_device_active_connection(nm_device):
Packit Service 0535c1
    active_conn = None
Packit Service 0535c1
    if nm_device:
Packit Service 0535c1
        active_conn = nm_device.get_active_connection()
Packit Service 0535c1
    return active_conn
Packit Service 0535c1
Packit Service 0535c1
Packit Service 1b5118
def delete_iface_profiles_except(context, ifname, excluded_profile):
Packit Service 0535c1
    for con in list_connections_by_ifname(context, ifname):
Packit Service 1b5118
        if (
Packit Service 1b5118
            not excluded_profile
Packit Service 1b5118
            or not con.profile
Packit Service 1b5118
            or con.profile.get_uuid() != excluded_profile.get_uuid()
Packit Service 1b5118
        ):
Packit Service 1b5118
            con.delete()
Packit Service 0535c1
Packit Service 0535c1
Packit Service 0535c1
def list_connections_by_ifname(context, ifname):
Packit Service 0535c1
    return [
Packit Service 0535c1
        ConnectionProfile(context, profile=con)
Packit Service 0535c1
        for con in context.client.get_connections()
Packit Service 0535c1
        if con.get_interface_name() == ifname
Packit Service 0535c1
    ]
Packit Service 0535c1
Packit Service 0535c1
Packit Service 0535c1
def is_activated(nm_ac, nm_dev):
Packit Service 0535c1
    if not (nm_ac and nm_dev):
Packit Service 0535c1
        return False
Packit Service 0535c1
Packit Service 0535c1
    state = nm_ac.get_state()
Packit Service 0535c1
    if state == NM.ActiveConnectionState.ACTIVATED:
Packit Service 0535c1
        return True
Packit Service 0535c1
    elif state == NM.ActiveConnectionState.ACTIVATING:
Packit Service 0535c1
        ac_state_flags = nm_ac.get_state_flags()
Packit Service 0535c1
        nm_flags = NM.ActivationStateFlags
Packit Service 0535c1
        ip4_is_dynamic = ipv4.is_dynamic(nm_ac)
Packit Service 0535c1
        ip6_is_dynamic = ipv6.is_dynamic(nm_ac)
Packit Service 0535c1
        if (
Packit Service 0535c1
            ac_state_flags & nm_flags.IS_MASTER
Packit Service 0535c1
            or (ip4_is_dynamic and ac_state_flags & nm_flags.IP6_READY)
Packit Service 0535c1
            or (ip6_is_dynamic and ac_state_flags & nm_flags.IP4_READY)
Packit Service 0535c1
            or (ip4_is_dynamic and ip6_is_dynamic)
Packit Service 0535c1
        ):
Packit Service 0535c1
            # For interface meet any condition below will be
Packit Service 0535c1
            # treated as activated when reach IP_CONFIG state:
Packit Service 0535c1
            #   * Is master device.
Packit Service 0535c1
            #   * DHCPv4 enabled with IP6_READY flag.
Packit Service 0535c1
            #   * DHCPv6/Autoconf with IP4_READY flag.
Packit Service 0535c1
            #   * DHCPv4 enabled with DHCPv6/Autoconf enabled.
Packit Service 0535c1
            return (
Packit Service 0535c1
                NM.DeviceState.IP_CONFIG
Packit Service 0535c1
                <= nm_dev.get_state()
Packit Service 0535c1
                <= NM.DeviceState.ACTIVATED
Packit Service 0535c1
            )
Packit Service 0535c1
Packit Service 0535c1
    return False