Skip to content

Commit 6f345bb

Browse files
authored
Merge pull request #2286 from GNS3/release-v2.2.43
Release v2.2.43
2 parents 71d06ab + 89ec458 commit 6f345bb

15 files changed

+153
-77
lines changed

CHANGELOG

+10
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,15 @@
11
# Change Log
22

3+
## 2.2.43 19/09/2023
4+
5+
* Force English output for VBoxManage. Fixes #2266
6+
* Automatically add vboxnet and DHCP server if not present for VirtualBox GNS3 VM. Ref #2266
7+
* Fix issue with controller config saved before checking current version with previous one
8+
* Prevent X11 socket file to be modified by Docker container
9+
* Use the user data dir to store built-in appliances
10+
* Catch ConnectionResetError exception when client disconnects
11+
* Upgrade to PyQt 5.15.9 and pywin32
12+
313
## 2.2.42 09/08/2023
414

515
* Bundle web-ui v2.2.42

gns3server/appliances/open-media-vault.gns3a

+16
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@
2626
"kvm": "require"
2727
},
2828
"images": [
29+
{
30+
"filename": "openmediavault_6.5.0-amd64.iso",
31+
"version": "6.5.0",
32+
"md5sum": "aa40e5ca50748b139cba2f4ac704a72d",
33+
"filesize": 941621248,
34+
"download_url": "https://www.openmediavault.org/download.html",
35+
"direct_download_url": "https://sourceforge.net/projects/openmediavault/files/6.5.0/openmediavault_6.5.0-amd64.iso"
36+
},
2937
{
3038
"filename": "openmediavault_6.0.24-amd64.iso",
3139
"version": "6.0.24",
@@ -60,6 +68,14 @@
6068
}
6169
],
6270
"versions": [
71+
{
72+
"name": "6.5.0",
73+
"images": {
74+
"hda_disk_image": "empty30G.qcow2",
75+
"hdb_disk_image": "empty30G.qcow2",
76+
"cdrom_image": "openmediavault_6.5.0-amd64.iso"
77+
}
78+
},
6379
{
6480
"name": "6.0.24",
6581
"images": {

gns3server/appliances/vyos.gns3a

+4-22
Original file line numberDiff line numberDiff line change
@@ -59,32 +59,28 @@
5959
"version": "1.2.9-S1",
6060
"md5sum": "3fece6363f9766f862e26d292d0ed5a3",
6161
"filesize": 430964736,
62-
"download_url": "https://support.vyos.io/en/downloads/files/vyos-1-2-9-s1-generic-iso-image",
63-
"direct_download_url": "https://s3-us.vyos.io/1.2.9-S1/vyos-1.2.9-S1-amd64.iso"
62+
"download_url": "https://support.vyos.io/en/downloads/files/vyos-1-2-9-s1-generic-iso-image"
6463
},
6564
{
6665
"filename": "vyos-1.2.9-S1-10G-qemu.qcow2",
6766
"version": "1.2.9-S1-KVM",
6867
"md5sum": "0a70d78b80a3716d42487c02ef44f41f",
6968
"filesize": 426967040,
70-
"download_url": "https://support.vyos.io/en/downloads/files/vyos-1-2-9-s1-for-kvm",
71-
"direct_download_url": "https://s3-us.vyos.io/1.2.9-S1/vyos-1.2.9-S1-10G-qemu.qcow2"
69+
"download_url": "https://support.vyos.io/en/downloads/files/vyos-1-2-9-s1-for-kvm"
7270
},
7371
{
7472
"filename": "vyos-1.2.9-amd64.iso",
7573
"version": "1.2.9",
7674
"md5sum": "586be23b6256173e174c82d8f1f699a1",
7775
"filesize": 430964736,
78-
"download_url": "https://support.vyos.io/en/downloads/files/vyos-1-2-9-generic-iso-image",
79-
"direct_download_url": "https://s3-us.vyos.io/1.2.9/vyos-1.2.9-amd64.iso"
76+
"download_url": "https://support.vyos.io/en/downloads/files/vyos-1-2-9-generic-iso-image"
8077
},
8178
{
8279
"filename": "vyos-1.2.9-10G-qemu.qcow2",
8380
"version": "1.2.9-KVM",
8481
"md5sum": "76871c7b248c32f75177c419128257ac",
8582
"filesize": 427360256,
86-
"download_url": "https://support.vyos.io/en/downloads/files/vyos-1-2-9-10g-qemu-qcow2",
87-
"direct_download_url": "https://s3-us.vyos.io/1.2.9/vyos-1.2.9-10G-qemu.qcow2"
83+
"download_url": "https://support.vyos.io/en/downloads/files/vyos-1-2-9-10g-qemu-qcow2"
8884
},
8985
{
9086
"filename": "vyos-1.2.8-amd64.iso",
@@ -93,13 +89,6 @@
9389
"filesize": 429916160,
9490
"download_url": "https://support.vyos.io/en/downloads/files/vyos-1-2-8-generic-iso-image"
9591
},
96-
{
97-
"filename": "vyos-1.1.8-amd64.iso",
98-
"version": "1.1.8",
99-
"md5sum": "95a141d4b592b81c803cdf7e9b11d8ea",
100-
"filesize": 241172480,
101-
"direct_download_url": "https://s3-us.vyos.io/vyos-1.1.8-amd64.iso"
102-
},
10392
{
10493
"filename": "empty8G.qcow2",
10594
"version": "1.0",
@@ -170,13 +159,6 @@
170159
"hda_disk_image": "empty8G.qcow2",
171160
"cdrom_image": "vyos-1.2.8-amd64.iso"
172161
}
173-
},
174-
{
175-
"name": "1.1.8",
176-
"images": {
177-
"hda_disk_image": "empty8G.qcow2",
178-
"cdrom_image": "vyos-1.1.8-amd64.iso"
179-
}
180162
}
181163
]
182164
}

