gns3-server 3.0.2__py3-none-any.whl → 3.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of gns3-server might be problematic. Click here for more details.

@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: gns3-server
3
- Version: 3.0.2
3
+ Version: 3.0.3
4
4
  Summary: GNS3 graphical interface for the GNS3 server.
5
5
  Author-email: Jeremy Grossmann <developers@gns3.com>
6
6
  License: GNU GENERAL PUBLIC LICENSE
@@ -725,13 +725,13 @@ Requires-Dist: platformdirs<3,>=2.4.0
725
725
  Requires-Dist: importlib-resources>=1.3; python_version <= "3.9"
726
726
  Requires-Dist: truststore>=0.10.0; python_version >= "3.10"
727
727
  Provides-Extra: dev
728
- Requires-Dist: pytest==8.3.3; extra == "dev"
728
+ Requires-Dist: pytest==8.3.4; extra == "dev"
729
729
  Requires-Dist: flake8==7.1.1; extra == "dev"
730
730
  Requires-Dist: pytest-timeout==2.3.1; extra == "dev"
731
- Requires-Dist: pytest-asyncio==0.21.2; extra == "dev"
731
+ Requires-Dist: pytest-asyncio==0.25.2; extra == "dev"
732
732
  Requires-Dist: requests==2.32.3; extra == "dev"
733
- Requires-Dist: httpx==0.27.2; extra == "dev"
734
- Requires-Dist: httpx_ws==0.6.2; extra == "dev"
733
+ Requires-Dist: httpx==0.28.1; extra == "dev"
734
+ Requires-Dist: httpx_ws==0.7.1; extra == "dev"
735
735
 
736
736
  # GNS3 server repository
737
737
 
@@ -2,11 +2,11 @@ gns3server/__init__.py,sha256=7t93V0ASczMyzTR7up2g0FBQ6Rm1eC8wxyysMKUeAKE,716
2
2
  gns3server/__main__.py,sha256=5CO8WDwpzZ2BRo3Ct95MhMGxyXQ3QsHBcWt3jPlcLb0,736
3
3
  gns3server/alembic.ini,sha256=XWHHdJ3QOHO3NJh5LK6bMHT6kv7GzAr26X1hs43DH4o,3086
4
4
  gns3server/config.py,sha256=3UmjwcthW-gMKbLEPzygzrEVJYza-H1IWRjJZ_L1-tg,9244
5
- gns3server/crash_report.py,sha256=WLpcAtoTZ_MFDuPpJo6L6MW0OqGjMTrIilSc7oditOE,6021
5
+ gns3server/crash_report.py,sha256=P0BmchoJI4xWYRtE81S3owlIDJHQtKAMS8FVEzkdCZM,6021
6
6
  gns3server/logger.py,sha256=zjHjyyqK74YMVPdjjznj03xWO42Kx3RDeVnZflT-0eI,5309
7
- gns3server/main.py,sha256=w16TCAYfTmdKsrCjm7rt4hlwsaMfLiWxw8598K4B3zA,2286
8
- gns3server/server.py,sha256=ZoqI8I1UI_gQgescnEiT0XFijJVo86vM3aowGLUOXHw,13362
9
- gns3server/version.py,sha256=QxUxoSMx508tXlMSHuEUDgxjrmPrqRyrX3VxGhKmlbE,1462
7
+ gns3server/main.py,sha256=_bLqv2j1TqgYjDFpSCs-6cUTjJ4_fWDQEFQdGKheIeE,4392
8
+ gns3server/server.py,sha256=KMwIfPvYNw0He5DSyenFuLvr7mlxZlS5azDXKQIVlms,11795
9
+ gns3server/version.py,sha256=3PAMFzRKLzMB1Esc-6vn50dgeeMGnInni-eVSFpYsc8,1462
10
10
  gns3server/api/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
11
  gns3server/api/server.py,sha256=LQAKxtBaVxylgVTqRpVhdwACdkaibDryOSUT2us5PUk,7972
12
12
  gns3server/api/routes/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -22,7 +22,7 @@ gns3server/api/routes/compute/ethernet_hub_nodes.py,sha256=-V2NmAroWZCwR0GqP2nAO
22
22
  gns3server/api/routes/compute/ethernet_switch_nodes.py,sha256=28-EOAb0ukocg3dyMptMg7Z3Nzjk4ZA2mhO5OA8cbfc,7975
