mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-10-23 19:32:24 +03:00
Merge branch '3.1' into mypy-compute-qemu-vm
This commit is contained in:
commit
8c0a5404ac
@ -36,7 +36,7 @@ async def root():
|
|||||||
@router.get("/debug", response_class=HTMLResponse, deprecated=True, include_in_schema=False)
|
@router.get("/debug", response_class=HTMLResponse, deprecated=True, include_in_schema=False)
|
||||||
def debug(request: Request):
|
def debug(request: Request):
|
||||||
|
|
||||||
kwargs = {"gns3_version": __version__, "gns3_host": request.client.host}
|
kwargs = {"gns3_version": __version__, "gns3_host": request.client.host if request.client else None}
|
||||||
return templates.TemplateResponse(request=request, name="index.html", context=kwargs)
|
return templates.TemplateResponse(request=request, name="index.html", context=kwargs)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@ -227,7 +227,11 @@ class DockerVM(BaseNode):
|
|||||||
return display
|
return display
|
||||||
display += 1
|
display += 1
|
||||||
|
|
||||||
@BaseNode.name.setter
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@name.setter
|
||||||
def name(self, new_name):
|
def name(self, new_name):
|
||||||
"""
|
"""
|
||||||
Sets the name of this Qemu VM.
|
Sets the name of this Qemu VM.
|
||||||
@ -737,13 +741,15 @@ class DockerVM(BaseNode):
|
|||||||
params["Env"].append("{}={}".format(var_name, formatted))
|
params["Env"].append("{}={}".format(var_name, formatted))
|
||||||
|
|
||||||
if self._environment:
|
if self._environment:
|
||||||
for e in self._environment.strip().split("\n"):
|
for env in self._environment.strip().split("\n"):
|
||||||
e = e.strip()
|
env = env.strip()
|
||||||
if e.split("=")[0] == "":
|
if env.split("=")[0] == "":
|
||||||
self.project.emit("log.warning", {"message": f"{self.name} has invalid environment variable: {e}"})
|
self.project.emit(
|
||||||
|
"log.warning", {"message": f"{self.name} has invalid environment variable: {env}"}
|
||||||
|
)
|
||||||
continue
|
continue
|
||||||
if not e.startswith("GNS3_"):
|
if not env.startswith("GNS3_"):
|
||||||
formatted = self._format_env(variables, e)
|
formatted = self._format_env(variables, env)
|
||||||
vm_name = self._name.replace(",", ",,")
|
vm_name = self._name.replace(",", ",,")
|
||||||
project_path = self.project.path.replace(",", ",,")
|
project_path = self.project.path.replace(",", ",,")
|
||||||
formatted = formatted.replace("%vm-name%", '"' + vm_name.replace('"', '\\"') + '"')
|
formatted = formatted.replace("%vm-name%", '"' + vm_name.replace('"', '\\"') + '"')
|
||||||
|
|||||||
@ -92,8 +92,8 @@ class IOLDockerVM(VendorDockerVM):
|
|||||||
# controller-allocated application id (MACs would flip to the fallback
|
# controller-allocated application id (MACs would flip to the fallback
|
||||||
# hash, colliding with the allocation pool) and any pending
|
# hash, colliding with the allocation pool) and any pending
|
||||||
# startup-config delivered by a PUT.
|
# startup-config delivered by a PUT.
|
||||||
_application_id = None
|
_application_id: int | None = None
|
||||||
_startup_config_content = None
|
_startup_config_content: str | None = None
|
||||||
_startup_config_dirty = False
|
_startup_config_dirty = False
|
||||||
|
|
||||||
def _parse_vendor_environment(self):
|
def _parse_vendor_environment(self):
|
||||||
@ -119,7 +119,7 @@ class IOLDockerVM(VendorDockerVM):
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def application_id(self) -> int:
|
def application_id(self) -> int | None:
|
||||||
"""
|
"""
|
||||||
IOL application ID: drives interface MACs (aabb.cc{app}{iface}) and
|
IOL application ID: drives interface MACs (aabb.cc{app}{iface}) and
|
||||||
the NVRAM file name. Allocated by the controller from the IOL Docker
|
the NVRAM file name. Allocated by the controller from the IOL Docker
|
||||||
@ -178,6 +178,8 @@ class IOLDockerVM(VendorDockerVM):
|
|||||||
initial configuration dialog.
|
initial configuration dialog.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if self._startup_config_content is None:
|
||||||
|
return
|
||||||
content = self._startup_config_content.replace("%h", self._name)
|
content = self._startup_config_content.replace("%h", self._name)
|
||||||
nvram_file = self._iol_nvram_file()
|
nvram_file = self._iol_nvram_file()
|
||||||
os.makedirs(os.path.dirname(nvram_file), exist_ok=True)
|
os.makedirs(os.path.dirname(nvram_file), exist_ok=True)
|
||||||
@ -189,7 +191,11 @@ class IOLDockerVM(VendorDockerVM):
|
|||||||
raise DockerError(f"Could not write IOL startup-config to NVRAM of container '{self._name}': {e}")
|
raise DockerError(f"Could not write IOL startup-config to NVRAM of container '{self._name}': {e}")
|
||||||
log.debug("IOL container '%s': startup-config written to %s", self._name, nvram_file)
|
log.debug("IOL container '%s': startup-config written to %s", self._name, nvram_file)
|
||||||
|
|
||||||
@DockerVM.name.setter
|
@property
|
||||||
|
def name(self):
|
||||||
|
return self._name
|
||||||
|
|
||||||
|
@name.setter
|
||||||
def name(self, new_name):
|
def name(self, new_name):
|
||||||
"""
|
"""
|
||||||
Override: keep the hostname line inside the NVRAM in sync with the
|
Override: keep the hostname line inside the NVRAM in sync with the
|
||||||
@ -228,7 +234,11 @@ class IOLDockerVM(VendorDockerVM):
|
|||||||
result["startup_config_content"] = self._startup_config_content
|
result["startup_config_content"] = self._startup_config_content
|
||||||
return result
|
return result
|
||||||
|
|
||||||
@DockerVM.adapters.setter
|
@property
|
||||||
|
def adapters(self):
|
||||||
|
return len(self._ethernet_adapters)
|
||||||
|
|
||||||
|
@adapters.setter
|
||||||
def adapters(self, adapters):
|
def adapters(self, adapters):
|
||||||
"""
|
"""
|
||||||
Override: one IOL adapter is a 4-port unit — the IOU model. The
|
Override: one IOL adapter is a 4-port unit — the IOU model. The
|
||||||
|
|||||||
@ -466,7 +466,7 @@ class Project:
|
|||||||
)
|
)
|
||||||
|
|
||||||
# Non-recursive: list only the current directory level
|
# Non-recursive: list only the current directory level
|
||||||
files = []
|
files: list[dict] = []
|
||||||
try:
|
try:
|
||||||
scandir_iter = os.scandir(target_path)
|
scandir_iter = os.scandir(target_path)
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
|
|||||||
@ -952,7 +952,11 @@ class VMwareVM(BaseNode):
|
|||||||
await self._stop_remote_console()
|
await self._stop_remote_console()
|
||||||
await self._start_console()
|
await self._start_console()
|
||||||
|
|
||||||
@BaseNode.console_type.setter
|
@property
|
||||||
|
def console_type(self):
|
||||||
|
return self._console_type
|
||||||
|
|
||||||
|
@console_type.setter
|
||||||
def console_type(self, new_console_type):
|
def console_type(self, new_console_type):
|
||||||
"""
|
"""
|
||||||
Sets the console type for this VMware VM.
|
Sets the console type for this VMware VM.
|
||||||
|
|||||||
@ -48,6 +48,10 @@ class ConfigConflictError(Exception):
|
|||||||
LIST_OPTION_SEPARATORS = {"additional_images_paths": ";"}
|
LIST_OPTION_SEPARATORS = {"additional_images_paths": ";"}
|
||||||
|
|
||||||
|
|
||||||
|
def parser_sections(parser: configparser.ConfigParser) -> dict[str, dict[str, str]]:
|
||||||
|
return {section: dict(parser[section]) for section in parser.sections()}
|
||||||
|
|
||||||
|
|
||||||
class Config:
|
class Config:
|
||||||
"""
|
"""
|
||||||
Configuration file management using configparser.
|
Configuration file management using configparser.
|
||||||
@ -328,7 +332,7 @@ class Config:
|
|||||||
changed.append(f"{section}.{option}")
|
changed.append(f"{section}.{option}")
|
||||||
|
|
||||||
# validate the merged settings before touching the file on disk
|
# validate the merged settings before touching the file on disk
|
||||||
ServerConfig(**merged_parser._sections)
|
ServerConfig(**parser_sections(merged_parser))
|
||||||
|
|
||||||
directory_name = os.path.dirname(main_config_file)
|
directory_name = os.path.dirname(main_config_file)
|
||||||
if directory_name:
|
if directory_name:
|
||||||
@ -414,7 +418,7 @@ class Config:
|
|||||||
self._watched_files[file] = os.stat(file).st_mtime
|
self._watched_files[file] = os.stat(file).st_mtime
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self._settings = ServerConfig(**config._sections)
|
self._settings = ServerConfig(**parser_sections(config))
|
||||||
except ValidationError as e:
|
except ValidationError as e:
|
||||||
log.critical(f"Could not validate configuration file settings: {e}")
|
log.critical(f"Could not validate configuration file settings: {e}")
|
||||||
raise
|
raise
|
||||||
|
|||||||
@ -216,6 +216,13 @@ class Compute:
|
|||||||
"""
|
"""
|
||||||
return self._host
|
return self._host
|
||||||
|
|
||||||
|
@host.setter
|
||||||
|
def host(self, host):
|
||||||
|
self._host = host
|
||||||
|
self._host_ip_cache = None # invalidate; re-resolve on next access
|
||||||
|
if self._console_host is None:
|
||||||
|
self._console_host = host
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def host_ip(self):
|
def host_ip(self):
|
||||||
"""
|
"""
|
||||||
@ -228,13 +235,6 @@ class Compute:
|
|||||||
self._host_ip_cache = "0.0.0.0"
|
self._host_ip_cache = "0.0.0.0"
|
||||||
return self._host_ip_cache
|
return self._host_ip_cache
|
||||||
|
|
||||||
@host.setter
|
|
||||||
def host(self, host):
|
|
||||||
self._host = host
|
|
||||||
self._host_ip_cache = None # invalidate; re-resolve on next access
|
|
||||||
if self._console_host is None:
|
|
||||||
self._console_host = host
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def console_host(self):
|
def console_host(self):
|
||||||
return self._console_host
|
return self._console_host
|
||||||
|
|||||||
@ -236,12 +236,11 @@ class ShellConnection(TelnetConnection):
|
|||||||
async def disconnected(self):
|
async def disconnected(self):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@asyncio.coroutine
|
async def window_size_changed(self, columns, rows):
|
||||||
def window_size_changed(self, columns, rows):
|
|
||||||
self._size = Size(rows=rows, columns=columns)
|
self._size = Size(rows=rows, columns=columns)
|
||||||
self._cb.terminal_size_changed()
|
self._cb.terminal_size_changed()
|
||||||
if self._window_size_changed_callback:
|
if self._window_size_changed_callback:
|
||||||
yield from self._window_size_changed_callback(columns, rows)
|
await self._window_size_changed_callback(columns, rows)
|
||||||
|
|
||||||
async def feed(self, data):
|
async def feed(self, data):
|
||||||
data = data.decode()
|
data = data.decode()
|
||||||
|
|||||||
@ -359,22 +359,17 @@ module = [
|
|||||||
"gns3server.api.routes.controller.snapshots", # 1
|
"gns3server.api.routes.controller.snapshots", # 1
|
||||||
"gns3server.api.routes.controller.templates", # 10
|
"gns3server.api.routes.controller.templates", # 10
|
||||||
"gns3server.api.routes.controller.users", # 14
|
"gns3server.api.routes.controller.users", # 14
|
||||||
"gns3server.api.routes.index", # 1
|
|
||||||
"gns3server.api.server", # 2
|
"gns3server.api.server", # 2
|
||||||
"gns3server.compute.docker.docker_vm", # 3
|
|
||||||
"gns3server.compute.docker.iol_docker_vm", # 3
|
|
||||||
"gns3server.compute.dynamips.nodes.router", # 2
|
"gns3server.compute.dynamips.nodes.router", # 2
|
||||||
"gns3server.compute.iou.iou_vm", # 4
|
"gns3server.compute.iou.iou_vm", # 4
|
||||||
"gns3server.compute.iou.utils.iou_export", # 2
|
"gns3server.compute.iou.utils.iou_export", # 2
|
||||||
"gns3server.compute.iou.utils.iou_import", # 2
|
"gns3server.compute.iou.utils.iou_import", # 2
|
||||||
"gns3server.compute.project", # 1
|
"gns3server.compute.project", # 1
|
||||||
|
"gns3server.compute.qemu.qemu_vm", # 2
|
||||||
"gns3server.compute.virtualbox.virtualbox_vm", # 1
|
"gns3server.compute.virtualbox.virtualbox_vm", # 1
|
||||||
"gns3server.compute.vmware.vmware_vm", # 1
|
|
||||||
"gns3server.compute.vpcs.vpcs_vm", # 2
|
"gns3server.compute.vpcs.vpcs_vm", # 2
|
||||||
"gns3server.config", # 1
|
|
||||||
"gns3server.controller.appliance", # 2
|
"gns3server.controller.appliance", # 2
|
||||||
"gns3server.controller.appliance_manager", # 5
|
"gns3server.controller.appliance_manager", # 5
|
||||||
"gns3server.controller.compute", # 2
|
|
||||||
"gns3server.controller.project", # 2
|
"gns3server.controller.project", # 2
|
||||||
"gns3server.controller.topology", # 1
|
"gns3server.controller.topology", # 1
|
||||||
"gns3server.db.models.acl", # 1
|
"gns3server.db.models.acl", # 1
|
||||||
@ -420,7 +415,6 @@ module = [
|
|||||||
"gns3server.services.computes", # 4
|
"gns3server.services.computes", # 4
|
||||||
"gns3server.services.templates", # 18
|
"gns3server.services.templates", # 18
|
||||||
"gns3server.utils.asyncio.aiozipstream", # 8
|
"gns3server.utils.asyncio.aiozipstream", # 8
|
||||||
"gns3server.utils.asyncio.embed_shell", # 1
|
|
||||||
"gns3server.utils.encryption", # 2
|
"gns3server.utils.encryption", # 2
|
||||||
"gns3server.utils.http_client", # 4
|
"gns3server.utils.http_client", # 4
|
||||||
"gns3server.utils.images", # 4
|
"gns3server.utils.images", # 4
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user