mirror of
https://github.com/GNS3/gns3-server.git
synced 2026-08-27 12:30:13 +03:00
Merge branch '2.2' into 3.1
# Conflicts: # CHANGELOG # conf/gns3_server.conf # gns3server/compute/docker/__init__.py # gns3server/compute/docker/docker_vm.py # gns3server/compute/qemu/qemu_vm.py # gns3server/controller/import_project.py # gns3server/crash_report.py # gns3server/version.py
This commit is contained in:
commit
7487ec14e0
14
CHANGELOG
14
CHANGELOG
@ -1,5 +1,19 @@
|
||||
# Change Log
|
||||
|
||||
## 2.2.60 15/07/2026
|
||||
|
||||
* Sync appliances
|
||||
* Only set IOU images to be executable when importing images
|
||||
* fix(import): project import does not move images symlinks into place
|
||||
* Search for system UEFI that is compatible with Python < 3.12
|
||||
* Add OVMF firmware directory configuration
|
||||
* Automatically add a Random Number Generator (RNG) device when using uefi option is enabled
|
||||
* fix(docker): handle container name conflict automatically
|
||||
* fix: gns3-server crashes on startup if "Open this project in the background" is active but there is a problem with that project
|
||||
* Handle HTTPNotFound exception when retrieving compute status
|
||||
* Fix: Check compute connectivity before open() during project deletion
|
||||
* API endpoints to manage base configuration files for templates
|
||||
|
||||
## 3.1.0a4 09/07/2026
|
||||
|
||||
* Bundle web-ui v3.1.0a4
|
||||
|
||||
@ -14,7 +14,7 @@
|
||||
"symbol": "linux_guest.svg",
|
||||
"docker": {
|
||||
"adapters": 1,
|
||||
"image": "gns3/ubuntu:noble",
|
||||
"image": "gns3/ubuntu:resolute",
|
||||
"console_type": "telnet"
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,7 +34,8 @@ import json
|
||||
import shlex
|
||||
import psutil
|
||||
|
||||
from gns3server.utils import parse_version
|
||||
from pathlib import Path
|
||||
from gns3server.utils import parse_version, shlex_quote
|
||||
from gns3server.utils.asyncio import subprocess_check_output, cancellable_wait_run_in_executor
|
||||
from .qemu_error import QemuError
|
||||
from .utils.qcow2 import Qcow2, Qcow2Error
|
||||
@ -2292,15 +2293,23 @@ class QemuVM(BaseNode):
|
||||
options.extend(["-bios", self._bios_image.replace(",", ",,")])
|
||||
|
||||
elif self._uefi:
|
||||
|
||||
ovmf_firmware_dir = self._manager.config.get_section_config("Qemu").get("ovmf_firmware_dir", "/usr/share/OVMF")
|
||||
system_ovmf_firmware_dir = Path(ovmf_firmware_dir)
|
||||
log.info("Using OVMF firmware directory: {}".format(system_ovmf_firmware_dir))
|
||||
old_ovmf_vars_path = os.path.join(self.working_dir, "OVMF_VARS.fd")
|
||||
if os.path.exists(old_ovmf_vars_path):
|
||||
# the node has its own UEFI variables store already, we must also use the old UEFI firmware
|
||||
ovmf_firmware_path = self.manager.get_abs_image_path("OVMF_CODE.fd")
|
||||
else:
|
||||
system_ovmf_firmware_path = "/usr/share/OVMF/OVMF_CODE_4M.fd"
|
||||
if os.path.exists(system_ovmf_firmware_path):
|
||||
ovmf_firmware_path = system_ovmf_firmware_path
|
||||
# Use a manual case-insensitive search instead
|
||||
try:
|
||||
system_ovmf_firmware_path = next((f for f in system_ovmf_firmware_dir.glob("*.fd")
|
||||
if f.name.lower() == "ovmf_code_4m.fd"), None)
|
||||
except (FileNotFoundError, StopIteration):
|
||||
system_ovmf_firmware_path = None
|
||||
|
||||
if system_ovmf_firmware_path:
|
||||
ovmf_firmware_path = str(system_ovmf_firmware_path)
|
||||
else:
|
||||
# otherwise, get the UEFI firmware from the images directory
|
||||
ovmf_firmware_path = self.manager.get_abs_image_path("OVMF_CODE_4M.fd")
|
||||
@ -2309,9 +2318,13 @@ class QemuVM(BaseNode):
|
||||
options.extend(["-drive", "if=pflash,format=raw,readonly,file={}".format(ovmf_firmware_path)])
|
||||
|
||||
# try to use the UEFI variables store from the system first
|
||||
system_ovmf_vars_path = "/usr/share/OVMF/OVMF_VARS_4M.fd"
|
||||
if os.path.exists(system_ovmf_vars_path):
|
||||
ovmf_vars_path = system_ovmf_vars_path
|
||||
try:
|
||||
system_ovmf_vars_path = next((f for f in system_ovmf_firmware_dir.glob("*.fd")
|
||||
if f.name.lower() == "ovmf_vars_4m.fd"), None)
|
||||
except (FileNotFoundError, StopIteration):
|
||||
system_ovmf_vars_path = None
|
||||
if system_ovmf_vars_path:
|
||||
ovmf_vars_path = str(system_ovmf_vars_path)
|
||||
else:
|
||||
# otherwise, get the UEFI variables store from the images directory
|
||||
ovmf_vars_path = self.manager.get_abs_image_path("OVMF_VARS_4M.fd")
|
||||
@ -2327,6 +2340,10 @@ class QemuVM(BaseNode):
|
||||
except OSError as e:
|
||||
raise QemuError("Cannot copy OVMF_VARS_4M.fd file to the node working directory: {}".format(e))
|
||||
options.extend(["-drive", "if=pflash,format=raw,file={}".format(ovmf_vars_node_path)])
|
||||
|
||||
# edk2 firmware requires a Random Number Generator (RNG) device in order to turn network adapters on
|
||||
options.extend(["-object", "rng-random,filename=/dev/urandom,id=rng0 "])
|
||||
options.extend(["-device", "virtio-rng-pci,rng=rng0"])
|
||||
return options
|
||||
|
||||
def _linux_boot_options(self):
|
||||
|
||||
@ -295,14 +295,19 @@ async def _import_images(controller, images_path):
|
||||
for (dirpath, dirnames, filenames) in os.walk(root, followlinks=False):
|
||||
for filename in filenames:
|
||||
path = os.path.join(dirpath, filename)
|
||||
if os.path.islink(path):
|
||||
continue
|
||||
dst = os.path.join(image_dir, os.path.relpath(path, root))
|
||||
os.makedirs(os.path.dirname(dst), exist_ok=True)
|
||||
if not os.path.exists(dst):
|
||||
await wait_run_in_executor(shutil.move, path, dst)
|
||||
os.chmod(dst, stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC)
|
||||
|
||||
try:
|
||||
with open(dst, "rb") as f:
|
||||
# read the first 7 bytes of the file.
|
||||
elf_header_start = f.read(7)
|
||||
# IOU images must start with the ELF magic number, be 32-bit or 64-bit, little endian and have an ELF version of 1
|
||||
if elf_header_start == b'\x7fELF\x01\x01\x01' or elf_header_start == b'\x7fELF\x02\x01\x01':
|
||||
os.chmod(dst, stat.S_IWRITE | stat.S_IREAD | stat.S_IEXEC)
|
||||
except OSError as e:
|
||||
continue
|
||||
|
||||
async def update_snapshots(snapshots_dir, project_path, project_name, project_id, reset_mac_addresses=True):
|
||||
"""
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user