23
23
  gns3server/api/routes/compute/frame_relay_switch_nodes.py,sha256=3N1qM-J0QnvB6YO-V2G6R7xReX96ZuP-PyR2htsLM-I,7709
24
24
  gns3server/api/routes/compute/images.py,sha256=6GkZgfDVF3agi7PvOOHVsd7ijUxu6xiQ-3Zc2Jfqlvs,4679
25
- gns3server/api/routes/compute/iou_nodes.py,sha256=BndYiH4MzOhP1EPmsifDqASBsI9i05J0IS01hKl_uzA,10518
25
+ gns3server/api/routes/compute/iou_nodes.py,sha256=0HyPzUJs7Yrh73j9oxiIz9x6OjQTJBYc0Fk-DosTxjI,10531
26
26
  gns3server/api/routes/compute/nat_nodes.py,sha256=WiXCr-mPMsbM3ZF9TDxS15OYm5jzsfPjirGYCeLWd3E,7472
27
27
  gns3server/api/routes/compute/notifications.py,sha256=klAacqbts6slBYDBcEGv_fUw1S9sXMQktdVHNDLBZHc,2993
28
28
  gns3server/api/routes/compute/projects.py,sha256=KhsKfy0zrqh4EDumQXuMf8EkYMENdLcA6Aaxnvhiy18,8107
@@ -61,6 +61,7 @@ gns3server/appliances/a10-vthunder.gns3a,sha256=TyEaFP2MagSKBvRFBWB5VD6wcYG4E-jt
61
61
  gns3server/appliances/aaa.gns3a,sha256=A0ZxwwR74BlNR28Fe-tyDCdGe5widI_CceIXrAqYmU4,785
62
62
  gns3server/appliances/alcatel-7750.gns3a,sha256=Sj1WcE--zdIWgf3-DQ-AFBTz41_p6UC9I9iZ3av6TaI,2775
63
63
  gns3server/appliances/almalinux.gns3a,sha256=F37VYRnx0twhNxibZsAN9BKjISl1zu-6hwjOTsWjh0Y,3642
64
+ gns3server/appliances/alpine-cloud.gns3a,sha256=V6ZQ1yiT7Ou03840aplPaWweeufmtcK3KzqpszQW_8s,2285
64
65
  gns3server/appliances/alpine-linux-virt.gns3a,sha256=0BDnDSVRIllXk6Tpuyk1G2vWv9uiwyaCmdd_vYyBK-g,2567
65
66
  gns3server/appliances/alpine-linux.gns3a,sha256=LZs8KQNJQtmpUn7uVOmLlb23kjQHc9Vbrhk-VzwT68o,810
66
67
  gns3server/appliances/arista-ceos.gns3a,sha256=_N88hNErMaD4Wt7AcL4EfGpaohsMhvXWqFkvgcgPeiE,2316
@@ -239,6 +240,7 @@ gns3server/appliances/sophos-iview.gns3a,sha256=5oTP_tQMgCRj-gwz0UyHTR5HSeOMLotu
239
240
  gns3server/appliances/sophos-utm.gns3a,sha256=QtvZ-WDRoAGQsPtP0SCFWMcNA64FkK_X32pUVWvk_Xk,9607
240
241
  gns3server/appliances/sophos-xg.gns3a,sha256=jlghrtfuFGVfFxXFbaYMSTJY3abs1RyuMtTYnj2vGnk,9488
241
242
  gns3server/appliances/stonework.gns3a,sha256=BlagJsXI6Ib_NarXAl7y5HRMaUC8_GriQ8ZGu8B556w,849
243
+ gns3server/appliances/stormshield-eva.gns3a,sha256=DyQN8kJdmvmSj-EXEG7nd-jYvQyENr2WxEF3rI7-TRU,2085
242
244
  gns3server/appliances/tacacs-gui.gns3a,sha256=j35G1eqLB3Krd1RQxpuQcUqsBEcLY2urWjNl0RHBDlo,2191
243
245
  gns3server/appliances/tinycore-linux.gns3a,sha256=ezaMlB_pGZzL52hlV_Yd2IxNNMEwJyd7YVyxP2rqLPc,2818
244
246
  gns3server/appliances/trendmicro-imsva.gns3a,sha256=APIe4SKcVIlaPEfe9ugtf4IP25qiAM69dy53OKodSks,2642
