Blame libnmstate/netapplier.py

Packit b9ca78
#
Packit b9ca78
# Copyright (c) 2018-2020 Red Hat, Inc.
Packit b9ca78
#
Packit b9ca78
# This file is part of nmstate
Packit b9ca78
#
Packit b9ca78
# This program is free software: you can redistribute it and/or modify
Packit b9ca78
# it under the terms of the GNU Lesser General Public License as published by
Packit b9ca78
# the Free Software Foundation, either version 2.1 of the License, or
Packit b9ca78
# (at your option) any later version.
Packit b9ca78
#
Packit b9ca78
# This program is distributed in the hope that it will be useful,
Packit b9ca78
# but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit b9ca78
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit b9ca78
# GNU Lesser General Public License for more details.
Packit b9ca78
#
Packit b9ca78
# You should have received a copy of the GNU Lesser General Public License
Packit b9ca78
# along with this program. If not, see <https://www.gnu.org/licenses/>.
Packit b9ca78
#
Packit b9ca78
Packit b9ca78
import copy
Packit b9ca78
import time
Packit b9ca78
Packit b9ca78
Packit b9ca78
from libnmstate import validator
Packit b9ca78
from libnmstate.error import NmstateVerificationError
Packit b9ca78
Packit b9ca78
from .nmstate import create_checkpoints
Packit b9ca78
from .nmstate import destroy_checkpoints
Packit b9ca78
from .nmstate import plugin_context
Packit b9ca78
from .nmstate import plugins_capabilities
Packit b9ca78
from .nmstate import rollback_checkpoints
Packit b9ca78
from .nmstate import show_with_plugins
Packit b9ca78
from .net_state import NetState
Packit b9ca78
Packit b9ca78
MAINLOOP_TIMEOUT = 35
Packit b9ca78
VERIFY_RETRY_INTERNAL = 1
Packit b9ca78
VERIFY_RETRY_TIMEOUT = 5
Packit b9ca78
Packit b9ca78
Packit b9ca78
def apply(
Packit b9ca78
    desired_state,
Packit b9ca78
    *,
Packit b9ca78
    verify_change=True,
Packit b9ca78
    commit=True,
Packit b9ca78
    rollback_timeout=60,
Packit b9ca78
    save_to_disk=True,
Packit b9ca78
):
Packit b9ca78
    """
Packit b9ca78
    Apply the desired state
Packit b9ca78
Packit b9ca78
    :param verify_change: Check if the outcome state matches the desired state
Packit b9ca78
        and rollback if not.
Packit b9ca78
    :param commit: Commit the changes after verification if the state matches.
Packit b9ca78
    :param rollback_timeout: Revert the changes if they are not commited within
Packit b9ca78
        this timeout (specified in seconds).
Packit b9ca78
    :type verify_change: bool
Packit b9ca78
    :type commit: bool
Packit b9ca78
    :type rollback_timeout: int (seconds)
Packit b9ca78
    :returns: Checkpoint identifier
Packit b9ca78
    :rtype: str
Packit b9ca78
    """
Packit b9ca78
    desired_state = copy.deepcopy(desired_state)
Packit b9ca78
    with plugin_context() as plugins:
Packit b9ca78
        validator.schema_validate(desired_state)
Packit b9ca78
        current_state = show_with_plugins(plugins, include_status_data=True)
Packit b9ca78
        validator.validate_capabilities(
Packit b9ca78
            desired_state, plugins_capabilities(plugins)
Packit b9ca78
        )
Packit b9ca78
        net_state = NetState(desired_state, current_state, save_to_disk)
Packit b9ca78
        checkpoints = create_checkpoints(plugins, rollback_timeout)
Packit b9ca78
        _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk)
Packit b9ca78
        if commit:
Packit b9ca78
            destroy_checkpoints(plugins, checkpoints)
Packit b9ca78
        else:
Packit b9ca78
            return checkpoints
Packit b9ca78
Packit b9ca78
Packit b9ca78
def commit(*, checkpoint=None):
Packit b9ca78
    """
Packit b9ca78
    Commit a checkpoint that was received from `apply()`.
Packit b9ca78
Packit b9ca78
    :param checkpoint: Checkpoint to commit. If not specified, a checkpoint
Packit b9ca78
        will be selected and committed.
Packit b9ca78
    :type checkpoint: str
Packit b9ca78
    """
Packit b9ca78
    with plugin_context() as plugins:
Packit b9ca78
        destroy_checkpoints(plugins, checkpoint)
Packit b9ca78
Packit b9ca78
Packit b9ca78
def rollback(*, checkpoint=None):
Packit b9ca78
    """
Packit b9ca78
    Roll back a checkpoint that was received from `apply()`.
Packit b9ca78
Packit b9ca78
    :param checkpoint: Checkpoint to roll back. If not specified, a checkpoint
Packit b9ca78
        will be selected and rolled back.
Packit b9ca78
    :type checkpoint: str
Packit b9ca78
    """
Packit b9ca78
    with plugin_context() as plugins:
Packit b9ca78
        rollback_checkpoints(plugins, checkpoint)
Packit b9ca78
Packit b9ca78
Packit b9ca78
def _apply_ifaces_state(plugins, net_state, verify_change, save_to_disk):
Packit b9ca78
    for plugin in plugins:
Packit b9ca78
        plugin.apply_changes(net_state, save_to_disk)
Packit b9ca78
    verified = False
Packit b9ca78
    if verify_change:
Packit b9ca78
        for _ in range(VERIFY_RETRY_TIMEOUT):
Packit b9ca78
            try:
Packit b9ca78
                _verify_change(plugins, net_state)
Packit b9ca78
                verified = True
Packit b9ca78
                break
Packit b9ca78
            except NmstateVerificationError:
Packit b9ca78
                time.sleep(VERIFY_RETRY_INTERNAL)
Packit b9ca78
        if not verified:
Packit b9ca78
            _verify_change(plugins, net_state)
Packit b9ca78
Packit b9ca78
Packit b9ca78
def _verify_change(plugins, net_state):
Packit b9ca78
    current_state = show_with_plugins(plugins)
Packit b9ca78
    net_state.verify(current_state)