This commit is contained in:
grossmj 2018-08-25 14:10:47 +07:00
parent ad9b6f42bf
commit 902de3dd47
12 changed files with 57 additions and 42 deletions

View File

@ -29,7 +29,7 @@ import re
from gns3server.utils.interfaces import interfaces
from ..compute.port_manager import PortManager
from ..utils.asyncio import wait_run_in_executor, locked_coroutine
from ..utils.asyncio import wait_run_in_executor, locking
from ..utils.asyncio.telnet_server import AsyncioTelnetServer
from ..ubridge.hypervisor import Hypervisor
from ..ubridge.ubridge_error import UbridgeError
@ -516,7 +516,8 @@ class BaseNode:
except UbridgeError as e:
raise UbridgeError("Error while sending command '{}': {}: {}".format(command, e, self._ubridge_hypervisor.read_stdout()))
@locked_coroutine
@locking
@asyncio.coroutine
def _start_ubridge(self):
"""
Starts uBridge (handles connections to and from this node).

View File

@ -25,7 +25,7 @@ import asyncio
import logging
import aiohttp
from gns3server.utils import parse_version
from gns3server.utils.asyncio import locked_coroutine
from gns3server.utils.asyncio import locking
from gns3server.compute.base_manager import BaseManager
from gns3server.compute.docker.docker_vm import DockerVM
from gns3server.compute.docker.docker_error import DockerError, DockerHttp304Error, DockerHttp404Error
@ -182,7 +182,8 @@ class Docker(BaseManager):
autoping=True)
return connection
@locked_coroutine
@locking
@asyncio.coroutine
def pull_image(self, image, progress_callback=None):
"""
Pull image from docker repository

View File

@ -43,7 +43,7 @@ from .utils.iou_export import nvram_export
from gns3server.ubridge.ubridge_error import UbridgeError
from gns3server.utils.file_watcher import FileWatcher
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
from gns3server.utils.asyncio import locked_coroutine
from gns3server.utils.asyncio import locking
import gns3server.utils.asyncio
import gns3server.utils.images
@ -550,7 +550,8 @@ class IOUVM(BaseNode):
# configure networking support
yield from self._networking()
@locked_coroutine
@locking
@asyncio.coroutine
def _networking(self):
"""
Configures the IOL bridge in uBridge.

View File

@ -33,7 +33,7 @@ import xml.etree.ElementTree as ET
from gns3server.utils import parse_version
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
from gns3server.utils.asyncio.serial import asyncio_open_serial
from gns3server.utils.asyncio import locked_coroutine
from gns3server.utils.asyncio import locking
from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError
from gns3server.compute.nios.nio_udp import NIOUDP
from gns3server.compute.adapters.ethernet_adapter import EthernetAdapter
@ -296,7 +296,8 @@ class VirtualBoxVM(BaseNode):
if (yield from self.check_hw_virtualization()):
self._hw_virtualization = True
@locked_coroutine
@locking
@asyncio.coroutine
def stop(self):
"""
Stops this VirtualBox VM.

View File

@ -26,7 +26,7 @@ import tempfile
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
from gns3server.utils.asyncio.serial import asyncio_open_serial
from gns3server.utils.asyncio import locked_coroutine
from gns3server.utils.asyncio import locking
from collections import OrderedDict
from .vmware_error import VMwareError
from ..nios.nio_udp import NIOUDP
@ -94,7 +94,8 @@ class VMwareVM(BaseNode):
return self._vmnets
@locked_coroutine
@locking
@asyncio.coroutine
def _control_vm(self, subcommand, *additional_args):
args = [self._vmx_path]

View File

@ -27,7 +27,7 @@ from operator import itemgetter
from ..utils import parse_version
from ..utils.images import list_images
from ..utils.asyncio import locked_coroutine, asyncio_ensure_future
from ..utils.asyncio import locking, asyncio_ensure_future
from ..controller.controller_error import ControllerError
from ..version import __version__, __version_info__
@ -400,7 +400,8 @@ class Compute:
except aiohttp.web.HTTPConflict:
pass
@locked_coroutine
@locking
@asyncio.coroutine
def connect(self):
"""
Check if remote server is accessible

View File

@ -21,7 +21,7 @@ import asyncio
import aiohttp
import ipaddress
from ...utils.asyncio import locked_coroutine, asyncio_ensure_future
from ...utils.asyncio import locking, asyncio_ensure_future
from .vmware_gns3_vm import VMwareGNS3VM
from .virtualbox_gns3_vm import VirtualBoxGNS3VM
from .remote_gns3_vm import RemoteGNS3VM
@ -265,7 +265,8 @@ class GNS3VM:
except GNS3VMError as e:
log.warn(str(e))
@locked_coroutine
@locking
@asyncio.coroutine
def start(self):
"""
Start the GNS3 VM
@ -339,7 +340,8 @@ class GNS3VM:
except aiohttp.web.HTTPConflict as e:
log.warning("Could not check the VM is in the same subnet as the local server: {}".format(e.text))
@locked_coroutine
@locking
@asyncio.coroutine
def _suspend(self):
"""
Suspend the GNS3 VM
@ -351,7 +353,8 @@ class GNS3VM:
log.info("Suspend the GNS3 VM")
yield from engine.suspend()
@locked_coroutine
@locking
@asyncio.coroutine
def _stop(self):
"""
Stop the GNS3 VM