@@ -375,7 +377,7 @@ gns3server/compute/ubridge/ubridge_error.py,sha256=cyaHkJXstCd1RJCd5Z3xcmz9Gz8o9
375
377
  gns3server/compute/ubridge/ubridge_hypervisor.py,sha256=GpQPeqnyWUldr2RXz36N87g0K1XOUgTr-JkU4AB2Mwk,9215
376
378
  gns3server/compute/virtualbox/__init__.py,sha256=Ul6lAKxdKJNKXP_v4sHo_Kr53davcFnIH280ZDDhqKo,8014
377
379
  gns3server/compute/virtualbox/virtualbox_error.py,sha256=xiJkTmC6-dKylwEsm2zY1ptoojCyogaK2AIWhVSXFbU,813
378
- gns3server/compute/virtualbox/virtualbox_vm.py,sha256=HKPRJ24a2FV3jT7enn-U5t_tJNQK-u4Qtlg7PKewqXk,46886
380
+ gns3server/compute/virtualbox/virtualbox_vm.py,sha256=iEFfPU2dbWlsYNEHL0QnCIUyauxB-AiHu-iTuZaEfeQ,47143
379
381
  gns3server/compute/vmware/__init__.py,sha256=yu09nv0AqfmNPMKtU2XxrpAuxc8zhQBI-aQtqeIKcCo,29166
380
382
  gns3server/compute/vmware/vmware_error.py,sha256=2yJUpG2xTal5rkBbi1HJ8QmfIH9ipRrUjtVaIVEsxtc,805
381
383
  gns3server/compute/vmware/vmware_vm.py,sha256=WSEuEgtdrLDajGVsRRcgvaOzPepB_5ORrfFUx7rpYgo,35898
@@ -560,8 +562,8 @@ gns3server/static/web-ui/NotoSans-Regular.bb384defbe36eaec.svg,sha256=uECuQtpAPz
560
562
  gns3server/static/web-ui/NotoSans-Regular.e6139cb1663a1c57.ttf,sha256=NPyxxROGVf4PlLBl3aiZC8bvHIpeR0bbt37H7hWtNGI,512588
561
563
  gns3server/static/web-ui/ReleaseNotes.txt,sha256=uag7ABM-yXleLBxhtetbpVOCssZPXcd_lLMyUAdQsn4,5527
562
564
  gns3server/static/web-ui/favicon.ico,sha256=ucy7cQDhOulawYo6ntAIV_MhtjtJjx-3q6tQb8HEDpk,5430
563
- gns3server/static/web-ui/index.html,sha256=mear17OnyP8egGZXvsUmuuClEa01X_YIFZZbb5OBPDc,11546
564
- gns3server/static/web-ui/main.62c99707e4709a56.js,sha256=m0OxkO_z5Zosa-n7qxnT3OvXjtgMYCL348nJ4iZrpws,4319606
565
+ gns3server/static/web-ui/index.html,sha256=f6KgIQQ6ibSMrVOuCTqQSkV9ex13YKgQnpHnGscR1ao,11546
566
+ gns3server/static/web-ui/main.2e807eb4bc32f838.js,sha256=wQapR8yTeSICPR5T-gQZDZgR_8uaxWADeqBecwnTE-U,4319609
565
567
  gns3server/static/web-ui/polyfills.319c79dd175e50d0.js,sha256=sQPX0SyLyUHk_0gvODKsdL3-lQsQ_whJeMgxx6tO04A,38362
566
568
  gns3server/static/web-ui/roboto-latin-100.539f0a96b40596f7.woff2,sha256=EoI9WFYFI4EhVUr_i7BgojXcNvN-_Z-x5-bqGpYivDU,15808
567
569
  gns3server/static/web-ui/roboto-latin-100.5ba994dac3e79ea8.woff,sha256=xOrU3p96_yN9BrUw6thBPRNXQn9qkllENCu04rHc5tA,20368
@@ -1243,9 +1245,9 @@ gns3server/utils/asyncio/telnet_server.py,sha256=dteUIryUX25iRr5-dMkdBYSTNZQZfLK
1243
1245
  gns3server/utils/zipfile_zstd/__init__.py,sha256=QXfnwyxx_CDJdAgOzqqBAD_7WDudc9VN03U0Gfccr5I,163
1244
1246
  gns3server/utils/zipfile_zstd/_patcher.py,sha256=RCMj1y8OrIJheEGnuERDH0l2hvLaFl5wa_IZNiTpBbU,380
1245
1247
  gns3server/utils/zipfile_zstd/_zipfile.py,sha256=KvAeNmWZHu2LHuUOZ8_Tnu_dRi3NOIWM6I3hg_c7NsQ,2189
