mirror of
https://github.com/GNS3/gns3-server
synced 2024-11-28 11:18:11 +00:00
Use the project working directory for VPCS VM
This commit is contained in:
parent
f5ed9fbcf1
commit
db41076ce5
@ -1,8 +1,8 @@
|
|||||||
curl -i -X POST 'http://localhost:8000/project' -d '{"location": "/private/var/folders/3s/r2wbv07n7wg4vrsn874lmxxh0000gn/T/pytest-308/test_create_project_with_dir0"}'
|
curl -i -X POST 'http://localhost:8000/project' -d '{"location": "/private/var/folders/3s/r2wbv07n7wg4vrsn874lmxxh0000gn/T/pytest-321/test_create_project_with_dir0"}'
|
||||||
|
|
||||||
POST /project HTTP/1.1
|
POST /project HTTP/1.1
|
||||||
{
|
{
|
||||||
"location": "/private/var/folders/3s/r2wbv07n7wg4vrsn874lmxxh0000gn/T/pytest-308/test_create_project_with_dir0"
|
"location": "/private/var/folders/3s/r2wbv07n7wg4vrsn874lmxxh0000gn/T/pytest-321/test_create_project_with_dir0"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -15,6 +15,6 @@ SERVER: Python/3.4 aiohttp/0.13.1
|
|||||||
X-ROUTE: /project
|
X-ROUTE: /project
|
||||||
|
|
||||||
{
|
{
|
||||||
"location": "/private/var/folders/3s/r2wbv07n7wg4vrsn874lmxxh0000gn/T/pytest-308/test_create_project_with_dir0",
|
"location": "/private/var/folders/3s/r2wbv07n7wg4vrsn874lmxxh0000gn/T/pytest-321/test_create_project_with_dir0",
|
||||||
"uuid": "7b9efb50-4909-4dc2-bb61-0bf443874c4c"
|
"uuid": "a00bbbdf-4088-4634-816d-513e0428275f"
|
||||||
}
|
}
|
||||||
|
@ -118,7 +118,7 @@ class Config(object):
|
|||||||
:returns: configparser section
|
:returns: configparser section
|
||||||
"""
|
"""
|
||||||
|
|
||||||
if section is not in self._config:
|
if section not in self._config:
|
||||||
return self._config["DEFAULT"]
|
return self._config["DEFAULT"]
|
||||||
return self._config[section]
|
return self._config[section]
|
||||||
|
|
||||||
|
@ -33,11 +33,13 @@ class BaseVM:
|
|||||||
|
|
||||||
# TODO: When delete release console ports
|
# TODO: When delete release console ports
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def project(self):
|
def project(self):
|
||||||
"""Return VM current project"""
|
"""Return VM current project"""
|
||||||
return self._project
|
return self._project
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def name(self):
|
def name(self):
|
||||||
"""
|
"""
|
||||||
@ -48,6 +50,7 @@ class BaseVM:
|
|||||||
|
|
||||||
return self._name
|
return self._name
|
||||||
|
|
||||||
|
|
||||||
@name.setter
|
@name.setter
|
||||||
def name(self, new_name):
|
def name(self, new_name):
|
||||||
"""
|
"""
|
||||||
@ -58,6 +61,7 @@ class BaseVM:
|
|||||||
|
|
||||||
self._name = new_name
|
self._name = new_name
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def uuid(self):
|
def uuid(self):
|
||||||
"""
|
"""
|
||||||
@ -68,6 +72,7 @@ class BaseVM:
|
|||||||
|
|
||||||
return self._uuid
|
return self._uuid
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def manager(self):
|
def manager(self):
|
||||||
"""
|
"""
|
||||||
@ -78,6 +83,16 @@ class BaseVM:
|
|||||||
|
|
||||||
return self._manager
|
return self._manager
|
||||||
|
|
||||||
|
|
||||||
|
@property
|
||||||
|
def working_dir(self):
|
||||||
|
"""
|
||||||
|
Return VM working directory
|
||||||
|
"""
|
||||||
|
|
||||||
|
return self._project.vm_working_directory(self._uuid)
|
||||||
|
|
||||||
|
|
||||||
def create(self):
|
def create(self):
|
||||||
"""
|
"""
|
||||||
Creates the VM.
|
Creates the VM.
|
||||||
@ -85,6 +100,7 @@ class BaseVM:
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
"""
|
"""
|
||||||
Starts the VM process.
|
Starts the VM process.
|
||||||
@ -92,6 +108,7 @@ class BaseVM:
|
|||||||
|
|
||||||
raise NotImplementedError
|
raise NotImplementedError
|
||||||
|
|
||||||
|
|
||||||
def stop(self):
|
def stop(self):
|
||||||
"""
|
"""
|
||||||
Starts the VM process.
|
Starts the VM process.
|
||||||
|
@ -45,23 +45,41 @@ class Project:
|
|||||||
self._path = os.path.join(self._location, self._uuid)
|
self._path = os.path.join(self._location, self._uuid)
|
||||||
if os.path.exists(self._path) is False:
|
if os.path.exists(self._path) is False:
|
||||||
os.mkdir(self._path)
|
os.mkdir(self._path)
|
||||||
os.mkdir(os.path.join(self._path, "files"))
|
os.mkdir(os.path.join(self._path, "vms"))
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def uuid(self):
|
def uuid(self):
|
||||||
|
|
||||||
return self._uuid
|
return self._uuid
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def location(self):
|
def location(self):
|
||||||
|
|
||||||
return self._location
|
return self._location
|
||||||
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self):
|
def path(self):
|
||||||
|
|
||||||
return self._path
|
return self._path
|
||||||
|
|
||||||
|
|
||||||
|
def vm_working_directory(self, vm_identifier):
|
||||||
|
"""
|
||||||
|
Return a working directory for a specific VM.
|
||||||
|
If the directory doesn't exist, the directory is created.
|
||||||
|
|
||||||
|
:param vm_identifier: UUID of VM
|
||||||
|
"""
|
||||||
|
|
||||||
|
path = os.path.join(self._path, 'vms', vm_identifier)
|
||||||
|
if os.path.exists(path) is False:
|
||||||
|
os.mkdir(path)
|
||||||
|
return path
|
||||||
|
|
||||||
|
|
||||||
def __json__(self):
|
def __json__(self):
|
||||||
|
|
||||||
return {
|
return {
|
||||||
|
@ -51,11 +51,10 @@ class VPCSVM(BaseVM):
|
|||||||
:param uuid: VPCS instance UUID
|
:param uuid: VPCS instance UUID
|
||||||
:param project: Project instance
|
:param project: Project instance
|
||||||
:param manager: parent VM Manager
|
:param manager: parent VM Manager
|
||||||
:param working_dir: path to a working directory
|
|
||||||
:param console: TCP console port
|
:param console: TCP console port
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def __init__(self, name, uuid, project, manager, working_dir=None, console=None):
|
def __init__(self, name, uuid, project, manager, console=None):
|
||||||
|
|
||||||
super().__init__(name, uuid, project, manager)
|
super().__init__(name, uuid, project, manager)
|
||||||
|
|
||||||
@ -63,9 +62,6 @@ class VPCSVM(BaseVM):
|
|||||||
|
|
||||||
self._console = console
|
self._console = console
|
||||||
|
|
||||||
# TODO: remove working_dir
|
|
||||||
self._working_dir = "/tmp"
|
|
||||||
|
|
||||||
self._command = []
|
self._command = []
|
||||||
self._process = None
|
self._process = None
|
||||||
self._vpcs_stdout_file = ""
|
self._vpcs_stdout_file = ""
|
||||||
@ -75,14 +71,6 @@ class VPCSVM(BaseVM):
|
|||||||
self._script_file = ""
|
self._script_file = ""
|
||||||
self._ethernet_adapter = EthernetAdapter() # one adapter with 1 Ethernet interface
|
self._ethernet_adapter = EthernetAdapter() # one adapter with 1 Ethernet interface
|
||||||
|
|
||||||
# working_dir_path = os.path.join(working_dir, "vpcs", "pc-{}".format(self._id))
|
|
||||||
#
|
|
||||||
# if vpcs_id and not os.path.isdir(working_dir_path):
|
|
||||||
# raise VPCSError("Working directory {} doesn't exist".format(working_dir_path))
|
|
||||||
#
|
|
||||||
# # create the vm own working directory
|
|
||||||
# self.working_dir = working_dir_path
|
|
||||||
#
|
|
||||||
try:
|
try:
|
||||||
if not self._console:
|
if not self._console:
|
||||||
self._console = self._manager.port_manager.get_free_console_port()
|
self._console = self._manager.port_manager.get_free_console_port()
|
||||||
@ -133,7 +121,7 @@ class VPCSVM(BaseVM):
|
|||||||
|
|
||||||
if self._script_file:
|
if self._script_file:
|
||||||
# update the startup.vpc
|
# update the startup.vpc
|
||||||
config_path = os.path.join(self._working_dir, "startup.vpc")
|
config_path = os.path.join(self.working_dir, "startup.vpc")
|
||||||
if os.path.isfile(config_path):
|
if os.path.isfile(config_path):
|
||||||
try:
|
try:
|
||||||
with open(config_path, "r+", errors="replace") as f:
|
with open(config_path, "r+", errors="replace") as f:
|
||||||
@ -155,7 +143,7 @@ class VPCSVM(BaseVM):
|
|||||||
"""
|
"""
|
||||||
# TODO: should be async
|
# TODO: should be async
|
||||||
try:
|
try:
|
||||||
output = subprocess.check_output([self._path, "-v"], cwd=self._working_dir)
|
output = subprocess.check_output([self._path, "-v"], cwd=self.working_dir)
|
||||||
match = re.search("Welcome to Virtual PC Simulator, version ([0-9a-z\.]+)", output.decode("utf-8"))
|
match = re.search("Welcome to Virtual PC Simulator, version ([0-9a-z\.]+)", output.decode("utf-8"))
|
||||||
if match:
|
if match:
|
||||||
version = match.group(1)
|
version = match.group(1)
|
||||||
@ -179,7 +167,7 @@ class VPCSVM(BaseVM):
|
|||||||
self._command = self._build_command()
|
self._command = self._build_command()
|
||||||
try:
|
try:
|
||||||
log.info("starting VPCS: {}".format(self._command))
|
log.info("starting VPCS: {}".format(self._command))
|
||||||
self._vpcs_stdout_file = os.path.join(self._working_dir, "vpcs.log")
|
self._vpcs_stdout_file = os.path.join(self.working_dir, "vpcs.log")
|
||||||
log.info("logging to {}".format(self._vpcs_stdout_file))
|
log.info("logging to {}".format(self._vpcs_stdout_file))
|
||||||
flags = 0
|
flags = 0
|
||||||
if sys.platform.startswith("win32"):
|
if sys.platform.startswith("win32"):
|
||||||
@ -188,7 +176,7 @@ class VPCSVM(BaseVM):
|
|||||||
self._process = yield from asyncio.create_subprocess_exec(*self._command,
|
self._process = yield from asyncio.create_subprocess_exec(*self._command,
|
||||||
stdout=fd,
|
stdout=fd,
|
||||||
stderr=subprocess.STDOUT,
|
stderr=subprocess.STDOUT,
|
||||||
cwd=self._working_dir,
|
cwd=self.working_dir,
|
||||||
creationflags=flags)
|
creationflags=flags)
|
||||||
log.info("VPCS instance {} started PID={}".format(self.name, self._process.pid))
|
log.info("VPCS instance {} started PID={}".format(self.name, self._process.pid))
|
||||||
self._started = True
|
self._started = True
|
||||||
|
@ -32,7 +32,7 @@ def test_path(tmpdir):
|
|||||||
p = Project(location=str(tmpdir))
|
p = Project(location=str(tmpdir))
|
||||||
assert p.path == os.path.join(str(tmpdir), p.uuid)
|
assert p.path == os.path.join(str(tmpdir), p.uuid)
|
||||||
assert os.path.exists(os.path.join(str(tmpdir), p.uuid))
|
assert os.path.exists(os.path.join(str(tmpdir), p.uuid))
|
||||||
assert os.path.exists(os.path.join(str(tmpdir), p.uuid, 'files'))
|
assert os.path.exists(os.path.join(str(tmpdir), p.uuid, 'vms'))
|
||||||
|
|
||||||
|
|
||||||
def test_temporary_path():
|
def test_temporary_path():
|
||||||
@ -43,3 +43,11 @@ def test_temporary_path():
|
|||||||
def test_json(tmpdir):
|
def test_json(tmpdir):
|
||||||
p = Project()
|
p = Project()
|
||||||
assert p.__json__() == {"location": p.location, "uuid": p.uuid}
|
assert p.__json__() == {"location": p.location, "uuid": p.uuid}
|
||||||
|
|
||||||
|
|
||||||
|
def test_vm_working_directory(tmpdir):
|
||||||
|
p = Project(location=str(tmpdir))
|
||||||
|
assert os.path.exists(p.vm_working_directory('00010203-0405-0607-0809-0a0b0c0d0e0f'))
|
||||||
|
assert os.path.exists(os.path.join(str(tmpdir), p.uuid, 'vms', '00010203-0405-0607-0809-0a0b0c0d0e0f'))
|
||||||
|
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ def manager():
|
|||||||
|
|
||||||
|
|
||||||
@patch("subprocess.check_output", return_value="Welcome to Virtual PC Simulator, version 0.6".encode("utf-8"))
|
@patch("subprocess.check_output", return_value="Welcome to Virtual PC Simulator, version 0.6".encode("utf-8"))
|
||||||
def test_vm(manager):
|
def test_vm(project, manager):
|
||||||
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
|
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
|
||||||
assert vm.name == "test"
|
assert vm.name == "test"
|
||||||
assert vm.uuid == "00010203-0405-0607-0809-0a0b0c0d0e0f"
|
assert vm.uuid == "00010203-0405-0607-0809-0a0b0c0d0e0f"
|
||||||
@ -81,20 +81,20 @@ def test_stop(project, loop, manager):
|
|||||||
process.terminate.assert_called_with()
|
process.terminate.assert_called_with()
|
||||||
|
|
||||||
|
|
||||||
def test_add_nio_binding_udp(manager):
|
def test_add_nio_binding_udp(manager, project):
|
||||||
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
|
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
|
||||||
nio = vm.port_add_nio_binding(0, {"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
|
nio = vm.port_add_nio_binding(0, {"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
|
||||||
assert nio.lport == 4242
|
assert nio.lport == 4242
|
||||||
|
|
||||||
|
|
||||||
def test_add_nio_binding_tap(project, manager):
|
def test_add_nio_binding_tap(project, manager):
|
||||||
vm = VPCSVM("test", 42, project, manager)
|
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
|
||||||
with patch("gns3server.modules.vpcs.vpcs_vm.has_privileged_access", return_value=True):
|
with patch("gns3server.modules.vpcs.vpcs_vm.has_privileged_access", return_value=True):
|
||||||
nio = vm.port_add_nio_binding(0, {"type": "nio_tap", "tap_device": "test"})
|
nio = vm.port_add_nio_binding(0, {"type": "nio_tap", "tap_device": "test"})
|
||||||
assert nio.tap_device == "test"
|
assert nio.tap_device == "test"
|
||||||
|
|
||||||
|
|
||||||
def test_add_nio_binding_tap_no_privileged_access(manager):
|
def test_add_nio_binding_tap_no_privileged_access(manager, project):
|
||||||
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
|
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
|
||||||
with patch("gns3server.modules.vpcs.vpcs_vm.has_privileged_access", return_value=False):
|
with patch("gns3server.modules.vpcs.vpcs_vm.has_privileged_access", return_value=False):
|
||||||
with pytest.raises(VPCSError):
|
with pytest.raises(VPCSError):
|
||||||
@ -102,7 +102,7 @@ def test_add_nio_binding_tap_no_privileged_access(manager):
|
|||||||
assert vm._ethernet_adapter.ports[0] is None
|
assert vm._ethernet_adapter.ports[0] is None
|
||||||
|
|
||||||
|
|
||||||
def test_port_remove_nio_binding(manager):
|
def test_port_remove_nio_binding(manager, project):
|
||||||
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
|
vm = VPCSVM("test", "00010203-0405-0607-0809-0a0b0c0d0e0f", project, manager)
|
||||||
nio = vm.port_add_nio_binding(0, {"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
|
nio = vm.port_add_nio_binding(0, {"type": "nio_udp", "lport": 4242, "rport": 4243, "rhost": "127.0.0.1"})
|
||||||
vm.port_remove_nio_binding(0)
|
vm.port_remove_nio_binding(0)
|
||||||
|
Loading…
Reference in New Issue
Block a user