gns3server/appliances/windows-11-dev-env.gns3a

+15
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,14 @@
2929
"kvm": "require"
3030
},
3131
"images": [
32+
{
33+
"filename": "WinDev2308Eval-disk1.vmdk",
34+
"version": "2308",
35+
"md5sum": "6a9b4ed6d7481f7bbf8a054c797b1eee",
36+
"filesize": 24945341952,
37+
"download_url": "https://download.microsoft.com/download/7/1/3/7135f2ab-8528-49fc-9252-8d5d94c697ef/WinDev2308Eval.VMWare.zip",
38+
"compression": "zip"
39+
},
3240
{
3341
"filename": "WinDev2212Eval-disk1.vmdk",
3442
"version": "2212",
@@ -48,6 +56,13 @@
4856
}
4957
],
5058
"versions": [
59+
{
60+
"name": "2308",
61+
"images": {
62+
"bios_image": "OVMF-edk2-stable202305.fd",
63+
"hda_disk_image": "WinDev2308Eval-disk1.vmdk"
64+
}
65+
},
5166
{
5267
"name": "2212",
5368
"images": {

gns3server/compute/docker/docker_vm.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -406,7 +406,7 @@ async def create(self):
406406
await self._start_vnc()
407407
params["Env"].append("QT_GRAPHICSSYSTEM=native") # To fix a Qt issue: https://github.com/GNS3/gns3-server/issues/556
408408
params["Env"].append("DISPLAY=:{}".format(self._display))
409-
params["HostConfig"]["Binds"].append("/tmp/.X11-unix/:/tmp/.X11-unix/")
409+
params["HostConfig"]["Binds"].append("/tmp/.X11-unix/X{0}:/tmp/.X11-unix/X{0}:ro".format(self._display))
410410

411411
if self._extra_hosts:
412412
extra_hosts = self._format_extra_hosts(self._extra_hosts)

gns3server/compute/virtualbox/__init__.py

+8-1
Original file line numberDiff line numberDiff line change
@@ -109,9 +109,16 @@ async def execute(self, subcommand, args, timeout=60):
109109
command = [vboxmanage_path, "--nologo", subcommand]
110110
command.extend(args)
111111
command_string = " ".join(command)
112+
env = os.environ.copy()
113+
env["LANG"] = "en" # force english output because we rely on it to parse the output
112114
log.info("Executing VBoxManage with command: {}".format(command_string))
113115
try:
114-
process = await asyncio.create_subprocess_exec(*command, stdout=asyncio.subprocess.PIPE, stderr=asyncio.subprocess.PIPE)
116+
process = await asyncio.create_subprocess_exec(
117+
*command,
118+
stdout=asyncio.subprocess.PIPE,
119+
stderr=asyncio.subprocess.PIPE,
120+
env=env
121+
)
115122
except (OSError, subprocess.SubprocessError) as e:
116123
raise VirtualBoxError("Could not execute VBoxManage: {}".format(e))
117124

gns3server/controller/__init__.py

+24-24
Original file line numberDiff line numberDiff line change
@@ -191,29 +191,28 @@ def save(self):
191191
Save the controller configuration on disk
192192
"""
193193

194-
if self._config_loaded is False:
195-
return
196-
197-
controller_settings = {"computes": [],
198-
"templates": [],
199-
"gns3vm": self.gns3vm.__json__(),
200-
"iou_license": self._iou_license_settings,
201-
"appliances_etag": self._appliance_manager.appliances_etag,
202-
"version": __version__}
203-
204-
for template in self._template_manager.templates.values():
205-
if not template.builtin:
206-
controller_settings["templates"].append(template.__json__())
194+
controller_settings = dict()
195+
if self._config_loaded:
196+
controller_settings = {"computes": [],
197+
"templates": [],
198+
"gns3vm": self.gns3vm.__json__(),
199+
"iou_license": self._iou_license_settings,
200+
"appliances_etag": self._appliance_manager.appliances_etag,
201+
"version": __version__}
202+
203+
for template in self._template_manager.templates.values():
204+
if not template.builtin:
205+
controller_settings["templates"].append(template.__json__())
207206

208-
for compute in self._computes.values():
209-
if compute.id != "local" and compute.id != "vm":
210-
controller_settings["computes"].append({"host": compute.host,
211-
"name": compute.name,
212-
"port": compute.port,
213-
"protocol": compute.protocol,
214-
"user": compute.user,
215-
"password": compute.password,
216-
"compute_id": compute.id})
207+
for compute in self._computes.values():
208+
if compute.id != "local" and compute.id != "vm":
209+
controller_settings["computes"].append({"host": compute.host,
210+
"name": compute.name,
211+
"port": compute.port,
212+
"protocol": compute.protocol,
213+
"user": compute.user,
214+
"password": compute.password,
215+
"compute_id": compute.id})
217216

218217
try:
219218
os.makedirs(os.path.dirname(self._config_file), exist_ok=True)
@@ -229,8 +228,7 @@ def _load_controller_settings(self):
229228

230229
try:
231230
if not os.path.exists(self._config_file):
232-
self._config_loaded = True
233-
self.save()
231+
self.save() # this will create the config file
234232
with open(self._config_file) as f:
235233
controller_settings = json.load(f)
236234
except (OSError, ValueError) as e:
@@ -255,6 +253,8 @@ def _load_controller_settings(self):
255253
if not previous_version or \
256254
parse_version(__version__.split("+")[0]) > parse_version(previous_version.split("+")[0]):
257255
self._appliance_manager.install_builtin_appliances()
256+
elif not os.listdir(self._appliance_manager.builtin_appliances_path()):
257+
self._appliance_manager.install_builtin_appliances()
258258

259259
self._appliance_manager.appliances_etag = controller_settings.get("appliances_etag")
260260
self._appliance_manager.load_appliances()

gns3server/controller/appliance_manager.py

+7-6
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import asyncio
2222
import aiohttp
2323
import shutil
24+
import platformdirs
2425

2526

2627
try:
@@ -81,13 +82,13 @@ def _custom_appliances_path(self):
8182
os.makedirs(appliances_path, exist_ok=True)
8283
return appliances_path
8384

84-
def _builtin_appliances_path(self, delete_first=False):
85+
def builtin_appliances_path(self, delete_first=False):
8586
"""
8687
Get the built-in appliance storage directory
8788
"""
8889

89-
config = Config.instance()
90-
appliances_dir = os.path.join(config.config_dir, "appliances")
90+
appname = vendor = "GNS3"
91+
appliances_dir = os.path.join(platformdirs.user_data_dir(appname, vendor, roaming=True), "appliances")
9192
if delete_first:
9293
shutil.rmtree(appliances_dir, ignore_errors=True)
9394
os.makedirs(appliances_dir, exist_ok=True)
@@ -98,7 +99,7 @@ def install_builtin_appliances(self):
9899
At startup we copy the built-in appliances files.
99100
"""
100101

101-
dst_path = self._builtin_appliances_path(delete_first=True)
102+
dst_path = self.builtin_appliances_path(delete_first=True)
102103
log.info(f"Installing built-in appliances in '{dst_path}'")
103104
from . import Controller
104105
try:
@@ -112,7 +113,7 @@ def load_appliances(self, symbol_theme="Classic"):
112113
"""
113114

114115
self._appliances = {}
115-
for directory, builtin in ((self._builtin_appliances_path(), True,), (self._custom_appliances_path(), False,)):
116+
for directory, builtin in ((self.builtin_appliances_path(), True,), (self._custom_appliances_path(), False,)):
116117
if directory and os.path.isdir(directory):
117118
for file in os.listdir(directory):
118119
if not file.endswith('.gns3a') and not file.endswith('.gns3appliance'):
@@ -215,7 +216,7 @@ async def download_appliances(self):
215216
from . import Controller
216217
Controller.instance().save()
217218
json_data = await response.json()
218-
appliances_dir = self._builtin_appliances_path()
219+
appliances_dir = self.builtin_appliances_path()
219220
downloaded_appliance_files = []
220221
for appliance in json_data:
221222
if appliance["type"] == "file":

0 commit comments

Comments
 (0)