1246
- gns3_server-3.0.2.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
1247
- gns3_server-3.0.2.dist-info/METADATA,sha256=F5fxjfxloNsp52Ga_hxOtfUOYyQkBEV48WNwXadIMPk,48323
1248
- gns3_server-3.0.2.dist-info/WHEEL,sha256=PZUExdf71Ui_so67QXpySuHtCi3-J3wvF4ORK6k_S8U,91
1249
- gns3_server-3.0.2.dist-info/entry_points.txt,sha256=kgHc6rA0RfDOTAkTDSwgWXKHWG4r5mQ-SsmpCHNgXPI,92
1250
- gns3_server-3.0.2.dist-info/top_level.txt,sha256=GvKJnXIKLBmewtHjQXkvmtz79ZW51IsfCoPMbHoWehQ,11
1251
- gns3_server-3.0.2.dist-info/RECORD,,
1248
+ gns3_server-3.0.3.dist-info/LICENSE,sha256=jOtLnuWt7d5Hsx6XXB2QxzrSe2sWWh3NgMfFRetluQM,35147
1249
+ gns3_server-3.0.3.dist-info/METADATA,sha256=_V6rn5lk6NS_o5mfEpZ4thVMDOLbsU9YOwCz9_jpid8,48323
1250
+ gns3_server-3.0.3.dist-info/WHEEL,sha256=In9FTNxeP60KnTkGw7wk6mJPYd_dQSjEZmXdBdMCI-8,91
1251
+ gns3_server-3.0.3.dist-info/entry_points.txt,sha256=kgHc6rA0RfDOTAkTDSwgWXKHWG4r5mQ-SsmpCHNgXPI,92
1252
+ gns3_server-3.0.3.dist-info/top_level.txt,sha256=GvKJnXIKLBmewtHjQXkvmtz79ZW51IsfCoPMbHoWehQ,11
1253
+ gns3_server-3.0.3.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (75.6.0)
2
+ Generator: setuptools (75.8.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5
 
@@ -284,7 +284,7 @@ async def start_iou_node_capture(
284
284
  """
285
285
 
286
286
  pcap_file_path = os.path.join(node.project.capture_working_directory(), node_capture_data.capture_file_name)
287
- await node.start_capture(adapter_number, pcap_file_path)
287
+ await node.start_capture(adapter_number, port_number, pcap_file_path)
288
288
  return {"pcap_file_path": str(pcap_file_path)}
289
289
 
290
290
 
@@ -0,0 +1,56 @@
1
+ {
2
+ "appliance_id": "edbaa01e-2032-4ee2-bb9f-dd5c4d84c270",
3
+ "name": "Alpine Cloud Guest",
4
+ "category": "guest",
5
+ "description": "Alpine Linux is a security-oriented, lightweight Linux distribution based on musl libc and busybox.",
6
+ "vendor_name": "Alpine Linux Development Team",
7
+ "vendor_url": "http://alpinelinux.org",
8
+ "vendor_logo_url": "https://raw.githubusercontent.com/GNS3/gns3-registry/master/vendor-logos/Alpine Linux.png",
9
+ "documentation_url": "http://wiki.alpinelinux.org",
10
+ "product_name": "Alpine Linux",
11
+ "product_url": "https://www.alpinelinux.org/cloud/",
12
+ "registry_version": 4,
13
+ "status": "stable",
14
+ "maintainer": "GNS3 Team",
15
+ "maintainer_email": "developers@gns3.net",
16
+ "usage": "\nUsername: alpine\nPassword: alpine",
17
+ "port_name_format": "Ethernet{0}",
18
+ "qemu": {
19
+ "adapter_type": "virtio-net-pci",
20
+ "adapters": 1,
21
+ "ram": 1024,
22
+ "hda_disk_interface": "virtio",
23
+ "arch": "x86_64",
24
+ "console_type": "telnet",
25
+ "boot_priority": "c",
26
+ "kvm": "require",
27
+ "options": "-nographic"
28
+ },
29
+ "images": [
30
+ {
31
+ "filename": "generic_alpine-3.21.2-x86_64-bios-cloudinit-r0.qcow2",
32
+ "version": "3.21.2",
33
+ "md5sum": "b40825dff2867e0ffaffbc4c87674462",
34
+ "filesize": 189726720,
35
+ "download_url": "https://www.alpinelinux.org/cloud/",
36
+ "direct_download_url": "https://dl-cdn.alpinelinux.org/alpine/v3.21/releases/cloud/generic_alpine-3.21.2-x86_64-bios-cloudinit-r0.qcow2"
37
+ },
38
+ {
39
+ "filename": "alpine-cloud-init-data.iso",
40
+ "version": "1.0",
41
+ "md5sum": "b1b4b16cc3bf0250c0fa377c19c97683",
42
+ "filesize": 374784,
43
+ "download_url": "https://github.com/GNS3/gns3-registry/tree/master/cloud-init/alpine-cloud",
44
+ "direct_download_url": "https://github.com/GNS3/gns3-registry/raw/master/cloud-init/alpine-cloud/alpine-cloud-init-data.iso"
45
+ }
46
+ ],
47
+ "versions": [
48
+ {
49
+ "name": "3.21.2",
50
+ "images": {
51
+ "hda_disk_image": "generic_alpine-3.21.2-x86_64-bios-cloudinit-r0.qcow2",
52
+ "cdrom_image": "alpine-cloud-init-data.iso"
53
+ }
54
+ }
55
+ ]
56
+ }
@@ -0,0 +1,50 @@
1
+ {
2
+ "appliance_id": "60801097-332e-4f40-a63e-8ad62047c01f",
3
+ "name": "Stormshield EVA",
4
+ "category": "firewall",
5
+ "description": "Stormshield EVA (Elastic Virtual Appliance) is a french virtual firewall designed to protect network infrastructures. It offers advanced features such as filtering, intrusion prevention (IPS), VPN management (IPSec/SSL), and access control.",
6
+ "vendor_name": "Stormshield",
7
+ "vendor_url": "https://www.stormshield.com/",
8
+ "vendor_logo_url": "https://www.stormshield.com/wp-content/uploads/stormshield-logo.png",
9
+ "documentation_url": "https://www.stormshield.com/fr/ressourcescenter/network-security-elastic-virtual-appliances/",
10
+ "product_name": "Stormshield EVA",
11
+ "product_url": "https://www.stormshield.com/fr/produits-et-services/produits/protection-des-reseaux/nos-produits/appliances-virtuelles/",
12
+ "registry_version": 4,
13
+ "status": "stable",
14
+ "availability": "service-contract",
15
+ "maintainer": "Samy SCANNA",
16
+ "maintainer_email": "samy.scanna@outlook.com",
17
+ "usage": "After the first boot, the appliance automatically runs the configuration script to set up the password, and network interfaces.",
18
+ "symbol": "stormshield.png",
19
+ "port_name_format": "port{port1}",
20
+ "qemu": {
21
+ "adapter_type": "vmxnet3",
22
+ "adapters": 8,
23
+ "ram": 2048,
24
+ "cpus": 1,
25
+ "hda_disk_interface": "scsi",
26
+ "arch": "x86_64",
27
+ "console_type": "telnet",
28
+ "kvm": "allow",
29
+ "options": "-serial stdio",
30
+ "on_close": "shutdown_signal",
31
+ "process_priority": "normal"
32
+ },
33
+ "images": [
34
+ {
35
+ "filename": "utm-SNS-EVA-4.3.33-kvm.qcow2",
36
+ "version": "4.3.33",
37
+ "md5sum": "21d94d0e20f2e270f06c5853fd750d5b",
38
+ "filesize": 284360704,
39
+ "download_url": "https://mystormshield.eu/product/download/"
40
+ }
41
+ ],
42
+ "versions": [
43
+ {
44
+ "images": {
45
+ "hda_disk_image": "utm-SNS-EVA-4.3.33-kvm.qcow2"
46
+ },
47
+ "name": "4.3.33"
48
+ }
49
+ ]
50
+ }
@@ -233,32 +233,36 @@ class VirtualBoxVM(BaseNode):
233
233
  """
234
234
  Fix the VM uuid in the case of linked clone
235
235
  """
236
- if os.path.exists(self._linked_vbox_file()):
237
- try:
238
- tree = ET.parse(self._linked_vbox_file())
239
- except ET.ParseError:
240
- raise VirtualBoxError(
241
- "Cannot modify VirtualBox linked nodes file. "
242
- "File {} is corrupted.".format(self._linked_vbox_file())
236
+
237
+ linked_vbox_file = self._linked_vbox_file()
238
+ if not os.path.exists(linked_vbox_file):
239
+ raise VirtualBoxError("Cannot find VirtualBox linked node file: {}".format(linked_vbox_file))
240
+
241
+ try:
242
+ tree = ET.parse(linked_vbox_file)
243
+ except ET.ParseError:
244
+ raise VirtualBoxError(f"Cannot modify VirtualBox linked node file. "
245
+ "File {linked_vbox_file} is corrupted.")
246
+ except OSError as e:
247
+ raise VirtualBoxError(f"Cannot modify VirtualBox linked nodes file '{self._linked_vbox_file()}': {e}")
248
+
249
+ machine = tree.getroot().find("{http://www.virtualbox.org/}Machine")
250
+ if machine is not None and machine.get("uuid") != "{" + self.id + "}":
251
+
252
+ for image in tree.getroot().findall("{http://www.virtualbox.org/}Image"):
253
+ currentSnapshot = machine.get("currentSnapshot")
254
+ if currentSnapshot:
255
+ newSnapshot = re.sub(r"\{.*\}", "{" + str(uuid.uuid4()) + "}", currentSnapshot)
256
+ shutil.move(
257
+ os.path.join(self.working_dir, self._vmname, "Snapshots", currentSnapshot) + ".vdi",
258
+ os.path.join(self.working_dir, self._vmname, "Snapshots", newSnapshot) + ".vdi"
243
259
  )
244
- except OSError as e:
245
- raise VirtualBoxError(f"Cannot modify VirtualBox linked nodes file '{self._linked_vbox_file()}': {e}")
246
-
247
- machine = tree.getroot().find("{http://www.virtualbox.org/}Machine")
248
- if machine is not None and machine.get("uuid") != "{" + self.id + "}":
249
-
250
- for image in tree.getroot().findall("{http://www.virtualbox.org/}Image"):
251
- currentSnapshot = machine.get("currentSnapshot")
252
- if currentSnapshot:
253
- newSnapshot = re.sub(r"\{.*\}", "{" + str(uuid.uuid4()) + "}", currentSnapshot)
254
- shutil.move(
255
- os.path.join(self.working_dir, self._vmname, "Snapshots", currentSnapshot) + ".vdi",
256
- os.path.join(self.working_dir, self._vmname, "Snapshots", newSnapshot) + ".vdi",
257
- )
258
- image.set("uuid", newSnapshot)
260
+ log.info(f"VirtualBox VM '{self.name}' [{self.id}] snapshot file moved from '{currentSnapshot}' to '{newSnapshot}'")
261
+ image.set("uuid", newSnapshot)
259
262
 
260
- machine.set("uuid", "{" + self.id + "}")
261
- tree.write(self._linked_vbox_file())
263
+ log.info(f"VirtualBox VM '{self.name}' [{self.id}] '{linked_vbox_file}' has been patched")
264
+ machine.set("uuid", "{" + self.id + "}")
265
+ tree.write(linked_vbox_file)
262
266
 
263
267
  async def check_hw_virtualization(self):
264
268
  """
@@ -488,7 +492,7 @@ class VirtualBoxVM(BaseNode):
488
492
 
489
493
  async def save_linked_hdds_info(self):
490
494
  """
491
- Save linked cloned hard disks information.
495
+ Save linked cloned hard disk information.
492
496
 
493
497
  :returns: disk table information
494
498
  """
@@ -58,7 +58,7 @@ class CrashReport:
58
58
  Report crash to a third party service
59
59
  """
60
60
 
61
- DSN = "https://9cf53e6b9adfe49b867f1847b7cc4d72@o19455.ingest.us.sentry.io/38482"
61
+ DSN = "https://2c96fa0280f82c48108f122b87cd902c@o19455.ingest.us.sentry.io/38482"
62
62
  _instance = None
63
63
 
64
64
  def __init__(self):
gns3server/main.py CHANGED
@@ -30,6 +30,7 @@ import gns3server.utils.get_resource
30
30
  import os
31
31
  import sys
32
32
  import asyncio
33
+ import argparse
33
34
 
34
35
 
35
36
  def daemonize():
@@ -59,6 +60,42 @@ def daemonize():
59
60
  print("Second fork failed: %d (%s)\n" % (e.errno, e.strerror), file=sys.stderr)
60
61
  sys.exit(1)
61
62
 
63
+ def parse_arguments(argv):
64
+ """
65
+ Parse command line arguments
66
+
67
+ :param argv: Array of command line arguments
68
+ """
69
+ from gns3server.version import __version__
70
+ parser = argparse.ArgumentParser(description=f"GNS3 server version {__version__}")
71
+ parser.add_argument("-v", "--version", help="show the version", action="version", version=__version__)
72
+ parser.add_argument("--host", help="run on the given host/IP address")
73
+ parser.add_argument("--port", help="run on the given port", type=int)
74
+ parser.add_argument("--ssl", action="store_true", help="run in SSL mode")
75
+ parser.add_argument("--config", help="Configuration file")
76
+ parser.add_argument("--certfile", help="SSL cert file")
77
+ parser.add_argument("--certkey", help="SSL key file")
78
+ parser.add_argument("-L", "--local", action="store_true", help="local mode (allows some insecure operations)")
79
+ parser.add_argument(
80
+ "-A", "--allow", action="store_true", help="allow remote connections to local console ports"
81
+ )
82
+ parser.add_argument("-q", "--quiet", default=False, action="store_true", help="do not show logs on stdout")
83
+ parser.add_argument("-d", "--debug", default=False, action="store_true", help="show debug logs")
84
+ parser.add_argument("--logfile", "--log", help="send output to logfile instead of console")
85
+ parser.add_argument("--logmaxsize", default=10000000, help="maximum logfile size in bytes (default is 10MB)")
86
+ parser.add_argument(
87
+ "--logbackupcount", default=10, help="number of historical log files to keep (default is 10)"
88
+ )
89
+ parser.add_argument(
90
+ "--logcompression", default=False, action="store_true", help="compress inactive (historical) logs"
91
+ )
92
+ parser.add_argument("--daemon", action="store_true", help="start as a daemon")
93
+ parser.add_argument("--pid", help="store process pid")
94
+ parser.add_argument("--profile", help="Settings profile (blank will use default settings files)")
95
+
96
+ args = parser.parse_args(argv)
97
+ return parser, args
98
+
62
99
 
63
100
  def main():
64
101
  """
@@ -69,10 +106,11 @@ def main():
69
106
  raise SystemExit("Windows is not a supported platform to run the GNS3 server")
70
107
  if "--daemon" in sys.argv:
71
108
  daemonize()
72
- from gns3server.server import Server
73
109
 
74
110
  try:
75
- asyncio.run(Server().run())
111
+ parser, args = parse_arguments(sys.argv[1:])
112
+ from gns3server.server import Server
113
+ asyncio.run(Server().run(parser, args))
76
114
  except KeyboardInterrupt:
77
115
  pass
78
116
 
gns3server/server.py CHANGED
@@ -23,7 +23,6 @@ Start the program. Use main.py to load it.
23
23
  import os
24
24
  import datetime
25
25
  import locale
26
- import argparse
27
26
  import psutil
28
27
  import sys
29
28
  import asyncio
@@ -33,13 +32,10 @@ import uvicorn
33
32
  import secrets
34
33
  import string
35
34
 
36
- from gns3server.controller import Controller
37
- from gns3server.compute.port_manager import PortManager
38
35
  from gns3server.logger import init_logger
39
36
  from gns3server.version import __version__
40
37
  from gns3server.config import Config
41
38
  from gns3server.crash_report import CrashReport
42
- from gns3server.api.server import app
43
39
  from pydantic import ValidationError, SecretStr
44
40
 
45
41
  import logging
@@ -90,40 +86,13 @@ class Server:
90
86
  else:
91
87
  log.info(f"Current locale is {language}.{encoding}")
92
88
 
93
- def _parse_arguments(self, argv):
89
+ def _setup_logging(self, args):
94
90
  """
95
- Parse command line arguments and override local configuration
91
+ Setup logging.
96
92
 
97
- :params args: Array of command line arguments
93
+ :param args: command line arguments
98
94
  """
99
95
 
100
- parser = argparse.ArgumentParser(description=f"GNS3 server version {__version__}")
101
- parser.add_argument("-v", "--version", help="show the version", action="version", version=__version__)
102
- parser.add_argument("--host", help="run on the given host/IP address")
103
- parser.add_argument("--port", help="run on the given port", type=int)
104
- parser.add_argument("--ssl", action="store_true", help="run in SSL mode")
105
- parser.add_argument("--config", help="Configuration file")
106
- parser.add_argument("--certfile", help="SSL cert file")
107
- parser.add_argument("--certkey", help="SSL key file")
108
- parser.add_argument("-L", "--local", action="store_true", help="local mode (allows some insecure operations)")
109
- parser.add_argument(
110
- "-A", "--allow", action="store_true", help="allow remote connections to local console ports"
111
- )
112
- parser.add_argument("-q", "--quiet", default=False, action="store_true", help="do not show logs on stdout")
113
- parser.add_argument("-d", "--debug", default=False, action="store_true", help="show debug logs")
114
- parser.add_argument("--logfile", "--log", help="send output to logfile instead of console")
115
- parser.add_argument("--logmaxsize", default=10000000, help="maximum logfile size in bytes (default is 10MB)")
116
- parser.add_argument(
117
- "--logbackupcount", default=10, help="number of historical log files to keep (default is 10)"
118
- )
119
- parser.add_argument(
120
- "--logcompression", default=False, action="store_true", help="compress inactive (historical) logs"
121
- )
122
- parser.add_argument("--daemon", action="store_true", help="start as a daemon")
123
- parser.add_argument("--pid", help="store process pid")
124
- parser.add_argument("--profile", help="Settings profile (blank will use default settings files)")
125
-
126
- args = parser.parse_args(argv)
127
96
  level = logging.INFO
128
97
  if args.debug:
129
98
  level = logging.DEBUG
@@ -137,6 +106,15 @@ class Server:
137
106
  quiet=args.quiet,
138
107
  )
139
108
 
109
+ @staticmethod
110
+ def _load_config_and_set_defaults(parser, args, argv=None):
111
+ """
112
+ Parse command line arguments and override local configuration
113
+
114
+ :param parser: ArgumentParser instance
115
+ :param args: command line arguments
116
+ """
117
+
140
118
  try:
141
119
  if args.config:
142
120
  Config.instance(files=[args.config], profile=args.profile)
@@ -157,7 +135,10 @@ class Server:
157
135
  }