View File

@ -36,7 +36,7 @@ from .udp_link import UDPLink
from ..config import Config
from ..utils.path import check_path_allowed, get_default_project_directory
from ..utils.asyncio.pool import Pool
from ..utils.asyncio import locked_coroutine
from ..utils.asyncio import locking
from ..utils.asyncio import wait_run_in_executor
from ..utils.asyncio import asyncio_ensure_future
from .export_project import export_project
@ -525,7 +525,8 @@ class Project:
self.dump()
return node
@locked_coroutine
@locking
@asyncio.coroutine
def __delete_node_links(self, node):
"""
Delete all link connected to this node.
@ -783,7 +784,8 @@ class Project:
def _topology_file(self):
return os.path.join(self.path, self._filename)
@locked_coroutine
@locking
@asyncio.coroutine
def open(self):
"""
Load topology elements

View File

@ -20,7 +20,7 @@ import time
import logging
import asyncio
from ..utils.asyncio import locked_coroutine
from ..utils.asyncio import locking
from .ubridge_error import UbridgeError
log = logging.getLogger(__name__)
@ -176,7 +176,8 @@ class UBridgeHypervisor:
self._host = host
@locked_coroutine
@locking
@asyncio.coroutine
def send(self, command):
"""
Sends commands to this hypervisor.

View File

@ -138,26 +138,28 @@ def wait_for_named_pipe_creation(pipe_path, timeout=60):
return
raise asyncio.TimeoutError()
#FIXME: Use the following wrapper when we drop Python 3.4 and use the async def syntax
# def locking(f):
#
# @wraps(f)
# async def wrapper(oself, *args, **kwargs):
# lock_name = "__" + f.__name__ + "_lock"
# if not hasattr(oself, lock_name):
# setattr(oself, lock_name, asyncio.Lock())
# async with getattr(oself, lock_name):
# return await f(oself, *args, **kwargs)
# return wrapper
def locked_coroutine(f):
"""
Method decorator that replace asyncio.coroutine that warranty
that this specific method of this class instance will not we
executed twice at the same time
"""
@asyncio.coroutine
def new_function(*args, **kwargs):
def locking(f):
# In the instance of the class we will store
# a lock has an attribute.
lock_var_name = "__" + f.__name__ + "_lock"
if not hasattr(args[0], lock_var_name):
setattr(args[0], lock_var_name, asyncio.Lock())
with (yield from getattr(args[0], lock_var_name)):
return (yield from f(*args, **kwargs))
return new_function
@functools.wraps(f)
def wrapper(oself, *args, **kwargs):
lock_name = "__" + f.__name__ + "_lock"
if not hasattr(oself, lock_name):
setattr(oself, lock_name, asyncio.Lock())
with (yield from getattr(oself, lock_name)):
return (yield from f(oself, *args, **kwargs))
return wrapper
#FIXME: conservative approach to supported versions, please remove it when we drop the support to Python < 3.4.4
try:

View File

@ -104,7 +104,7 @@ def http_server(request, loop, port_manager, monkeypatch, controller):
monkeypatch.setattr('gns3server.compute.virtualbox.virtualbox_vm.VirtualBoxVM.close', lambda self: True)
loop.run_until_complete(instance.unload())
srv.close()
srv.wait_closed()
loop.run_until_complete(srv.wait_closed())
@pytest.fixture

View File

@ -21,7 +21,7 @@ import pytest
import sys
from unittest.mock import MagicMock
from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_output, wait_for_process_termination, locked_coroutine
from gns3server.utils.asyncio import wait_run_in_executor, subprocess_check_output, wait_for_process_termination, locking
from tests.utils import AsyncioMagicMock
@ -84,7 +84,8 @@ def test_lock_decorator(loop):
def __init__(self):
self._test_val = 0
@locked_coroutine
@locking
@asyncio.coroutine
def method_to_lock(self):
res = self._test_val
yield from asyncio.sleep(0.1)