158
136
 
159
137
  parser.set_defaults(**defaults)
160
- return parser.parse_args(argv)
138
+ if argv is None:
139
+ argv = sys.argv[1:]
140
+ args = parser.parse_args(argv)
141
+ return args
161
142
 
162
143
  @staticmethod
163
144
  def _set_config_defaults_from_command_line(args):
@@ -174,6 +155,8 @@ class Server:
174
155
  config.Server.enable_ssl = args.ssl
175
156
 
176
157
  def _signal_handling(self):
158
+
159
+ from gns3server.controller import Controller
177
160
  def signal_handler(signame, *args):
178
161
 
179
162
  try:
@@ -239,9 +222,10 @@ class Server:
239
222
  log.critical("Can't write pid file %s: %s", path, str(e))
240
223
  sys.exit(1)
241
224
 
242
- async def run(self):
225
+ async def run(self, parser, args):
243
226
 
244
- args = self._parse_arguments(sys.argv[1:])
227
+ self._setup_logging(args)
228
+ args = self._load_config_and_set_defaults(parser, args)
245
229
 
246
230
  if args.pid:
247
231
  self._pid_lock(args.pid)
@@ -256,7 +240,6 @@ class Server:
256
240
 
257
241
  self._set_config_defaults_from_command_line(args)
258
242
  config = Config.instance().settings
259
-
260
243
  if not config.Server.compute_password.get_secret_value():
261
244
  alphabet = string.ascii_letters + string.digits + string.punctuation
262
245
  generated_password = ''.join(secrets.choice(alphabet) for _ in range(16))
@@ -297,11 +280,13 @@ class Server:
297
280
  host = config.Server.host
298
281
  port = config.Server.port
299
282
 
283
+ from gns3server.compute.port_manager import PortManager
300
284
  PortManager.instance().console_host = host
301
285
  self._signal_handling()
302
286
 
303
287
  try:
304
288
  log.info(f"Starting server on {host}:{port}")
289
+ from gns3server.api.server import app
305
290
 
306
291
  # only show uvicorn access logs in debug mode
307
292
  access_log = False
@@ -46,6 +46,6 @@
46
46
 
47
47
  gtag('config', 'G-0BT7QQV1W1');
48
48
  </script>
49
- <script src="runtime.24fa95b7061d7056.js" type="module"></script><script src="polyfills.319c79dd175e50d0.js" type="module"></script><script src="main.62c99707e4709a56.js" type="module"></script>
49
+ <script src="runtime.24fa95b7061d7056.js" type="module"></script><script src="polyfills.319c79dd175e50d0.js" type="module"></script><script src="main.2e807eb4bc32f838.js" type="module"></script>
50
50
 
51
51
  </body></html>