gns3-server 3.0.0__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.
- gns3_server-3.0.0.dist-info/LICENSE +674 -0
- gns3_server-3.0.0.dist-info/METADATA +868 -0
- gns3_server-3.0.0.dist-info/RECORD +1251 -0
- gns3_server-3.0.0.dist-info/WHEEL +5 -0
- gns3_server-3.0.0.dist-info/entry_points.txt +3 -0
- gns3_server-3.0.0.dist-info/top_level.txt +1 -0
- gns3server/__init__.py +17 -0
- gns3server/__main__.py +20 -0
- gns3server/alembic.ini +103 -0
- gns3server/api/__init__.py +0 -0
- gns3server/api/routes/__init__.py +0 -0
- gns3server/api/routes/compute/__init__.py +267 -0
- gns3server/api/routes/compute/atm_switch_nodes.py +233 -0
- gns3server/api/routes/compute/capabilities.py +51 -0
- gns3server/api/routes/compute/cloud_nodes.py +249 -0
- gns3server/api/routes/compute/compute.py +143 -0
- gns3server/api/routes/compute/dependencies/__init__.py +0 -0
- gns3server/api/routes/compute/dependencies/authentication.py +83 -0
- gns3server/api/routes/compute/docker_nodes.py +393 -0
- gns3server/api/routes/compute/dynamips_nodes.py +367 -0
- gns3server/api/routes/compute/ethernet_hub_nodes.py +236 -0
- gns3server/api/routes/compute/ethernet_switch_nodes.py +246 -0
- gns3server/api/routes/compute/frame_relay_switch_nodes.py +240 -0
- gns3server/api/routes/compute/images.py +156 -0
- gns3server/api/routes/compute/iou_nodes.py +344 -0
- gns3server/api/routes/compute/nat_nodes.py +244 -0
- gns3server/api/routes/compute/notifications.py +88 -0
- gns3server/api/routes/compute/projects.py +243 -0
- gns3server/api/routes/compute/qemu_nodes.py +412 -0
- gns3server/api/routes/compute/virtualbox_nodes.py +377 -0
- gns3server/api/routes/compute/vmware_nodes.py +355 -0
- gns3server/api/routes/compute/vpcs_nodes.py +343 -0
- gns3server/api/routes/controller/__init__.py +147 -0
- gns3server/api/routes/controller/acl.py +268 -0
- gns3server/api/routes/controller/appliances.py +150 -0
- gns3server/api/routes/controller/computes.py +231 -0
- gns3server/api/routes/controller/controller.py +319 -0
- gns3server/api/routes/controller/dependencies/__init__.py +0 -0
- gns3server/api/routes/controller/dependencies/authentication.py +117 -0
- gns3server/api/routes/controller/dependencies/database.py +38 -0
- gns3server/api/routes/controller/dependencies/rbac.py +78 -0
- gns3server/api/routes/controller/drawings.py +131 -0
- gns3server/api/routes/controller/gns3vm.py +71 -0
- gns3server/api/routes/controller/groups.py +231 -0
- gns3server/api/routes/controller/images.py +255 -0
- gns3server/api/routes/controller/links.py +287 -0
- gns3server/api/routes/controller/nodes.py +619 -0
- gns3server/api/routes/controller/pools.py +239 -0
- gns3server/api/routes/controller/privileges.py +43 -0
- gns3server/api/routes/controller/projects.py +595 -0
- gns3server/api/routes/controller/roles.py +224 -0
- gns3server/api/routes/controller/snapshots.py +124 -0
- gns3server/api/routes/controller/symbols.py +133 -0
- gns3server/api/routes/controller/templates.py +192 -0
- gns3server/api/routes/controller/users.py +254 -0
- gns3server/api/routes/index.py +93 -0
- gns3server/api/server.py +224 -0
- gns3server/appliances/6wind-turbo-router.gns3a +47 -0
- gns3server/appliances/IPCop.gns3a +52 -0
- gns3server/appliances/a10-vthunder.gns3a +72 -0
- gns3server/appliances/aaa.gns3a +20 -0
- gns3server/appliances/alcatel-7750.gns3a +74 -0
- gns3server/appliances/almalinux.gns3a +84 -0
- gns3server/appliances/alpine-linux-virt.gns3a +59 -0
- gns3server/appliances/alpine-linux.gns3a +21 -0
- gns3server/appliances/arista-ceos.gns3a +20 -0
- gns3server/appliances/arista-veos.gns3a +577 -0
- gns3server/appliances/aruba-arubaoscx.gns3a +233 -0
- gns3server/appliances/aruba-vgw.gns3a +60 -0
- gns3server/appliances/aruba-vmc.gns3a +56 -0
- gns3server/appliances/asterfusion-vAsterNOS.gns3a +49 -0
- gns3server/appliances/asterisk.gns3a +114 -0
- gns3server/appliances/bigswitch-bigcloud-fabric.gns3a +42 -0
- gns3server/appliances/bird.gns3a +42 -0
- gns3server/appliances/bird2.gns3a +57 -0
- gns3server/appliances/brocade-vadx.gns3a +43 -0
- gns3server/appliances/brocade-vrouter.gns3a +138 -0
- gns3server/appliances/brocade-vtm.gns3a +136 -0
- gns3server/appliances/bsdrp.gns3a +117 -0
- gns3server/appliances/centos-cloud.gns3a +115 -0
- gns3server/appliances/centos7.gns3a +72 -0
- gns3server/appliances/checkpoint-gaia.gns3a +81 -0
- gns3server/appliances/chromium.gns3a +19 -0
- gns3server/appliances/cisco-1700.gns3a +39 -0
- gns3server/appliances/cisco-2600.gns3a +38 -0
- gns3server/appliances/cisco-2691.gns3a +38 -0
- gns3server/appliances/cisco-3620.gns3a +38 -0
- gns3server/appliances/cisco-3640.gns3a +38 -0
- gns3server/appliances/cisco-3660.gns3a +38 -0
- gns3server/appliances/cisco-3725.gns3a +38 -0
- gns3server/appliances/cisco-3745.gns3a +45 -0
- gns3server/appliances/cisco-7200.gns3a +92 -0
- gns3server/appliances/cisco-asa.gns3a +86 -0
- gns3server/appliances/cisco-asav.gns3a +227 -0
- gns3server/appliances/cisco-c8000v.gns3a +108 -0
- gns3server/appliances/cisco-cat9k.gns3a +58 -0
- gns3server/appliances/cisco-csr1000v.gns3a +316 -0
- gns3server/appliances/cisco-dcnm.gns3a +96 -0
- gns3server/appliances/cisco-fcnf.gns3a +71 -0
- gns3server/appliances/cisco-fmcv.gns3a +139 -0
- gns3server/appliances/cisco-fsve.gns3a +57 -0
- gns3server/appliances/cisco-ftdv.gns3a +99 -0
- gns3server/appliances/cisco-iosv.gns3a +178 -0
- gns3server/appliances/cisco-iosvl2.gns3a +95 -0
- gns3server/appliances/cisco-iosxrv.gns3a +57 -0
- gns3server/appliances/cisco-iosxrv9k.gns3a +188 -0
- gns3server/appliances/cisco-iou-l2.gns3a +84 -0
- gns3server/appliances/cisco-iou-l3.gns3a +84 -0
- gns3server/appliances/cisco-ise.gns3a +154 -0
- gns3server/appliances/cisco-ngipsv.gns3a +73 -0
- gns3server/appliances/cisco-nxosv.gns3a +56 -0
- gns3server/appliances/cisco-nxosv9k.gns3a +433 -0
- gns3server/appliances/cisco-pyats.gns3a +19 -0
- gns3server/appliances/cisco-smc.gns3a +71 -0
- gns3server/appliances/cisco-vWLC.gns3a +140 -0
- gns3server/appliances/cisco-wsav.gns3a +44 -0
- gns3server/appliances/citrix-netscaler-vpx.gns3a +72 -0
- gns3server/appliances/citrix-sd-wan.gns3a +46 -0
- gns3server/appliances/citrix-sdwan-center.gns3a +46 -0
- gns3server/appliances/clavister-netsheild.gns3a +59 -0
- gns3server/appliances/clavister-netwall.gns3a +71 -0
- gns3server/appliances/clearos.gns3a +107 -0
- gns3server/appliances/cloudrouter.gns3a +72 -0
- gns3server/appliances/coreos.gns3a +329 -0
- gns3server/appliances/cumulus-vx.gns3a +440 -0
- gns3server/appliances/danos.gns3a +57 -0
- gns3server/appliances/debian.gns3a +85 -0
- gns3server/appliances/deft-linux.gns3a +96 -0
- gns3server/appliances/dell-ftos.gns3a +71 -0
- gns3server/appliances/dns.gns3a +20 -0
- gns3server/appliances/empty-vm.gns3a +199 -0
- gns3server/appliances/endhost.gns3a +17 -0
- gns3server/appliances/exos.gns3a +51 -0
- gns3server/appliances/extreme-networks-voss.gns3a +152 -0
- gns3server/appliances/f5-bigip.gns3a +322 -0
- gns3server/appliances/f5-bigiq.gns3a +165 -0
- gns3server/appliances/fedora-cloud.gns3a +70 -0
- gns3server/appliances/firefox.gns3a +59 -0
- gns3server/appliances/fortiadc-manager.gns3a +54 -0
- gns3server/appliances/fortiadc.gns3a +502 -0
- gns3server/appliances/fortianalyzer.gns3a +519 -0
- gns3server/appliances/fortiauthenticator.gns3a +251 -0
- gns3server/appliances/forticache.gns3a +210 -0
- gns3server/appliances/fortigate.gns3a +742 -0
- gns3server/appliances/fortimail.gns3a +392 -0
- gns3server/appliances/fortimanager.gns3a +519 -0
- gns3server/appliances/fortiproxy.gns3a +83 -0
- gns3server/appliances/fortirecorder.gns3a +69 -0
- gns3server/appliances/fortisandbox.gns3a +210 -0
- gns3server/appliances/fortisiem-super_worker.gns3a +210 -0
- gns3server/appliances/fortiweb.gns3a +308 -0
- gns3server/appliances/freeRouter.gns3a +44 -0
- gns3server/appliances/freebsd.gns3a +75 -0
- gns3server/appliances/freenas.gns3a +183 -0
- gns3server/appliances/frr.gns3a +84 -0
- gns3server/appliances/haproxy.gns3a +18 -0
- gns3server/appliances/hbcd-pe.gns3a +62 -0
- gns3server/appliances/hp-vsr1001.gns3a +149 -0
- gns3server/appliances/huawei-ar1kv.gns3a +58 -0
- gns3server/appliances/huawei-ce12800.gns3a +43 -0
- gns3server/appliances/huawei-ne40e.gns3a +94 -0
- gns3server/appliances/huawei-usg6kv.gns3a +50 -0
- gns3server/appliances/innovaphone-app.gns3a +50 -0
- gns3server/appliances/innovaphone-ipva.gns3a +78 -0
- gns3server/appliances/ipfire.gns3a +181 -0
- gns3server/appliances/ipterm.gns3a +19 -0
- gns3server/appliances/ipxe.gns3a +47 -0
- gns3server/appliances/juniper-junos-space.gns3a +46 -0
- gns3server/appliances/juniper-vmx-legacy.gns3a +55 -0
- gns3server/appliances/juniper-vmx-vcp.gns3a +520 -0
- gns3server/appliances/juniper-vmx-vfp.gns3a +281 -0
- gns3server/appliances/juniper-vqfx-pfe.gns3a +71 -0
- gns3server/appliances/juniper-vqfx-re.gns3a +85 -0
- gns3server/appliances/juniper-vrr.gns3a +66 -0
- gns3server/appliances/juniper-vsrx.gns3a +332 -0
- gns3server/appliances/jupyter.gns3a +20 -0
- gns3server/appliances/jupyter27.gns3a +20 -0
- gns3server/appliances/kali-linux-cli.gns3a +18 -0
- gns3server/appliances/kali-linux.gns3a +248 -0
- gns3server/appliances/kemp-vlm.gns3a +111 -0
- gns3server/appliances/kerio-connect.gns3a +131 -0
- gns3server/appliances/kerio-control.gns3a +143 -0
- gns3server/appliances/kerio-operator.gns3a +130 -0
- gns3server/appliances/lancom-vrouter.gns3a +45 -0
- gns3server/appliances/loadbalancer_org-va.gns3a +56 -0
- gns3server/appliances/macos-install.gns3a +72 -0
- gns3server/appliances/mcjoin.gns3a +19 -0
- gns3server/appliances/microcore-linux.gns3a +72 -0
- gns3server/appliances/mikrotik-ccr1036-8g-2s+.gns3a +165 -0
- gns3server/appliances/mikrotik-ccr1072-1g-8s+.gns3a +161 -0
- gns3server/appliances/mikrotik-chr.gns3a +108 -0
- gns3server/appliances/mikrotik-crs328-24p-4s+.gns3a +173 -0
- gns3server/appliances/mikrotik-crs328-4c-20s-4s+.gns3a +189 -0
- gns3server/appliances/mikrotik-rb1100ahx4-dude-edition.gns3a +155 -0
- gns3server/appliances/mikrotik-rb2011uias.gns3a +161 -0
- gns3server/appliances/mikrotik-rb3011uias.gns3a +161 -0
- gns3server/appliances/mikrotik-rb4011igs+.gns3a +161 -0
- gns3server/appliances/mikrotik-rb450g.gns3a +155 -0
- gns3server/appliances/mikrotik-rb450gx4.gns3a +155 -0
- gns3server/appliances/mikrotik-winbox.gns3a +19 -0
- gns3server/appliances/mininet.gns3a +47 -0
- gns3server/appliances/net_toolbox.gns3a +20 -0
- gns3server/appliances/netapp-ontapsim.gns3a +185 -0
- gns3server/appliances/netem.gns3a +44 -0
- gns3server/appliances/network_automation.gns3a +19 -0
- gns3server/appliances/nixos.gns3a +52 -0
- gns3server/appliances/nokia-vsim.gns3a +47 -0
- gns3server/appliances/ntopng.gns3a +24 -0
- gns3server/appliances/onos.gns3a +19 -0
- gns3server/appliances/op5-monitor.gns3a +72 -0
- gns3server/appliances/open-media-vault.gns3a +120 -0
- gns3server/appliances/openbsd.gns3a +44 -0
- gns3server/appliances/opennac.gns3a +45 -0
- gns3server/appliances/opensuse.gns3a +47 -0
- gns3server/appliances/openvswitch-management.gns3a +21 -0
- gns3server/appliances/openvswitch.gns3a +21 -0
- gns3server/appliances/openwrt-realview.gns3a +56 -0
- gns3server/appliances/openwrt.gns3a +359 -0
- gns3server/appliances/opnsense.gns3a +122 -0
- gns3server/appliances/oracle-linux-cloud.gns3a +115 -0
- gns3server/appliances/ostinato-wireshark.gns3a +20 -0
- gns3server/appliances/ostinato.gns3a +75 -0
- gns3server/appliances/ovs-snmp.gns3a +18 -0
- gns3server/appliances/packetfence-zen.gns3a +151 -0
- gns3server/appliances/pan-vm-fw.gns3a +241 -0
- gns3server/appliances/parrot-os.gns3a +68 -0
- gns3server/appliances/pfsense.gns3a +122 -0
- gns3server/appliances/proxmox-mg.gns3a +69 -0
- gns3server/appliances/puppy-linux.gns3a +82 -0
- gns3server/appliances/python-go-perl-php.gns3a +17 -0
- gns3server/appliances/raspian.gns3a +79 -0
- gns3server/appliances/reactos.gns3a +67 -0
- gns3server/appliances/rhel.gns3a +207 -0
- gns3server/appliances/riverbed-steelhead-ng-vcx.gns3a +68 -0
- gns3server/appliances/rockylinux.gns3a +100 -0
- gns3server/appliances/security-onion.gns3a +108 -0
- gns3server/appliances/smoothwall.gns3a +54 -0
- gns3server/appliances/sophos-iview.gns3a +66 -0
- gns3server/appliances/sophos-utm.gns3a +263 -0
- gns3server/appliances/sophos-xg.gns3a +198 -0
- gns3server/appliances/stonework.gns3a +21 -0
- gns3server/appliances/tacacs-gui.gns3a +57 -0
- gns3server/appliances/tinycore-linux.gns3a +73 -0
- gns3server/appliances/trendmicro-imsva.gns3a +54 -0
- gns3server/appliances/trendmicro-iwsva.gns3a +53 -0
- gns3server/appliances/truenas.gns3a +104 -0
- gns3server/appliances/turnkey-wordpress.gns3a +20 -0
- gns3server/appliances/ubuntu-cloud.gns3a +116 -0
- gns3server/appliances/ubuntu-docker.gns3a +20 -0
- gns3server/appliances/ubuntu-gui.gns3a +98 -0
- gns3server/appliances/untangle.gns3a +208 -0
- gns3server/appliances/viptela-edge-genericx86-64.gns3a +84 -0
- gns3server/appliances/viptela-smart-genericx86-64.gns3a +82 -0
- gns3server/appliances/viptela-vmanage-genericx86-64.gns3a +95 -0
- gns3server/appliances/vpp.gns3a +45 -0
- gns3server/appliances/vrin.gns3a +118 -0
- gns3server/appliances/vyos.gns3a +179 -0
- gns3server/appliances/watchguard-fireboxv.gns3a +45 -0
- gns3server/appliances/watchguard-xtmv.gns3a +45 -0
- gns3server/appliances/webterm.gns3a +20 -0
- gns3server/appliances/windows-11-dev-env.gns3a +74 -0
- gns3server/appliances/windows-xp+ie.gns3a +52 -0
- gns3server/appliances/windows.gns3a +125 -0
- gns3server/appliances/windows_server.gns3a +83 -0
- gns3server/appliances/zentyal-server.gns3a +159 -0
- gns3server/appliances/zeroshell.gns3a +103 -0
- gns3server/compute/__init__.py +38 -0
- gns3server/compute/adapters/__init__.py +0 -0
- gns3server/compute/adapters/adapter.py +104 -0
- gns3server/compute/adapters/ethernet_adapter.py +33 -0
- gns3server/compute/adapters/serial_adapter.py +32 -0
- gns3server/compute/base_manager.py +547 -0
- gns3server/compute/base_node.py +979 -0
- gns3server/compute/builtin/__init__.py +46 -0
- gns3server/compute/builtin/builtin_node_factory.py +42 -0
- gns3server/compute/builtin/nodes/__init__.py +0 -0
- gns3server/compute/builtin/nodes/cloud.py +548 -0
- gns3server/compute/builtin/nodes/ethernet_hub.py +104 -0
- gns3server/compute/builtin/nodes/ethernet_switch.py +104 -0
- gns3server/compute/builtin/nodes/nat.py +97 -0
- gns3server/compute/compute_error.py +48 -0
- gns3server/compute/docker/__init__.py +320 -0
- gns3server/compute/docker/docker_error.py +33 -0
- gns3server/compute/docker/docker_vm.py +1378 -0
- gns3server/compute/docker/resources/bin/udhcpc +15 -0
- gns3server/compute/docker/resources/etc/udhcpc/default.script +138 -0
- gns3server/compute/docker/resources/init.sh +102 -0
- gns3server/compute/docker/resources/run-cmd.sh +6 -0
- gns3server/compute/dynamips/__init__.py +661 -0
- gns3server/compute/dynamips/adapters/__init__.py +0 -0
- gns3server/compute/dynamips/adapters/adapter.py +165 -0
- gns3server/compute/dynamips/adapters/c1700_mb_1fe.py +36 -0
- gns3server/compute/dynamips/adapters/c1700_mb_wic1.py +37 -0
- gns3server/compute/dynamips/adapters/c2600_mb_1e.py +36 -0
- gns3server/compute/dynamips/adapters/c2600_mb_1fe.py +37 -0
- gns3server/compute/dynamips/adapters/c2600_mb_2e.py +36 -0
- gns3server/compute/dynamips/adapters/c2600_mb_2fe.py +36 -0
- gns3server/compute/dynamips/adapters/c7200_io_2fe.py +36 -0
- gns3server/compute/dynamips/adapters/c7200_io_fe.py +36 -0
- gns3server/compute/dynamips/adapters/c7200_io_ge_e.py +36 -0
- gns3server/compute/dynamips/adapters/gt96100_fe.py +31 -0
- gns3server/compute/dynamips/adapters/leopard_2fe.py +37 -0
- gns3server/compute/dynamips/adapters/nm_16esw.py +32 -0
- gns3server/compute/dynamips/adapters/nm_1e.py +32 -0
- gns3server/compute/dynamips/adapters/nm_1fe_tx.py +32 -0
- gns3server/compute/dynamips/adapters/nm_4e.py +32 -0
- gns3server/compute/dynamips/adapters/nm_4t.py +32 -0
- gns3server/compute/dynamips/adapters/pa_2fe_tx.py +32 -0
- gns3server/compute/dynamips/adapters/pa_4e.py +32 -0
- gns3server/compute/dynamips/adapters/pa_4t.py +32 -0
- gns3server/compute/dynamips/adapters/pa_8e.py +32 -0
- gns3server/compute/dynamips/adapters/pa_8t.py +32 -0
- gns3server/compute/dynamips/adapters/pa_a1.py +32 -0
- gns3server/compute/dynamips/adapters/pa_fe_tx.py +32 -0
- gns3server/compute/dynamips/adapters/pa_ge.py +32 -0
- gns3server/compute/dynamips/adapters/pa_pos_oc3.py +32 -0
- gns3server/compute/dynamips/adapters/wic_1enet.py +40 -0
- gns3server/compute/dynamips/adapters/wic_1t.py +40 -0
- gns3server/compute/dynamips/adapters/wic_2t.py +40 -0
- gns3server/compute/dynamips/dynamips_error.py +26 -0
- gns3server/compute/dynamips/dynamips_factory.py +71 -0
- gns3server/compute/dynamips/dynamips_hypervisor.py +333 -0
- gns3server/compute/dynamips/hypervisor.py +210 -0
- gns3server/compute/dynamips/nios/__init__.py +0 -0
- gns3server/compute/dynamips/nios/nio.py +352 -0
- gns3server/compute/dynamips/nios/nio_generic_ethernet.py +73 -0
- gns3server/compute/dynamips/nios/nio_linux_ethernet.py +72 -0
- gns3server/compute/dynamips/nios/nio_null.py +51 -0
- gns3server/compute/dynamips/nios/nio_tap.py +66 -0
- gns3server/compute/dynamips/nios/nio_udp.py +136 -0
- gns3server/compute/dynamips/nios/nio_unix.py +88 -0
- gns3server/compute/dynamips/nios/nio_vde.py +88 -0
- gns3server/compute/dynamips/nodes/__init__.py +0 -0
- gns3server/compute/dynamips/nodes/atm_switch.py +514 -0
- gns3server/compute/dynamips/nodes/bridge.py +107 -0
- gns3server/compute/dynamips/nodes/c1700.py +160 -0
- gns3server/compute/dynamips/nodes/c2600.py +171 -0
- gns3server/compute/dynamips/nodes/c2691.py +112 -0
- gns3server/compute/dynamips/nodes/c3600.py +155 -0
- gns3server/compute/dynamips/nodes/c3725.py +112 -0
- gns3server/compute/dynamips/nodes/c3745.py +112 -0
- gns3server/compute/dynamips/nodes/c7200.py +268 -0
- gns3server/compute/dynamips/nodes/device.py +134 -0
- gns3server/compute/dynamips/nodes/ethernet_hub.py +241 -0
- gns3server/compute/dynamips/nodes/ethernet_switch.py +496 -0
- gns3server/compute/dynamips/nodes/frame_relay_switch.py +379 -0
- gns3server/compute/dynamips/nodes/router.py +1797 -0
- gns3server/compute/error.py +40 -0
- gns3server/compute/iou/__init__.py +64 -0
- gns3server/compute/iou/iou_error.py +25 -0
- gns3server/compute/iou/iou_vm.py +1482 -0
- gns3server/compute/iou/utils/__init__.py +0 -0
- gns3server/compute/iou/utils/iou_export.py +233 -0
- gns3server/compute/iou/utils/iou_import.py +232 -0
- gns3server/compute/nios/__init__.py +0 -0
- gns3server/compute/nios/nio.py +120 -0
- gns3server/compute/nios/nio_ethernet.py +56 -0
- gns3server/compute/nios/nio_tap.py +56 -0
- gns3server/compute/nios/nio_udp.py +82 -0
- gns3server/compute/notification_manager.py +73 -0
- gns3server/compute/port_manager.py +402 -0
- gns3server/compute/project.py +434 -0
- gns3server/compute/project_manager.py +122 -0
- gns3server/compute/qemu/__init__.py +304 -0
- gns3server/compute/qemu/qemu_error.py +26 -0
- gns3server/compute/qemu/qemu_vm.py +2697 -0
- gns3server/compute/qemu/resources/config.img.zip +0 -0
- gns3server/compute/qemu/utils/__init__.py +0 -0
- gns3server/compute/qemu/utils/guest_cid.py +38 -0
- gns3server/compute/qemu/utils/qcow2.py +138 -0
- gns3server/compute/qemu/utils/ziputils.py +55 -0
- gns3server/compute/ubridge/__init__.py +0 -0
- gns3server/compute/ubridge/hypervisor.py +256 -0
- gns3server/compute/ubridge/ubridge_error.py +32 -0
- gns3server/compute/ubridge/ubridge_hypervisor.py +285 -0
- gns3server/compute/virtualbox/__init__.py +212 -0
- gns3server/compute/virtualbox/virtualbox_error.py +26 -0
- gns3server/compute/virtualbox/virtualbox_vm.py +1255 -0
- gns3server/compute/vmware/__init__.py +725 -0
- gns3server/compute/vmware/vmware_error.py +26 -0
- gns3server/compute/vmware/vmware_vm.py +1007 -0
- gns3server/compute/vpcs/__init__.py +91 -0
- gns3server/compute/vpcs/vpcs_error.py +26 -0
- gns3server/compute/vpcs/vpcs_vm.py +595 -0
- gns3server/config.py +284 -0
- gns3server/config_samples/gns3_server.conf +160 -0
- gns3server/configs/ios_base_startup-config.txt +26 -0
- gns3server/configs/ios_etherswitch_startup-config.txt +181 -0
- gns3server/configs/iou_l2_base_startup-config.txt +133 -0
- gns3server/configs/iou_l3_base_startup-config.txt +109 -0
- gns3server/configs/vpcs_base_config.txt +9 -0
- gns3server/controller/__init__.py +691 -0
- gns3server/controller/appliance.py +86 -0
- gns3server/controller/appliance_manager.py +486 -0
- gns3server/controller/appliance_to_template.py +132 -0
- gns3server/controller/compute.py +677 -0
- gns3server/controller/controller_error.py +77 -0
- gns3server/controller/drawing.py +229 -0
- gns3server/controller/export_project.py +336 -0
- gns3server/controller/gns3vm/__init__.py +412 -0
- gns3server/controller/gns3vm/base_gns3_vm.py +303 -0
- gns3server/controller/gns3vm/gns3_vm_error.py +28 -0
- gns3server/controller/gns3vm/hyperv_gns3_vm.py +346 -0
- gns3server/controller/gns3vm/remote_gns3_vm.py +73 -0
- gns3server/controller/gns3vm/virtualbox_gns3_vm.py +480 -0
- gns3server/controller/gns3vm/vmware_gns3_vm.py +216 -0
- gns3server/controller/import_project.py +332 -0
- gns3server/controller/link.py +461 -0
- gns3server/controller/node.py +840 -0
- gns3server/controller/notification.py +149 -0
- gns3server/controller/ports/__init__.py +0 -0
- gns3server/controller/ports/atm_port.py +51 -0
- gns3server/controller/ports/ethernet_port.py +49 -0
- gns3server/controller/ports/fastethernet_port.py +43 -0
- gns3server/controller/ports/frame_relay_port.py +43 -0
- gns3server/controller/ports/gigabitethernet_port.py +43 -0
- gns3server/controller/ports/port.py +109 -0
- gns3server/controller/ports/port_factory.py +213 -0
- gns3server/controller/ports/pos_port.py +52 -0
- gns3server/controller/ports/serial_port.py +63 -0
- gns3server/controller/project.py +1399 -0
- gns3server/controller/snapshot.py +140 -0
- gns3server/controller/symbol_themes.py +153 -0
- gns3server/controller/symbols.py +168 -0
- gns3server/controller/topology.py +788 -0
- gns3server/controller/udp_link.py +245 -0
- gns3server/core/__init__.py +0 -0
- gns3server/core/tasks.py +99 -0
- gns3server/crash_report.py +167 -0
- gns3server/db/__init__.py +0 -0
- gns3server/db/models/__init__.py +38 -0
- gns3server/db/models/acl.py +46 -0
- gns3server/db/models/base.py +117 -0
- gns3server/db/models/computes.py +33 -0
- gns3server/db/models/images.py +43 -0
- gns3server/db/models/pools.py +52 -0
- gns3server/db/models/privileges.py +359 -0
- gns3server/db/models/roles.py +57 -0
- gns3server/db/models/templates.py +272 -0
- gns3server/db/models/users.py +94 -0
- gns3server/db/repositories/__init__.py +0 -0
- gns3server/db/repositories/base.py +24 -0
- gns3server/db/repositories/computes.py +93 -0
- gns3server/db/repositories/images.py +141 -0
- gns3server/db/repositories/pools.py +218 -0
- gns3server/db/repositories/rbac.py +430 -0
- gns3server/db/repositories/templates.py +172 -0
- gns3server/db/repositories/users.py +289 -0
- gns3server/db/tasks.py +230 -0
- gns3server/db_migrations/README +5 -0
- gns3server/db_migrations/env.py +101 -0
- gns3server/db_migrations/script.py.mako +24 -0
- gns3server/db_migrations/versions/7ceeddd9c9a8_init.py +28 -0
- gns3server/db_migrations/versions/9a5292aa4389_add_mac_address_field_in_docker_.py +27 -0
- gns3server/disks/OVMF.fd +0 -0
- gns3server/disks/OVMF_CODE.fd +0 -0
- gns3server/disks/OVMF_VARS.fd +0 -0
- gns3server/disks/empty100G.qcow2 +0 -0
- gns3server/disks/empty10G.qcow2 +0 -0
- gns3server/disks/empty150G.qcow2 +0 -0
- gns3server/disks/empty1T.qcow2 +0 -0
- gns3server/disks/empty200G.qcow2 +0 -0
- gns3server/disks/empty20G.qcow2 +0 -0
- gns3server/disks/empty250G.qcow2 +0 -0
- gns3server/disks/empty30G.qcow2 +0 -0
- gns3server/disks/empty40G.qcow2 +0 -0
- gns3server/disks/empty500G.qcow2 +0 -0
- gns3server/disks/empty50G.qcow2 +0 -0
- gns3server/disks/empty8G.qcow2 +0 -0
- gns3server/gns3_server.egg-info/PKG-INFO +307 -0
- gns3server/gns3_server.egg-info/SOURCES.txt +0 -0
- gns3server/gns3_server.egg-info/dependency_links.txt +1 -0
- gns3server/gns3_server.egg-info/entry_points.txt +4 -0
- gns3server/gns3_server.egg-info/not-zip-safe +1 -0
- gns3server/gns3_server.egg-info/requires.txt +31 -0
- gns3server/gns3_server.egg-info/top_level.txt +2 -0
- gns3server/logger.py +164 -0
- gns3server/main.py +81 -0
- gns3server/schemas/__init__.py +85 -0
- gns3server/schemas/common.py +71 -0
- gns3server/schemas/compute/__init__.py +0 -0
- gns3server/schemas/compute/atm_switch_nodes.py +55 -0
- gns3server/schemas/compute/cloud_nodes.py +137 -0
- gns3server/schemas/compute/docker_nodes.py +75 -0
- gns3server/schemas/compute/dynamips_nodes.py +197 -0
- gns3server/schemas/compute/ethernet_hub_nodes.py +63 -0
- gns3server/schemas/compute/ethernet_switch_nodes.py +100 -0
- gns3server/schemas/compute/frame_relay_switch_nodes.py +55 -0
- gns3server/schemas/compute/iou_nodes.py +76 -0
- gns3server/schemas/compute/nat_nodes.py +122 -0
- gns3server/schemas/compute/nios.py +66 -0
- gns3server/schemas/compute/qemu_nodes.py +245 -0
- gns3server/schemas/compute/virtualbox_nodes.py +97 -0
- gns3server/schemas/compute/vmware_nodes.py +102 -0
- gns3server/schemas/compute/vpcs_nodes.py +68 -0
- gns3server/schemas/config.py +197 -0
- gns3server/schemas/controller/__init__.py +0 -0
- gns3server/schemas/controller/appliances.py +466 -0
- gns3server/schemas/controller/base.py +25 -0
- gns3server/schemas/controller/capabilities.py +34 -0
- gns3server/schemas/controller/computes.py +168 -0
- gns3server/schemas/controller/drawings.py +34 -0
- gns3server/schemas/controller/gns3vm.py +56 -0
- gns3server/schemas/controller/images.py +44 -0
- gns3server/schemas/controller/iou_license.py +23 -0
- gns3server/schemas/controller/labels.py +30 -0
- gns3server/schemas/controller/links.py +94 -0
- gns3server/schemas/controller/nodes.py +177 -0
- gns3server/schemas/controller/pools.py +81 -0
- gns3server/schemas/controller/projects.py +116 -0
- gns3server/schemas/controller/rbac.py +113 -0
- gns3server/schemas/controller/snapshots.py +42 -0
- gns3server/schemas/controller/templates/__init__.py +83 -0
- gns3server/schemas/controller/templates/cloud_templates.py +44 -0
- gns3server/schemas/controller/templates/docker_templates.py +59 -0
- gns3server/schemas/controller/templates/dynamips_templates.py +199 -0
- gns3server/schemas/controller/templates/ethernet_hub_templates.py +46 -0
- gns3server/schemas/controller/templates/ethernet_switch_templates.py +57 -0
- gns3server/schemas/controller/templates/iou_templates.py +47 -0
- gns3server/schemas/controller/templates/qemu_templates.py +94 -0
- gns3server/schemas/controller/templates/virtualbox_templates.py +64 -0
- gns3server/schemas/controller/templates/vmware_templates.py +61 -0
- gns3server/schemas/controller/templates/vpcs_templates.py +39 -0
- gns3server/schemas/controller/tokens.py +29 -0
- gns3server/schemas/controller/topology.py +82 -0
- gns3server/schemas/controller/users.py +105 -0
- gns3server/schemas/link.py +0 -0
- gns3server/schemas/qemu_disk_image.py +103 -0
- gns3server/schemas/version.py +25 -0
- gns3server/server.py +348 -0
- gns3server/services/__init__.py +19 -0
- gns3server/services/authentication.py +83 -0
- gns3server/services/computes.py +82 -0
- gns3server/services/templates.py +329 -0
- gns3server/static/.gitkeep +0 -0
- gns3server/static/favicon.ico +0 -0
- gns3server/static/redoc.standalone.js +1782 -0
- gns3server/static/swagger-ui-bundle.js +2 -0
- gns3server/static/swagger-ui.css +3 -0
- gns3server/static/web-ui/3rdpartylicenses.txt +2604 -0
- gns3server/static/web-ui/465.92c7ab880f2504d3.js +1 -0
- gns3server/static/web-ui/MaterialIcons-Regular.196fa4a92dd6fa73.ttf +0 -0
- gns3server/static/web-ui/MaterialIcons-Regular.1e50f5c2ffa6aba4.eot +0 -0
- gns3server/static/web-ui/MaterialIcons-Regular.7ea2023eeca07427.woff2 +0 -0
- gns3server/static/web-ui/MaterialIcons-Regular.db852539204b1a34.woff +0 -0
- gns3server/static/web-ui/NotoSans-Bold.635e9291df1a5a00.woff2 +0 -0
- gns3server/static/web-ui/NotoSans-Bold.885427cced6d8c94.woff +0 -0
- gns3server/static/web-ui/NotoSans-Bold.93203a43bc93ad9c.svg +8453 -0
- gns3server/static/web-ui/NotoSans-Bold.a7ab189a45f553b4.eot +0 -0
- gns3server/static/web-ui/NotoSans-Bold.e989c11744b36f58.ttf +0 -0
- gns3server/static/web-ui/NotoSans-BoldItalic.2baf33b639fc86a4.woff +0 -0
- gns3server/static/web-ui/NotoSans-BoldItalic.2eea9ba02e25c1d3.ttf +0 -0
- gns3server/static/web-ui/NotoSans-BoldItalic.46a5eec91da0d900.svg +8453 -0
- gns3server/static/web-ui/NotoSans-BoldItalic.7fdef73b477daa73.eot +0 -0
- gns3server/static/web-ui/NotoSans-BoldItalic.c62f70f121f271aa.woff2 +0 -0
- gns3server/static/web-ui/NotoSans-Italic.219ee88e5bc4e168.ttf +0 -0
- gns3server/static/web-ui/NotoSans-Italic.3d6f7cf772169c8d.svg +8453 -0
- gns3server/static/web-ui/NotoSans-Italic.77cd3818b5a2cb97.woff +0 -0
- gns3server/static/web-ui/NotoSans-Italic.85194585ae9d8c36.eot +0 -0
- gns3server/static/web-ui/NotoSans-Italic.eee02500e81db981.woff2 +0 -0
- gns3server/static/web-ui/NotoSans-Regular.156b7584192d70ed.eot +0 -0
- gns3server/static/web-ui/NotoSans-Regular.374d132a6803e279.woff2 +0 -0
- gns3server/static/web-ui/NotoSans-Regular.595e3f5876719740.woff +0 -0
- gns3server/static/web-ui/NotoSans-Regular.bb384defbe36eaec.svg +8453 -0
- gns3server/static/web-ui/NotoSans-Regular.e6139cb1663a1c57.ttf +0 -0
- gns3server/static/web-ui/ReleaseNotes.txt +179 -0
- gns3server/static/web-ui/assets/favicon.ico +0 -0
- gns3server/static/web-ui/assets/gns3_icon.svg +88 -0
- gns3server/static/web-ui/assets/gns3_icon_black.svg +88 -0
- gns3server/static/web-ui/assets/icons/mac/icon.icns +0 -0
- gns3server/static/web-ui/assets/icons/png/1024x1024.png +0 -0
- gns3server/static/web-ui/assets/icons/png/128x128.png +0 -0
- gns3server/static/web-ui/assets/icons/png/16x16.png +0 -0
- gns3server/static/web-ui/assets/icons/png/24x24.png +0 -0
- gns3server/static/web-ui/assets/icons/png/256x256.png +0 -0
- gns3server/static/web-ui/assets/icons/png/32x32.png +0 -0
- gns3server/static/web-ui/assets/icons/png/48x48.png +0 -0
- gns3server/static/web-ui/assets/icons/png/512x512.png +0 -0
- gns3server/static/web-ui/assets/icons/png/64x64.png +0 -0
- gns3server/static/web-ui/assets/icons/win/icon.ico +0 -0
- gns3server/static/web-ui/assets/logo-header.png +0 -0
- gns3server/static/web-ui/assets/resources/images/filter-capture.svg +428 -0
- gns3server/static/web-ui/assets/resources/images/filter.svg +708 -0
- gns3server/static/web-ui/assets/resources/images/inspect.svg +312 -0
- gns3server/static/web-ui/assets/resources/images/pause.svg +752 -0
- gns3server/static/web-ui/favicon.ico +0 -0
- gns3server/static/web-ui/index.html +51 -0
- gns3server/static/web-ui/main.f802edd2b8c6db1d.js +1 -0
- gns3server/static/web-ui/polyfills.319c79dd175e50d0.js +1 -0
- gns3server/static/web-ui/roboto-latin-100.539f0a96b40596f7.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-100.5ba994dac3e79ea8.woff +0 -0
- gns3server/static/web-ui/roboto-latin-100italic.41ba64219cb743c9.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-100italic.d61e7e8b07c0638c.woff +0 -0
- gns3server/static/web-ui/roboto-latin-300.4d8f8086236bad80.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-300.6c1bc461047e61f5.woff +0 -0
- gns3server/static/web-ui/roboto-latin-300italic.3a529751a590d3c1.woff +0 -0
- gns3server/static/web-ui/roboto-latin-300italic.45164643b3bd5824.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-400.1e2d4d3a272629cd.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-400.7e4a045b9373d9c1.woff +0 -0
- gns3server/static/web-ui/roboto-latin-400italic.68431199e5b90ea8.woff +0 -0
- gns3server/static/web-ui/roboto-latin-400italic.bb3c6955c4334c8a.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-500.1dfbc3dbf815e3f3.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-500.e21fe97fd2329ff7.woff +0 -0
- gns3server/static/web-ui/roboto-latin-500italic.7543a42b12b1452f.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-500italic.aaff6867154023d3.woff +0 -0
- gns3server/static/web-ui/roboto-latin-700.02633003129d1e63.woff +0 -0
- gns3server/static/web-ui/roboto-latin-700.12893bfc0762b0f3.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-700italic.bc7179e004e40113.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-700italic.e53062e27c63fafb.woff +0 -0
- gns3server/static/web-ui/roboto-latin-900.282ba77fda1349f3.woff2 +0 -0
- gns3server/static/web-ui/roboto-latin-900.4962e810cbb4d3e5.woff +0 -0
- gns3server/static/web-ui/roboto-latin-900italic.2394134a78bbaef8.woff +0 -0
- gns3server/static/web-ui/roboto-latin-900italic.9c1f80840351fa12.woff2 +0 -0
- gns3server/static/web-ui/runtime.24fa95b7061d7056.js +1 -0
- gns3server/static/web-ui/styles.6e966072487df0b7.css +5 -0
- gns3server/symbols/.gitkeep +0 -0
- gns3server/symbols/affinity/circle/blue/atm.svg +5 -0
- gns3server/symbols/affinity/circle/blue/bug.svg +8 -0
- gns3server/symbols/affinity/circle/blue/camera.svg +5 -0
- gns3server/symbols/affinity/circle/blue/camera_dome.svg +8 -0
- gns3server/symbols/affinity/circle/blue/client.svg +5 -0
- gns3server/symbols/affinity/circle/blue/client_vm.svg +6 -0
- gns3server/symbols/affinity/circle/blue/cloud.svg +5 -0
- gns3server/symbols/affinity/circle/blue/coffee.svg +6 -0
- gns3server/symbols/affinity/circle/blue/cog.svg +5 -0
- gns3server/symbols/affinity/circle/blue/communications.svg +5 -0
- gns3server/symbols/affinity/circle/blue/conversation.svg +12 -0
- gns3server/symbols/affinity/circle/blue/dna.svg +7 -0
- gns3server/symbols/affinity/circle/blue/dna2.svg +7 -0
- gns3server/symbols/affinity/circle/blue/docker.svg +11 -0
- gns3server/symbols/affinity/circle/blue/dslam.svg +5 -0
- gns3server/symbols/affinity/circle/blue/factory.svg +6 -0
- gns3server/symbols/affinity/circle/blue/fingerprint.svg +5 -0
- gns3server/symbols/affinity/circle/blue/firewall.svg +5 -0
- gns3server/symbols/affinity/circle/blue/firewall3.svg +5 -0
- gns3server/symbols/affinity/circle/blue/globe.svg +5 -0
- gns3server/symbols/affinity/circle/blue/grid.svg +5 -0
- gns3server/symbols/affinity/circle/blue/grid2.svg +5 -0
- gns3server/symbols/affinity/circle/blue/health.svg +5 -0
- gns3server/symbols/affinity/circle/blue/house.svg +9 -0
- gns3server/symbols/affinity/circle/blue/hub.svg +5 -0
- gns3server/symbols/affinity/circle/blue/inspect.svg +7 -0
- gns3server/symbols/affinity/circle/blue/inspect2.svg +6 -0
- gns3server/symbols/affinity/circle/blue/interconnect.svg +5 -0
- gns3server/symbols/affinity/circle/blue/ip_phone.svg +21 -0
- gns3server/symbols/affinity/circle/blue/isdn.svg +5 -0
- gns3server/symbols/affinity/circle/blue/laptop.svg +6 -0
- gns3server/symbols/affinity/circle/blue/ldap.svg +5 -0
- gns3server/symbols/affinity/circle/blue/light_bulb.svg +11 -0
- gns3server/symbols/affinity/circle/blue/link.svg +5 -0
- gns3server/symbols/affinity/circle/blue/loadbalancer.svg +5 -0
- gns3server/symbols/affinity/circle/blue/nas.svg +5 -0
- gns3server/symbols/affinity/circle/blue/nat.svg +60 -0
- gns3server/symbols/affinity/circle/blue/nat2.svg +55 -0
- gns3server/symbols/affinity/circle/blue/office.svg +5 -0
- gns3server/symbols/affinity/circle/blue/optical.svg +8 -0
- gns3server/symbols/affinity/circle/blue/phone_cloud.svg +6 -0
- gns3server/symbols/affinity/circle/blue/phone_old.svg +5 -0
- gns3server/symbols/affinity/circle/blue/phone_wireless.svg +8 -0
- gns3server/symbols/affinity/circle/blue/pinpoint.svg +5 -0
- gns3server/symbols/affinity/circle/blue/printer.svg +7 -0
- gns3server/symbols/affinity/circle/blue/rj45.svg +5 -0
- gns3server/symbols/affinity/circle/blue/router.svg +5 -0
- gns3server/symbols/affinity/circle/blue/router2.svg +5 -0
- gns3server/symbols/affinity/circle/blue/router_cloud.svg +6 -0
- gns3server/symbols/affinity/circle/blue/satellite.svg +6 -0
- gns3server/symbols/affinity/circle/blue/satellite_dish.svg +7 -0
- gns3server/symbols/affinity/circle/blue/scull.svg +8 -0
- gns3server/symbols/affinity/circle/blue/server.svg +5 -0
- gns3server/symbols/affinity/circle/blue/server_cluster.svg +7 -0
- gns3server/symbols/affinity/circle/blue/shield.svg +7 -0
- gns3server/symbols/affinity/circle/blue/statistics.svg +7 -0
- gns3server/symbols/affinity/circle/blue/storage.svg +5 -0
- gns3server/symbols/affinity/circle/blue/switch.svg +8 -0
- gns3server/symbols/affinity/circle/blue/switch_multilayer.svg +5 -0
- gns3server/symbols/affinity/circle/blue/tablet.svg +11 -0
- gns3server/symbols/affinity/circle/blue/template.svg +4 -0
- gns3server/symbols/affinity/circle/blue/tree.svg +5 -0
- gns3server/symbols/affinity/circle/blue/user.svg +7 -0
- gns3server/symbols/affinity/circle/blue/virtualbox.svg +7 -0
- gns3server/symbols/affinity/circle/blue/vm.svg +7 -0
- gns3server/symbols/affinity/circle/blue/vmware.svg +7 -0
- gns3server/symbols/affinity/circle/blue/vrf.svg +8 -0
- gns3server/symbols/affinity/circle/blue/wifi.svg +5 -0
- gns3server/symbols/affinity/circle/blue/wlc.svg +5 -0
- gns3server/symbols/affinity/circle/blue/xml.svg +5 -0
- gns3server/symbols/affinity/circle/gray/atm.svg +5 -0
- gns3server/symbols/affinity/circle/gray/bug.svg +8 -0
- gns3server/symbols/affinity/circle/gray/camera.svg +5 -0
- gns3server/symbols/affinity/circle/gray/camera_dome.svg +8 -0
- gns3server/symbols/affinity/circle/gray/client.svg +5 -0
- gns3server/symbols/affinity/circle/gray/client_vm.svg +6 -0
- gns3server/symbols/affinity/circle/gray/cloud.svg +5 -0
- gns3server/symbols/affinity/circle/gray/coffee.svg +6 -0
- gns3server/symbols/affinity/circle/gray/cog.svg +5 -0
- gns3server/symbols/affinity/circle/gray/communications.svg +5 -0
- gns3server/symbols/affinity/circle/gray/conversation.svg +12 -0
- gns3server/symbols/affinity/circle/gray/dna.svg +7 -0
- gns3server/symbols/affinity/circle/gray/dna2.svg +7 -0
- gns3server/symbols/affinity/circle/gray/docker.svg +11 -0
- gns3server/symbols/affinity/circle/gray/dslam.svg +5 -0
- gns3server/symbols/affinity/circle/gray/factory.svg +7 -0
- gns3server/symbols/affinity/circle/gray/fingerprint.svg +5 -0
- gns3server/symbols/affinity/circle/gray/firewall.svg +5 -0
- gns3server/symbols/affinity/circle/gray/firewall3.svg +5 -0
- gns3server/symbols/affinity/circle/gray/globe.svg +5 -0
- gns3server/symbols/affinity/circle/gray/grid.svg +5 -0
- gns3server/symbols/affinity/circle/gray/grid2.svg +5 -0
- gns3server/symbols/affinity/circle/gray/health.svg +5 -0
- gns3server/symbols/affinity/circle/gray/house.svg +9 -0
- gns3server/symbols/affinity/circle/gray/hub.svg +5 -0
- gns3server/symbols/affinity/circle/gray/inspect.svg +7 -0
- gns3server/symbols/affinity/circle/gray/inspect2.svg +6 -0
- gns3server/symbols/affinity/circle/gray/interconnect.svg +5 -0
- gns3server/symbols/affinity/circle/gray/ip_phone.svg +21 -0
- gns3server/symbols/affinity/circle/gray/isdn.svg +5 -0
- gns3server/symbols/affinity/circle/gray/laptop.svg +6 -0
- gns3server/symbols/affinity/circle/gray/ldap.svg +5 -0
- gns3server/symbols/affinity/circle/gray/light_bulb.svg +11 -0
- gns3server/symbols/affinity/circle/gray/link.svg +5 -0
- gns3server/symbols/affinity/circle/gray/loadbalancer.svg +5 -0
- gns3server/symbols/affinity/circle/gray/nas.svg +5 -0
- gns3server/symbols/affinity/circle/gray/nat.svg +60 -0
- gns3server/symbols/affinity/circle/gray/nat2.svg +55 -0
- gns3server/symbols/affinity/circle/gray/office.svg +5 -0
- gns3server/symbols/affinity/circle/gray/optical.svg +8 -0
- gns3server/symbols/affinity/circle/gray/phone_cloud.svg +6 -0
- gns3server/symbols/affinity/circle/gray/phone_old.svg +5 -0
- gns3server/symbols/affinity/circle/gray/phone_wireless.svg +8 -0
- gns3server/symbols/affinity/circle/gray/pinpoint.svg +5 -0
- gns3server/symbols/affinity/circle/gray/printer.svg +25 -0
- gns3server/symbols/affinity/circle/gray/rj45.svg +5 -0
- gns3server/symbols/affinity/circle/gray/router.svg +5 -0
- gns3server/symbols/affinity/circle/gray/router2.svg +5 -0
- gns3server/symbols/affinity/circle/gray/router_cloud.svg +6 -0
- gns3server/symbols/affinity/circle/gray/satellite.svg +6 -0
- gns3server/symbols/affinity/circle/gray/satellite_dish.svg +7 -0
- gns3server/symbols/affinity/circle/gray/scull.svg +8 -0
- gns3server/symbols/affinity/circle/gray/server.svg +5 -0
- gns3server/symbols/affinity/circle/gray/server_cluster.svg +7 -0
- gns3server/symbols/affinity/circle/gray/shield.svg +7 -0
- gns3server/symbols/affinity/circle/gray/statistics.svg +7 -0
- gns3server/symbols/affinity/circle/gray/storage.svg +5 -0
- gns3server/symbols/affinity/circle/gray/switch.svg +8 -0
- gns3server/symbols/affinity/circle/gray/switch_multilayer.svg +5 -0
- gns3server/symbols/affinity/circle/gray/tablet.svg +11 -0
- gns3server/symbols/affinity/circle/gray/template.svg +4 -0
- gns3server/symbols/affinity/circle/gray/tree.svg +5 -0
- gns3server/symbols/affinity/circle/gray/user.svg +7 -0
- gns3server/symbols/affinity/circle/gray/virtualbox.svg +7 -0
- gns3server/symbols/affinity/circle/gray/vm.svg +7 -0
- gns3server/symbols/affinity/circle/gray/vmware.svg +7 -0
- gns3server/symbols/affinity/circle/gray/vrf.svg +8 -0
- gns3server/symbols/affinity/circle/gray/wifi.svg +5 -0
- gns3server/symbols/affinity/circle/gray/wlc.svg +5 -0
- gns3server/symbols/affinity/circle/gray/xml.svg +5 -0
- gns3server/symbols/affinity/circle/green/atm.svg +5 -0
- gns3server/symbols/affinity/circle/green/bug.svg +8 -0
- gns3server/symbols/affinity/circle/green/camera.svg +5 -0
- gns3server/symbols/affinity/circle/green/camera_dome.svg +8 -0
- gns3server/symbols/affinity/circle/green/client.svg +5 -0
- gns3server/symbols/affinity/circle/green/client_vm.svg +6 -0
- gns3server/symbols/affinity/circle/green/cloud.svg +5 -0
- gns3server/symbols/affinity/circle/green/coffee.svg +6 -0
- gns3server/symbols/affinity/circle/green/cog.svg +5 -0
- gns3server/symbols/affinity/circle/green/communications.svg +5 -0
- gns3server/symbols/affinity/circle/green/conversation.svg +12 -0
- gns3server/symbols/affinity/circle/green/dna.svg +7 -0
- gns3server/symbols/affinity/circle/green/dna2.svg +7 -0
- gns3server/symbols/affinity/circle/green/docker.svg +11 -0
- gns3server/symbols/affinity/circle/green/dslam.svg +5 -0
- gns3server/symbols/affinity/circle/green/factory.svg +6 -0
- gns3server/symbols/affinity/circle/green/fingerprint.svg +5 -0
- gns3server/symbols/affinity/circle/green/firewall.svg +5 -0
- gns3server/symbols/affinity/circle/green/firewall3.svg +5 -0
- gns3server/symbols/affinity/circle/green/globe.svg +5 -0
- gns3server/symbols/affinity/circle/green/grid.svg +5 -0
- gns3server/symbols/affinity/circle/green/grid2.svg +5 -0
- gns3server/symbols/affinity/circle/green/health.svg +5 -0
- gns3server/symbols/affinity/circle/green/house.svg +9 -0
- gns3server/symbols/affinity/circle/green/hub.svg +5 -0
- gns3server/symbols/affinity/circle/green/inspect.svg +7 -0
- gns3server/symbols/affinity/circle/green/inspect2.svg +6 -0
- gns3server/symbols/affinity/circle/green/interconnect.svg +5 -0
- gns3server/symbols/affinity/circle/green/ip_phone.svg +21 -0
- gns3server/symbols/affinity/circle/green/isdn.svg +5 -0
- gns3server/symbols/affinity/circle/green/laptop.svg +6 -0
- gns3server/symbols/affinity/circle/green/ldap.svg +5 -0
- gns3server/symbols/affinity/circle/green/light_bulb.svg +11 -0
- gns3server/symbols/affinity/circle/green/link.svg +5 -0
- gns3server/symbols/affinity/circle/green/loadbalancer.svg +5 -0
- gns3server/symbols/affinity/circle/green/nas.svg +5 -0
- gns3server/symbols/affinity/circle/green/nat.svg +60 -0
- gns3server/symbols/affinity/circle/green/nat2.svg +55 -0
- gns3server/symbols/affinity/circle/green/office.svg +5 -0
- gns3server/symbols/affinity/circle/green/optical.svg +8 -0
- gns3server/symbols/affinity/circle/green/phone_cloud.svg +6 -0
- gns3server/symbols/affinity/circle/green/phone_old.svg +5 -0
- gns3server/symbols/affinity/circle/green/phone_wireless.svg +8 -0
- gns3server/symbols/affinity/circle/green/pinpoint.svg +5 -0
- gns3server/symbols/affinity/circle/green/printer.svg +7 -0
- gns3server/symbols/affinity/circle/green/rj45.svg +5 -0
- gns3server/symbols/affinity/circle/green/router.svg +5 -0
- gns3server/symbols/affinity/circle/green/router2.svg +5 -0
- gns3server/symbols/affinity/circle/green/router_cloud.svg +6 -0
- gns3server/symbols/affinity/circle/green/satellite.svg +6 -0
- gns3server/symbols/affinity/circle/green/satellite_dish.svg +7 -0
- gns3server/symbols/affinity/circle/green/scull.svg +8 -0
- gns3server/symbols/affinity/circle/green/server.svg +5 -0
- gns3server/symbols/affinity/circle/green/server_cluster.svg +7 -0
- gns3server/symbols/affinity/circle/green/shield.svg +7 -0
- gns3server/symbols/affinity/circle/green/statistics.svg +7 -0
- gns3server/symbols/affinity/circle/green/storage.svg +5 -0
- gns3server/symbols/affinity/circle/green/switch.svg +8 -0
- gns3server/symbols/affinity/circle/green/switch_multilayer.svg +5 -0
- gns3server/symbols/affinity/circle/green/tablet.svg +11 -0
- gns3server/symbols/affinity/circle/green/template.svg +4 -0
- gns3server/symbols/affinity/circle/green/tree.svg +5 -0
- gns3server/symbols/affinity/circle/green/user.svg +7 -0
- gns3server/symbols/affinity/circle/green/virtualbox.svg +7 -0
- gns3server/symbols/affinity/circle/green/vm.svg +7 -0
- gns3server/symbols/affinity/circle/green/vmware.svg +7 -0
- gns3server/symbols/affinity/circle/green/vrf.svg +8 -0
- gns3server/symbols/affinity/circle/green/wifi.svg +5 -0
- gns3server/symbols/affinity/circle/green/wlc.svg +5 -0
- gns3server/symbols/affinity/circle/green/xml.svg +5 -0
- gns3server/symbols/affinity/circle/red/atm.svg +5 -0
- gns3server/symbols/affinity/circle/red/bug.svg +8 -0
- gns3server/symbols/affinity/circle/red/camera.svg +5 -0
- gns3server/symbols/affinity/circle/red/camera_dome.svg +8 -0
- gns3server/symbols/affinity/circle/red/client.svg +5 -0
- gns3server/symbols/affinity/circle/red/client_vm.svg +6 -0
- gns3server/symbols/affinity/circle/red/cloud.svg +5 -0
- gns3server/symbols/affinity/circle/red/coffee.svg +6 -0
- gns3server/symbols/affinity/circle/red/cog.svg +5 -0
- gns3server/symbols/affinity/circle/red/communications.svg +5 -0
- gns3server/symbols/affinity/circle/red/conversation.svg +12 -0
- gns3server/symbols/affinity/circle/red/dna.svg +7 -0
- gns3server/symbols/affinity/circle/red/dna2.svg +7 -0
- gns3server/symbols/affinity/circle/red/docker.svg +11 -0
- gns3server/symbols/affinity/circle/red/dslam.svg +5 -0
- gns3server/symbols/affinity/circle/red/factory.svg +6 -0
- gns3server/symbols/affinity/circle/red/fingerprint.svg +5 -0
- gns3server/symbols/affinity/circle/red/firewall.svg +5 -0
- gns3server/symbols/affinity/circle/red/firewall3.svg +5 -0
- gns3server/symbols/affinity/circle/red/globe.svg +5 -0
- gns3server/symbols/affinity/circle/red/grid.svg +5 -0
- gns3server/symbols/affinity/circle/red/grid2.svg +5 -0
- gns3server/symbols/affinity/circle/red/health.svg +5 -0
- gns3server/symbols/affinity/circle/red/house.svg +9 -0
- gns3server/symbols/affinity/circle/red/hub.svg +5 -0
- gns3server/symbols/affinity/circle/red/inspect.svg +7 -0
- gns3server/symbols/affinity/circle/red/inspect2.svg +6 -0
- gns3server/symbols/affinity/circle/red/interconnect.svg +5 -0
- gns3server/symbols/affinity/circle/red/ip_phone.svg +21 -0
- gns3server/symbols/affinity/circle/red/isdn.svg +5 -0
- gns3server/symbols/affinity/circle/red/laptop.svg +6 -0
- gns3server/symbols/affinity/circle/red/ldap.svg +5 -0
- gns3server/symbols/affinity/circle/red/light_bulb.svg +11 -0
- gns3server/symbols/affinity/circle/red/link.svg +5 -0
- gns3server/symbols/affinity/circle/red/loadbalancer.svg +5 -0
- gns3server/symbols/affinity/circle/red/nas.svg +5 -0
- gns3server/symbols/affinity/circle/red/nat.svg +60 -0
- gns3server/symbols/affinity/circle/red/nat2.svg +55 -0
- gns3server/symbols/affinity/circle/red/office.svg +5 -0
- gns3server/symbols/affinity/circle/red/optical.svg +8 -0
- gns3server/symbols/affinity/circle/red/phone_cloud.svg +6 -0
- gns3server/symbols/affinity/circle/red/phone_old.svg +5 -0
- gns3server/symbols/affinity/circle/red/phone_wireless.svg +8 -0
- gns3server/symbols/affinity/circle/red/pinpoint.svg +5 -0
- gns3server/symbols/affinity/circle/red/printer.svg +7 -0
- gns3server/symbols/affinity/circle/red/rj45.svg +5 -0
- gns3server/symbols/affinity/circle/red/router.svg +5 -0
- gns3server/symbols/affinity/circle/red/router2.svg +5 -0
- gns3server/symbols/affinity/circle/red/router_cloud.svg +6 -0
- gns3server/symbols/affinity/circle/red/satellite.svg +6 -0
- gns3server/symbols/affinity/circle/red/satellite_dish.svg +7 -0
- gns3server/symbols/affinity/circle/red/scull.svg +8 -0
- gns3server/symbols/affinity/circle/red/server.svg +5 -0
- gns3server/symbols/affinity/circle/red/server_cluster.svg +7 -0
- gns3server/symbols/affinity/circle/red/shield.svg +7 -0
- gns3server/symbols/affinity/circle/red/statistics.svg +7 -0
- gns3server/symbols/affinity/circle/red/storage.svg +5 -0
- gns3server/symbols/affinity/circle/red/switch.svg +8 -0
- gns3server/symbols/affinity/circle/red/switch_multilayer.svg +5 -0
- gns3server/symbols/affinity/circle/red/tablet.svg +11 -0
- gns3server/symbols/affinity/circle/red/template.svg +4 -0
- gns3server/symbols/affinity/circle/red/tree.svg +5 -0
- gns3server/symbols/affinity/circle/red/user.svg +7 -0
- gns3server/symbols/affinity/circle/red/virtualbox.svg +7 -0
- gns3server/symbols/affinity/circle/red/vm.svg +7 -0
- gns3server/symbols/affinity/circle/red/vmware.svg +7 -0
- gns3server/symbols/affinity/circle/red/vrf.svg +8 -0
- gns3server/symbols/affinity/circle/red/wifi.svg +5 -0
- gns3server/symbols/affinity/circle/red/wlc.svg +5 -0
- gns3server/symbols/affinity/circle/red/xml.svg +5 -0
- gns3server/symbols/affinity/square/blue/atm.svg +5 -0
- gns3server/symbols/affinity/square/blue/bug.svg +5 -0
- gns3server/symbols/affinity/square/blue/camera.svg +12 -0
- gns3server/symbols/affinity/square/blue/camera_dome.svg +8 -0
- gns3server/symbols/affinity/square/blue/client.svg +8 -0
- gns3server/symbols/affinity/square/blue/client_vm.svg +8 -0
- gns3server/symbols/affinity/square/blue/cloud.svg +12 -0
- gns3server/symbols/affinity/square/blue/coffee.svg +5 -0
- gns3server/symbols/affinity/square/blue/cog.svg +8 -0
- gns3server/symbols/affinity/square/blue/communications.svg +8 -0
- gns3server/symbols/affinity/square/blue/conversation.svg +12 -0
- gns3server/symbols/affinity/square/blue/dna.svg +7 -0
- gns3server/symbols/affinity/square/blue/dna2.svg +7 -0
- gns3server/symbols/affinity/square/blue/docker.svg +11 -0
- gns3server/symbols/affinity/square/blue/dslam.svg +8 -0
- gns3server/symbols/affinity/square/blue/factory.svg +5 -0
- gns3server/symbols/affinity/square/blue/fingerprint.svg +9 -0
- gns3server/symbols/affinity/square/blue/firewall.svg +7 -0
- gns3server/symbols/affinity/square/blue/firewall3.svg +6 -0
- gns3server/symbols/affinity/square/blue/globe.svg +5 -0
- gns3server/symbols/affinity/square/blue/grid.svg +7 -0
- gns3server/symbols/affinity/square/blue/grid2.svg +7 -0
- gns3server/symbols/affinity/square/blue/health.svg +5 -0
- gns3server/symbols/affinity/square/blue/house.svg +6 -0
- gns3server/symbols/affinity/square/blue/hub.svg +7 -0
- gns3server/symbols/affinity/square/blue/inspect.svg +5 -0
- gns3server/symbols/affinity/square/blue/inspect2.svg +9 -0
- gns3server/symbols/affinity/square/blue/interconnect.svg +8 -0
- gns3server/symbols/affinity/square/blue/ip_phone.svg +23 -0
- gns3server/symbols/affinity/square/blue/isdn.svg +7 -0
- gns3server/symbols/affinity/square/blue/laptop.svg +8 -0
- gns3server/symbols/affinity/square/blue/ldap.svg +5 -0
- gns3server/symbols/affinity/square/blue/light_bulb.svg +11 -0
- gns3server/symbols/affinity/square/blue/link.svg +5 -0
- gns3server/symbols/affinity/square/blue/loadbalancer.svg +5 -0
- gns3server/symbols/affinity/square/blue/nas.svg +7 -0
- gns3server/symbols/affinity/square/blue/nat.svg +58 -0
- gns3server/symbols/affinity/square/blue/nat2.svg +74 -0
- gns3server/symbols/affinity/square/blue/office.svg +5 -0
- gns3server/symbols/affinity/square/blue/optical.svg +8 -0
- gns3server/symbols/affinity/square/blue/phone_cloud.svg +8 -0
- gns3server/symbols/affinity/square/blue/phone_old.svg +7 -0
- gns3server/symbols/affinity/square/blue/phone_wireless.svg +10 -0
- gns3server/symbols/affinity/square/blue/pinpoint.svg +9 -0
- gns3server/symbols/affinity/square/blue/printer.svg +27 -0
- gns3server/symbols/affinity/square/blue/rj45.svg +14 -0
- gns3server/symbols/affinity/square/blue/router.svg +7 -0
- gns3server/symbols/affinity/square/blue/router2.svg +5 -0
- gns3server/symbols/affinity/square/blue/router_cloud.svg +7 -0
- gns3server/symbols/affinity/square/blue/satellite.svg +8 -0
- gns3server/symbols/affinity/square/blue/satellite_dish.svg +7 -0
- gns3server/symbols/affinity/square/blue/scull.svg +10 -0
- gns3server/symbols/affinity/square/blue/server.svg +5 -0
- gns3server/symbols/affinity/square/blue/server_cluster.svg +9 -0
- gns3server/symbols/affinity/square/blue/shield.svg +5 -0
- gns3server/symbols/affinity/square/blue/statistics.svg +7 -0
- gns3server/symbols/affinity/square/blue/storage.svg +7 -0
- gns3server/symbols/affinity/square/blue/switch.svg +10 -0
- gns3server/symbols/affinity/square/blue/switch_multilayer.svg +8 -0
- gns3server/symbols/affinity/square/blue/tablet.svg +9 -0
- gns3server/symbols/affinity/square/blue/template.svg +4 -0
- gns3server/symbols/affinity/square/blue/tree.svg +5 -0
- gns3server/symbols/affinity/square/blue/user.svg +7 -0
- gns3server/symbols/affinity/square/blue/virtualbox.svg +7 -0
- gns3server/symbols/affinity/square/blue/vm.svg +7 -0
- gns3server/symbols/affinity/square/blue/vmware.svg +7 -0
- gns3server/symbols/affinity/square/blue/vrf.svg +5 -0
- gns3server/symbols/affinity/square/blue/wifi.svg +13 -0
- gns3server/symbols/affinity/square/blue/wlc.svg +7 -0
- gns3server/symbols/affinity/square/blue/xml.svg +10 -0
- gns3server/symbols/affinity/square/gray/atm.svg +5 -0
- gns3server/symbols/affinity/square/gray/bug.svg +5 -0
- gns3server/symbols/affinity/square/gray/camera.svg +12 -0
- gns3server/symbols/affinity/square/gray/camera_dome.svg +8 -0
- gns3server/symbols/affinity/square/gray/client.svg +8 -0
- gns3server/symbols/affinity/square/gray/client_vm.svg +8 -0
- gns3server/symbols/affinity/square/gray/cloud.svg +12 -0
- gns3server/symbols/affinity/square/gray/coffee.svg +5 -0
- gns3server/symbols/affinity/square/gray/cog.svg +8 -0
- gns3server/symbols/affinity/square/gray/communications.svg +8 -0
- gns3server/symbols/affinity/square/gray/conversation.svg +12 -0
- gns3server/symbols/affinity/square/gray/dna.svg +7 -0
- gns3server/symbols/affinity/square/gray/dna2.svg +7 -0
- gns3server/symbols/affinity/square/gray/docker.svg +11 -0
- gns3server/symbols/affinity/square/gray/dslam.svg +8 -0
- gns3server/symbols/affinity/square/gray/factory.svg +5 -0
- gns3server/symbols/affinity/square/gray/fingerprint.svg +9 -0
- gns3server/symbols/affinity/square/gray/firewall.svg +7 -0
- gns3server/symbols/affinity/square/gray/firewall3.svg +6 -0
- gns3server/symbols/affinity/square/gray/globe.svg +5 -0
- gns3server/symbols/affinity/square/gray/grid.svg +7 -0
- gns3server/symbols/affinity/square/gray/grid2.svg +7 -0
- gns3server/symbols/affinity/square/gray/health.svg +5 -0
- gns3server/symbols/affinity/square/gray/house.svg +6 -0
- gns3server/symbols/affinity/square/gray/hub.svg +7 -0
- gns3server/symbols/affinity/square/gray/inspect.svg +5 -0
- gns3server/symbols/affinity/square/gray/inspect2.svg +9 -0
- gns3server/symbols/affinity/square/gray/interconnect.svg +8 -0
- gns3server/symbols/affinity/square/gray/ip_phone.svg +23 -0
- gns3server/symbols/affinity/square/gray/isdn.svg +7 -0
- gns3server/symbols/affinity/square/gray/laptop.svg +8 -0
- gns3server/symbols/affinity/square/gray/ldap.svg +5 -0
- gns3server/symbols/affinity/square/gray/light_bulb.svg +11 -0
- gns3server/symbols/affinity/square/gray/link.svg +5 -0
- gns3server/symbols/affinity/square/gray/loadbalancer.svg +5 -0
- gns3server/symbols/affinity/square/gray/nas.svg +7 -0
- gns3server/symbols/affinity/square/gray/nat.svg +58 -0
- gns3server/symbols/affinity/square/gray/nat2.svg +74 -0
- gns3server/symbols/affinity/square/gray/office.svg +5 -0
- gns3server/symbols/affinity/square/gray/optical.svg +8 -0
- gns3server/symbols/affinity/square/gray/phone_cloud.svg +8 -0
- gns3server/symbols/affinity/square/gray/phone_old.svg +7 -0
- gns3server/symbols/affinity/square/gray/phone_wireless.svg +10 -0
- gns3server/symbols/affinity/square/gray/pinpoint.svg +9 -0
- gns3server/symbols/affinity/square/gray/printer.svg +27 -0
- gns3server/symbols/affinity/square/gray/rj45.svg +14 -0
- gns3server/symbols/affinity/square/gray/router.svg +7 -0
- gns3server/symbols/affinity/square/gray/router2.svg +5 -0
- gns3server/symbols/affinity/square/gray/router_cloud.svg +7 -0
- gns3server/symbols/affinity/square/gray/satellite.svg +8 -0
- gns3server/symbols/affinity/square/gray/satellite_dish.svg +7 -0
- gns3server/symbols/affinity/square/gray/scull.svg +10 -0
- gns3server/symbols/affinity/square/gray/server.svg +5 -0
- gns3server/symbols/affinity/square/gray/server_cluster.svg +9 -0
- gns3server/symbols/affinity/square/gray/shield.svg +5 -0
- gns3server/symbols/affinity/square/gray/statistics.svg +7 -0
- gns3server/symbols/affinity/square/gray/storage.svg +5 -0
- gns3server/symbols/affinity/square/gray/switch.svg +10 -0
- gns3server/symbols/affinity/square/gray/switch_multilayer.svg +9 -0
- gns3server/symbols/affinity/square/gray/tablet.svg +9 -0
- gns3server/symbols/affinity/square/gray/template.svg +4 -0
- gns3server/symbols/affinity/square/gray/tree.svg +5 -0
- gns3server/symbols/affinity/square/gray/user.svg +7 -0
- gns3server/symbols/affinity/square/gray/virtualbox.svg +7 -0
- gns3server/symbols/affinity/square/gray/vm.svg +7 -0
- gns3server/symbols/affinity/square/gray/vmware.svg +7 -0
- gns3server/symbols/affinity/square/gray/vrf.svg +5 -0
- gns3server/symbols/affinity/square/gray/wifi.svg +13 -0
- gns3server/symbols/affinity/square/gray/wlc.svg +7 -0
- gns3server/symbols/affinity/square/gray/xml.svg +10 -0
- gns3server/symbols/affinity/square/green/atm.svg +5 -0
- gns3server/symbols/affinity/square/green/bug.svg +5 -0
- gns3server/symbols/affinity/square/green/camera.svg +5 -0
- gns3server/symbols/affinity/square/green/camera_dome.svg +8 -0
- gns3server/symbols/affinity/square/green/client.svg +5 -0
- gns3server/symbols/affinity/square/green/client_vm.svg +6 -0
- gns3server/symbols/affinity/square/green/cloud.svg +12 -0
- gns3server/symbols/affinity/square/green/coffee.svg +5 -0
- gns3server/symbols/affinity/square/green/cog.svg +5 -0
- gns3server/symbols/affinity/square/green/communications.svg +5 -0
- gns3server/symbols/affinity/square/green/conversation.svg +12 -0
- gns3server/symbols/affinity/square/green/dna.svg +7 -0
- gns3server/symbols/affinity/square/green/dna2.svg +7 -0
- gns3server/symbols/affinity/square/green/docker.svg +11 -0
- gns3server/symbols/affinity/square/green/dslam.svg +5 -0
- gns3server/symbols/affinity/square/green/factory.svg +5 -0
- gns3server/symbols/affinity/square/green/fingerprint.svg +5 -0
- gns3server/symbols/affinity/square/green/firewall.svg +5 -0
- gns3server/symbols/affinity/square/green/firewall3.svg +5 -0
- gns3server/symbols/affinity/square/green/globe.svg +5 -0
- gns3server/symbols/affinity/square/green/grid.svg +5 -0
- gns3server/symbols/affinity/square/green/grid2.svg +5 -0
- gns3server/symbols/affinity/square/green/health.svg +5 -0
- gns3server/symbols/affinity/square/green/house.svg +6 -0
- gns3server/symbols/affinity/square/green/hub.svg +5 -0
- gns3server/symbols/affinity/square/green/inspect.svg +5 -0
- gns3server/symbols/affinity/square/green/inspect2.svg +5 -0
- gns3server/symbols/affinity/square/green/interconnect.svg +5 -0
- gns3server/symbols/affinity/square/green/ip_phone.svg +7 -0
- gns3server/symbols/affinity/square/green/isdn.svg +5 -0
- gns3server/symbols/affinity/square/green/laptop.svg +8 -0
- gns3server/symbols/affinity/square/green/ldap.svg +5 -0
- gns3server/symbols/affinity/square/green/light_bulb.svg +5 -0
- gns3server/symbols/affinity/square/green/link.svg +5 -0
- gns3server/symbols/affinity/square/green/loadbalancer.svg +5 -0
- gns3server/symbols/affinity/square/green/nas.svg +5 -0
- gns3server/symbols/affinity/square/green/nat.svg +58 -0
- gns3server/symbols/affinity/square/green/nat2.svg +74 -0
- gns3server/symbols/affinity/square/green/office.svg +5 -0
- gns3server/symbols/affinity/square/green/optical.svg +8 -0
- gns3server/symbols/affinity/square/green/phone_cloud.svg +6 -0
- gns3server/symbols/affinity/square/green/phone_old.svg +5 -0
- gns3server/symbols/affinity/square/green/phone_wireless.svg +5 -0
- gns3server/symbols/affinity/square/green/pinpoint.svg +5 -0
- gns3server/symbols/affinity/square/green/printer.svg +27 -0
- gns3server/symbols/affinity/square/green/rj45.svg +5 -0
- gns3server/symbols/affinity/square/green/router.svg +5 -0
- gns3server/symbols/affinity/square/green/router2.svg +5 -0
- gns3server/symbols/affinity/square/green/router_cloud.svg +6 -0
- gns3server/symbols/affinity/square/green/satellite.svg +5 -0
- gns3server/symbols/affinity/square/green/satellite_dish.svg +5 -0
- gns3server/symbols/affinity/square/green/scull.svg +8 -0
- gns3server/symbols/affinity/square/green/server.svg +5 -0
- gns3server/symbols/affinity/square/green/server_cluster.svg +7 -0
- gns3server/symbols/affinity/square/green/shield.svg +5 -0
- gns3server/symbols/affinity/square/green/statistics.svg +5 -0
- gns3server/symbols/affinity/square/green/storage.svg +5 -0
- gns3server/symbols/affinity/square/green/switch.svg +10 -0
- gns3server/symbols/affinity/square/green/switch_multilayer.svg +5 -0
- gns3server/symbols/affinity/square/green/tablet.svg +9 -0
- gns3server/symbols/affinity/square/green/template.svg +4 -0
- gns3server/symbols/affinity/square/green/tree.svg +5 -0
- gns3server/symbols/affinity/square/green/user.svg +7 -0
- gns3server/symbols/affinity/square/green/virtualbox.svg +7 -0
- gns3server/symbols/affinity/square/green/vm.svg +7 -0
- gns3server/symbols/affinity/square/green/vmware.svg +7 -0
- gns3server/symbols/affinity/square/green/vrf.svg +5 -0
- gns3server/symbols/affinity/square/green/wifi.svg +5 -0
- gns3server/symbols/affinity/square/green/wlc.svg +5 -0
- gns3server/symbols/affinity/square/green/xml.svg +5 -0
- gns3server/symbols/affinity/square/red/atm.svg +5 -0
- gns3server/symbols/affinity/square/red/bug.svg +5 -0
- gns3server/symbols/affinity/square/red/camera.svg +12 -0
- gns3server/symbols/affinity/square/red/camera_dome.svg +8 -0
- gns3server/symbols/affinity/square/red/client.svg +8 -0
- gns3server/symbols/affinity/square/red/client_vm.svg +8 -0
- gns3server/symbols/affinity/square/red/cloud.svg +12 -0
- gns3server/symbols/affinity/square/red/coffee.svg +5 -0
- gns3server/symbols/affinity/square/red/cog.svg +8 -0
- gns3server/symbols/affinity/square/red/communications.svg +8 -0
- gns3server/symbols/affinity/square/red/conversation.svg +12 -0
- gns3server/symbols/affinity/square/red/dna.svg +7 -0
- gns3server/symbols/affinity/square/red/dna2.svg +7 -0
- gns3server/symbols/affinity/square/red/docker.svg +11 -0
- gns3server/symbols/affinity/square/red/dslam.svg +8 -0
- gns3server/symbols/affinity/square/red/factory.svg +5 -0
- gns3server/symbols/affinity/square/red/fingerprint.svg +9 -0
- gns3server/symbols/affinity/square/red/firewall.svg +7 -0
- gns3server/symbols/affinity/square/red/firewall3.svg +5 -0
- gns3server/symbols/affinity/square/red/globe.svg +5 -0
- gns3server/symbols/affinity/square/red/grid.svg +7 -0
- gns3server/symbols/affinity/square/red/grid2.svg +7 -0
- gns3server/symbols/affinity/square/red/health.svg +5 -0
- gns3server/symbols/affinity/square/red/house.svg +6 -0
- gns3server/symbols/affinity/square/red/hub.svg +7 -0
- gns3server/symbols/affinity/square/red/inspect.svg +5 -0
- gns3server/symbols/affinity/square/red/inspect2.svg +9 -0
- gns3server/symbols/affinity/square/red/interconnect.svg +8 -0
- gns3server/symbols/affinity/square/red/ip_phone.svg +7 -0
- gns3server/symbols/affinity/square/red/isdn.svg +7 -0
- gns3server/symbols/affinity/square/red/laptop.svg +8 -0
- gns3server/symbols/affinity/square/red/ldap.svg +5 -0
- gns3server/symbols/affinity/square/red/light_bulb.svg +5 -0
- gns3server/symbols/affinity/square/red/link.svg +5 -0
- gns3server/symbols/affinity/square/red/loadbalancer.svg +5 -0
- gns3server/symbols/affinity/square/red/nas.svg +7 -0
- gns3server/symbols/affinity/square/red/nat.svg +58 -0
- gns3server/symbols/affinity/square/red/nat2.svg +74 -0
- gns3server/symbols/affinity/square/red/office.svg +5 -0
- gns3server/symbols/affinity/square/red/optical.svg +8 -0
- gns3server/symbols/affinity/square/red/phone_cloud.svg +6 -0
- gns3server/symbols/affinity/square/red/phone_old.svg +5 -0
- gns3server/symbols/affinity/square/red/phone_wireless.svg +5 -0
- gns3server/symbols/affinity/square/red/pinpoint.svg +9 -0
- gns3server/symbols/affinity/square/red/printer.svg +27 -0
- gns3server/symbols/affinity/square/red/rj45.svg +14 -0
- gns3server/symbols/affinity/square/red/router.svg +7 -0
- gns3server/symbols/affinity/square/red/router2.svg +5 -0
- gns3server/symbols/affinity/square/red/router_cloud.svg +6 -0
- gns3server/symbols/affinity/square/red/satellite.svg +8 -0
- gns3server/symbols/affinity/square/red/satellite_dish.svg +5 -0
- gns3server/symbols/affinity/square/red/scull.svg +10 -0
- gns3server/symbols/affinity/square/red/server.svg +5 -0
- gns3server/symbols/affinity/square/red/server_cluster.svg +9 -0
- gns3server/symbols/affinity/square/red/shield.svg +5 -0
- gns3server/symbols/affinity/square/red/statistics.svg +5 -0
- gns3server/symbols/affinity/square/red/storage.svg +7 -0
- gns3server/symbols/affinity/square/red/switch.svg +10 -0
- gns3server/symbols/affinity/square/red/switch_multilayer.svg +9 -0
- gns3server/symbols/affinity/square/red/tablet.svg +9 -0
- gns3server/symbols/affinity/square/red/template.svg +4 -0
- gns3server/symbols/affinity/square/red/tree.svg +5 -0
- gns3server/symbols/affinity/square/red/user.svg +7 -0
- gns3server/symbols/affinity/square/red/virtualbox.svg +7 -0
- gns3server/symbols/affinity/square/red/vm.svg +7 -0
- gns3server/symbols/affinity/square/red/vmware.svg +7 -0
- gns3server/symbols/affinity/square/red/vrf.svg +5 -0
- gns3server/symbols/affinity/square/red/wifi.svg +13 -0
- gns3server/symbols/affinity/square/red/wlc.svg +7 -0
- gns3server/symbols/affinity/square/red/xml.svg +10 -0
- gns3server/symbols/classic/PBX.svg +304 -0
- gns3server/symbols/classic/PIX_firewall.svg +187 -0
- gns3server/symbols/classic/access_point.svg +516 -0
- gns3server/symbols/classic/access_server.svg +270 -0
- gns3server/symbols/classic/asa.svg +424 -0
- gns3server/symbols/classic/atm_bridge.svg +219 -0
- gns3server/symbols/classic/atm_switch.svg +243 -0
- gns3server/symbols/classic/call_manager.svg +228 -0
- gns3server/symbols/classic/cloud.svg +163 -0
- gns3server/symbols/classic/computer.svg +560 -0
- gns3server/symbols/classic/docker_guest.svg +657 -0
- gns3server/symbols/classic/dslam.svg +155 -0
- gns3server/symbols/classic/edge_label_switch_router.svg +216 -0
- gns3server/symbols/classic/ethernet_switch.svg +228 -0
- gns3server/symbols/classic/firewall.svg +187 -0
- gns3server/symbols/classic/frame_relay_switch.svg +263 -0
- gns3server/symbols/classic/gateway.svg +309 -0
- gns3server/symbols/classic/hub.svg +204 -0
- gns3server/symbols/classic/ids.svg +310 -0
- gns3server/symbols/classic/iosv_l2_virl.svg +286 -0
- gns3server/symbols/classic/iosv_virl.svg +394 -0
- gns3server/symbols/classic/ip_phone.svg +171 -0
- gns3server/symbols/classic/label_switch_router.svg +223 -0
- gns3server/symbols/classic/lightweight_ap.svg +536 -0
- gns3server/symbols/classic/multilayer_switch.svg +317 -0
- gns3server/symbols/classic/nat.svg +207 -0
- gns3server/symbols/classic/optical_router.svg +207 -0
- gns3server/symbols/classic/printer.svg +178 -0
- gns3server/symbols/classic/qemu_guest.svg +1387 -0
- gns3server/symbols/classic/route_switch_processor.svg +395 -0
- gns3server/symbols/classic/router.awp.svg +362 -0
- gns3server/symbols/classic/router.svg +203 -0
- gns3server/symbols/classic/router_firewall.svg +395 -0
- gns3server/symbols/classic/router_netflow.svg +215 -0
- gns3server/symbols/classic/server.svg +226 -0
- gns3server/symbols/classic/sip_server.svg +305 -0
- gns3server/symbols/classic/traceng.svg +610 -0
- gns3server/symbols/classic/vbox_guest.svg +7691 -0
- gns3server/symbols/classic/vmware_guest.svg +572 -0
- gns3server/symbols/classic/voice_access_server.svg +289 -0
- gns3server/symbols/classic/voice_router.svg +223 -0
- gns3server/symbols/classic/vpcs_guest.svg +574 -0
- gns3server/symbols/classic/wlan_controller.svg +528 -0
- gns3server/templates/compute.html +62 -0
- gns3server/templates/controller.html +55 -0
- gns3server/templates/index.html +12 -0
- gns3server/templates/layout.html +20 -0
- gns3server/templates/project.html +91 -0
- gns3server/templates/upload.html +6 -0
- gns3server/utils/__init__.py +123 -0
- gns3server/utils/application_id.py +49 -0
- gns3server/utils/asyncio/__init__.py +148 -0
- gns3server/utils/asyncio/aiozipstream.py +528 -0
- gns3server/utils/asyncio/embed_shell.py +369 -0
- gns3server/utils/asyncio/input_stream.py +408 -0
- gns3server/utils/asyncio/pool.py +69 -0
- gns3server/utils/asyncio/raw_command_server.py +140 -0
- gns3server/utils/asyncio/serial.py +87 -0
- gns3server/utils/asyncio/telnet_server.py +450 -0
- gns3server/utils/cpu_percent.py +46 -0
- gns3server/utils/file_watcher.py +103 -0
- gns3server/utils/get_resource.py +48 -0
- gns3server/utils/hostname.py +112 -0
- gns3server/utils/http_client.py +71 -0
- gns3server/utils/images.py +378 -0
- gns3server/utils/interfaces.py +254 -0
- gns3server/utils/notification_queue.py +79 -0
- gns3server/utils/path.py +76 -0
- gns3server/utils/picture.py +146 -0
- gns3server/utils/qt.py +44 -0
- gns3server/utils/vmnet.py +277 -0
- gns3server/utils/zipfile_zstd/__init__.py +10 -0
- gns3server/utils/zipfile_zstd/_patcher.py +20 -0
- gns3server/utils/zipfile_zstd/_zipfile.py +64 -0
- gns3server/version.py +36 -0
|
@@ -0,0 +1,1255 @@
|
|
|
1
|
+
#
|
|
2
|
+
# Copyright (C) 2014 GNS3 Technologies Inc.
|
|
3
|
+
#
|
|
4
|
+
# This program is free software: you can redistribute it and/or modify
|
|
5
|
+
# it under the terms of the GNU General Public License as published by
|
|
6
|
+
# the Free Software Foundation, either version 3 of the License, or
|
|
7
|
+
# (at your option) any later version.
|
|
8
|
+
#
|
|
9
|
+
# This program is distributed in the hope that it will be useful,
|
|
10
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
11
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
12
|
+
# GNU General Public License for more details.
|
|
13
|
+
#
|
|
14
|
+
# You should have received a copy of the GNU General Public License
|
|
15
|
+
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
16
|
+
|
|
17
|
+
"""
|
|
18
|
+
VirtualBox VM instance.
|
|
19
|
+
"""
|
|
20
|
+
|
|
21
|
+
import re
|
|
22
|
+
import os
|
|
23
|
+
import sys
|
|
24
|
+
import json
|
|
25
|
+
import uuid
|
|
26
|
+
import shlex
|
|
27
|
+
import shutil
|
|
28
|
+
import asyncio
|
|
29
|
+
import tempfile
|
|
30
|
+
import xml.etree.ElementTree as ET
|
|
31
|
+
|
|
32
|
+
from gns3server.utils import parse_version
|
|
33
|
+
from gns3server.utils.asyncio.telnet_server import AsyncioTelnetServer
|
|
34
|
+
from gns3server.utils.asyncio.serial import asyncio_open_serial
|
|
35
|
+
from gns3server.utils.asyncio import locking
|
|
36
|
+
from gns3server.compute.virtualbox.virtualbox_error import VirtualBoxError
|
|
37
|
+
from gns3server.compute.nios.nio_udp import NIOUDP
|
|
38
|
+
from gns3server.compute.adapters.ethernet_adapter import EthernetAdapter
|
|
39
|
+
from gns3server.compute.base_node import BaseNode
|
|
40
|
+
|
|
41
|
+
import logging
|
|
42
|
+
|
|
43
|
+
log = logging.getLogger(__name__)
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class VirtualBoxVM(BaseNode):
|
|
47
|
+
|
|
48
|
+
"""
|
|
49
|
+
VirtualBox VM implementation.
|
|
50
|
+
"""
|
|
51
|
+
|
|
52
|
+
def __init__(
|
|
53
|
+
self,
|
|
54
|
+
name,
|
|
55
|
+
node_id,
|
|
56
|
+
project,
|
|
57
|
+
manager,
|
|
58
|
+
vmname,
|
|
59
|
+
linked_clone=False,
|
|
60
|
+
console=None,
|
|
61
|
+
console_type="telnet",
|
|
62
|
+
adapters=0,
|
|
63
|
+
):
|
|
64
|
+
|
|
65
|
+
super().__init__(
|
|
66
|
+
name, node_id, project, manager, console=console, linked_clone=linked_clone, console_type=console_type
|
|
67
|
+
)
|
|
68
|
+
|
|
69
|
+
self._uuid = None # UUID in VirtualBox
|
|
70
|
+
self._maximum_adapters = 8
|
|
71
|
+
self._system_properties = {}
|
|
72
|
+
self._telnet_server = None
|
|
73
|
+
self._local_udp_tunnels = {}
|
|
74
|
+
|
|
75
|
+
# VirtualBox settings
|
|
76
|
+
self._adapters = adapters
|
|
77
|
+
self._ethernet_adapters = {}
|
|
78
|
+
self._headless = False
|
|
79
|
+
self._on_close = "power_off"
|
|
80
|
+
self._vmname = vmname
|
|
81
|
+
self._use_any_adapter = False
|
|
82
|
+
self._ram = 0
|
|
83
|
+
self._adapter_type = "Intel PRO/1000 MT Desktop (82540EM)"
|
|
84
|
+
|
|
85
|
+
def asdict(self):
|
|
86
|
+
|
|
87
|
+
json = {
|
|
88
|
+
"name": self.name,
|
|
89
|
+
"usage": self.usage,
|
|
90
|
+
"node_id": self.id,
|
|
91
|
+
"console": self.console,
|
|
92
|
+
"console_type": self.console_type,
|
|
93
|
+
"project_id": self.project.id,
|
|
94
|
+
"vmname": self.vmname,
|
|
95
|
+
"headless": self.headless,
|
|
96
|
+
"on_close": self.on_close,
|
|
97
|
+
"adapters": self._adapters,
|
|
98
|
+
"adapter_type": self.adapter_type,
|
|
99
|
+
"ram": self.ram,
|
|
100
|
+
"status": self.status,
|
|
101
|
+
"use_any_adapter": self.use_any_adapter,
|
|
102
|
+
"linked_clone": self.linked_clone,
|
|
103
|
+
}
|
|
104
|
+
if self.linked_clone:
|
|
105
|
+
json["node_directory"] = self.working_path
|
|
106
|
+
else:
|
|
107
|
+
json["node_directory"] = None
|
|
108
|
+
return json
|
|
109
|
+
|
|
110
|
+
@property
|
|
111
|
+
def ethernet_adapters(self):
|
|
112
|
+
return self._ethernet_adapters
|
|
113
|
+
|
|
114
|
+
async def _get_system_properties(self):
|
|
115
|
+
|
|
116
|
+
properties = await self.manager.execute("list", ["systemproperties"])
|
|
117
|
+
for prop in properties:
|
|
118
|
+
try:
|
|
119
|
+
name, value = prop.split(":", 1)
|
|
120
|
+
except ValueError:
|
|
121
|
+
continue
|
|
122
|
+
self._system_properties[name.strip()] = value.strip()
|
|
123
|
+
|
|
124
|
+
async def _get_vm_state(self):
|
|
125
|
+
"""
|
|
126
|
+
Returns the VM state (e.g. running, paused etc.)
|
|
127
|
+
|
|
128
|
+
:returns: state (string)
|
|
129
|
+
"""
|
|
130
|
+
|
|
131
|
+
results = await self.manager.execute("showvminfo", [self._uuid, "--machinereadable"])
|
|
132
|
+
for info in results:
|
|
133
|
+
if "=" in info:
|
|
134
|
+
name, value = info.split("=", 1)
|
|
135
|
+
if name == "VMState":
|
|
136
|
+
return value.strip('"')
|
|
137
|
+
raise VirtualBoxError(f"Could not get VM state for {self._vmname}")
|
|
138
|
+
|
|
139
|
+
async def _control_vm(self, params):
|
|
140
|
+
"""
|
|
141
|
+
Change setting in this VM when running.
|
|
142
|
+
|
|
143
|
+
:param params: params to use with sub-command controlvm
|
|
144
|
+
|
|
145
|
+
:returns: result of the command.
|
|
146
|
+
"""
|
|
147
|
+
|
|
148
|
+
args = shlex.split(params)
|
|
149
|
+
result = await self.manager.execute("controlvm", [self._uuid] + args)
|
|
150
|
+
return result
|
|
151
|
+
|
|
152
|
+
async def _modify_vm(self, params):
|
|
153
|
+
"""
|
|
154
|
+
Change setting in this VM when not running.
|
|
155
|
+
|
|
156
|
+
:param params: params to use with sub-command modifyvm
|
|
157
|
+
"""
|
|
158
|
+
|
|
159
|
+
args = shlex.split(params)
|
|
160
|
+
await self.manager.execute("modifyvm", [self._uuid] + args)
|
|
161
|
+
|
|
162
|
+
async def _check_duplicate_linked_clone(self):
|
|
163
|
+
"""
|
|
164
|
+
Without linked clone two VM using the same image can't run
|
|
165
|
+
at the same time.
|
|
166
|
+
|
|
167
|
+
To avoid issue like false detection when a project close
|
|
168
|
+
and another open we try multiple times.
|
|
169
|
+
"""
|
|
170
|
+
trial = 0
|
|
171
|
+
|
|
172
|
+
while True:
|
|
173
|
+
found = False
|
|
174
|
+
for node in self.manager.nodes:
|
|
175
|
+
if node != self and node.vmname == self.vmname:
|
|
176
|
+
found = True
|
|
177
|
+
if node.project != self.project:
|
|
178
|
+
if trial >= 30:
|
|
179
|
+
raise VirtualBoxError(
|
|
180
|
+
f"Sorry a node without the linked clone setting enabled can only be used once on your server.\n{self.vmname} is already used by {node.name} in project {self.project.name}"
|
|
181
|
+
)
|
|
182
|
+
else:
|
|
183
|
+
if trial >= 5:
|
|
184
|
+
raise VirtualBoxError(
|
|
185
|
+
f"Sorry a node without the linked clone setting enabled can only be used once on your server.\n{self.vmname} is already used by {node.name} in this project"
|
|
186
|
+
)
|
|
187
|
+
if not found:
|
|
188
|
+
return
|
|
189
|
+
trial += 1
|
|
190
|
+
await asyncio.sleep(1)
|
|
191
|
+
|
|
192
|
+
async def _refresh_vm_uuid(self):
|
|
193
|
+
|
|
194
|
+
vm_info = await self._get_vm_info()
|
|
195
|
+
self._uuid = vm_info.get("UUID", self._uuid)
|
|
196
|
+
if not self._uuid:
|
|
197
|
+
raise VirtualBoxError(f"Could not find any UUID for VM '{self._vmname}'")
|
|
198
|
+
if "memory" in vm_info:
|
|
199
|
+
self._ram = int(vm_info["memory"])
|
|
200
|
+
|
|
201
|
+
async def create(self):
|
|
202
|
+
|
|
203
|
+
if not self.linked_clone:
|
|
204
|
+
await self._check_duplicate_linked_clone()
|
|
205
|
+
|
|
206
|
+
await self._get_system_properties()
|
|
207
|
+
if "API version" not in self._system_properties:
|
|
208
|
+
raise VirtualBoxError(f"Can't access to VirtualBox API version:\n{self._system_properties}")
|
|
209
|
+
if parse_version(self._system_properties["API version"]) < parse_version("4_3"):
|
|
210
|
+
raise VirtualBoxError("The VirtualBox API version is lower than 4.3")
|
|
211
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] created")
|
|
212
|
+
|
|
213
|
+
if self.linked_clone:
|
|
214
|
+
if self.id and os.path.isdir(os.path.join(self.working_dir, self._vmname)):
|
|
215
|
+
self._patch_vm_uuid()
|
|
216
|
+
await self.manager.execute("registervm", [self._linked_vbox_file()])
|
|
217
|
+
await self._refresh_vm_uuid()
|
|
218
|
+
await self._reattach_linked_hdds()
|
|
219
|
+
|
|
220
|
+
else:
|
|
221
|
+
await self._refresh_vm_uuid()
|
|
222
|
+
await self._create_linked_clone()
|
|
223
|
+
else:
|
|
224
|
+
await self._refresh_vm_uuid()
|
|
225
|
+
|
|
226
|
+
if self._adapters:
|
|
227
|
+
await self.set_adapters(self._adapters)
|
|
228
|
+
|
|
229
|
+
def _linked_vbox_file(self):
|
|
230
|
+
return os.path.join(self.working_dir, self._vmname, self._vmname + ".vbox")
|
|
231
|
+
|
|
232
|
+
def _patch_vm_uuid(self):
|
|
233
|
+
"""
|
|
234
|
+
Fix the VM uuid in the case of linked clone
|
|
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())
|
|
243
|
+
)
|
|
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)
|
|
259
|
+
|
|
260
|
+
machine.set("uuid", "{" + self.id + "}")
|
|
261
|
+
tree.write(self._linked_vbox_file())
|
|
262
|
+
|
|
263
|
+
async def check_hw_virtualization(self):
|
|
264
|
+
"""
|
|
265
|
+
Returns either hardware virtualization is activated or not.
|
|
266
|
+
|
|
267
|
+
:returns: boolean
|
|
268
|
+
"""
|
|
269
|
+
|
|
270
|
+
vm_info = await self._get_vm_info()
|
|
271
|
+
if "hwvirtex" in vm_info and vm_info["hwvirtex"] == "on":
|
|
272
|
+
return True
|
|
273
|
+
return False
|
|
274
|
+
|
|
275
|
+
@locking
|
|
276
|
+
async def start(self):
|
|
277
|
+
"""
|
|
278
|
+
Starts this VirtualBox VM.
|
|
279
|
+
"""
|
|
280
|
+
|
|
281
|
+
if self.status == "started":
|
|
282
|
+
return
|
|
283
|
+
|
|
284
|
+
# resume the VM if it is paused
|
|
285
|
+
vm_state = await self._get_vm_state()
|
|
286
|
+
if vm_state == "paused":
|
|
287
|
+
await self.resume()
|
|
288
|
+
return
|
|
289
|
+
|
|
290
|
+
# VM must be powered off to start it
|
|
291
|
+
if vm_state == "saved":
|
|
292
|
+
result = await self.manager.execute("guestproperty", ["get", self._uuid, "SavedByGNS3"])
|
|
293
|
+
if result == ["No value set!"]:
|
|
294
|
+
raise VirtualBoxError("VirtualBox VM was not saved from GNS3")
|
|
295
|
+
else:
|
|
296
|
+
await self.manager.execute("guestproperty", ["delete", self._uuid, "SavedByGNS3"])
|
|
297
|
+
elif vm_state == "poweroff":
|
|
298
|
+
await self._set_network_options()
|
|
299
|
+
await self._set_serial_console()
|
|
300
|
+
else:
|
|
301
|
+
raise VirtualBoxError(f"VirtualBox VM '{self.name}' is not powered off (current state is '{vm_state}')")
|
|
302
|
+
|
|
303
|
+
# check if there is enough RAM to run
|
|
304
|
+
self.check_available_ram(self.ram)
|
|
305
|
+
|
|
306
|
+
args = [self._uuid]
|
|
307
|
+
if self._headless:
|
|
308
|
+
args.extend(["--type", "headless"])
|
|
309
|
+
result = await self.manager.execute("startvm", args)
|
|
310
|
+
self.status = "started"
|
|
311
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] started")
|
|
312
|
+
log.debug(f"Start result: {result}")
|
|
313
|
+
|
|
314
|
+
# add a guest property to let the VM know about the GNS3 name
|
|
315
|
+
await self.manager.execute("guestproperty", ["set", self._uuid, "NameInGNS3", self.name])
|
|
316
|
+
# add a guest property to let the VM know about the GNS3 project directory
|
|
317
|
+
await self.manager.execute("guestproperty", ["set", self._uuid, "ProjectDirInGNS3", self.working_dir])
|
|
318
|
+
|
|
319
|
+
await self._start_ubridge()
|
|
320
|
+
for adapter_number in range(0, self._adapters):
|
|
321
|
+
nio = self._ethernet_adapters[adapter_number].get_nio(0)
|
|
322
|
+
if nio:
|
|
323
|
+
await self.add_ubridge_udp_connection(
|
|
324
|
+
f"VBOX-{self._id}-{adapter_number}", self._local_udp_tunnels[adapter_number][1], nio
|
|
325
|
+
)
|
|
326
|
+
|
|
327
|
+
await self._start_console()
|
|
328
|
+
|
|
329
|
+
if await self.check_hw_virtualization():
|
|
330
|
+
self._hw_virtualization = True
|
|
331
|
+
|
|
332
|
+
@locking
|
|
333
|
+
async def stop(self):
|
|
334
|
+
"""
|
|
335
|
+
Stops this VirtualBox VM.
|
|
336
|
+
"""
|
|
337
|
+
|
|
338
|
+
self._hw_virtualization = False
|
|
339
|
+
await self._stop_ubridge()
|
|
340
|
+
await self._stop_remote_console()
|
|
341
|
+
vm_state = await self._get_vm_state()
|
|
342
|
+
log.info(f"Stopping VirtualBox VM '{self.name}' [{self.id}] (current state is {vm_state})")
|
|
343
|
+
if vm_state in ("running", "paused"):
|
|
344
|
+
|
|
345
|
+
if self.on_close == "save_vm_state":
|
|
346
|
+
# add a guest property to know the VM has been saved
|
|
347
|
+
await self.manager.execute("guestproperty", ["set", self._uuid, "SavedByGNS3", "yes"])
|
|
348
|
+
result = await self._control_vm("savestate")
|
|
349
|
+
self.status = "stopped"
|
|
350
|
+
log.debug(f"Stop result: {result}")
|
|
351
|
+
elif self.on_close == "shutdown_signal":
|
|
352
|
+
# use ACPI to shutdown the VM
|
|
353
|
+
result = await self._control_vm("acpipowerbutton")
|
|
354
|
+
trial = 0
|
|
355
|
+
while True:
|
|
356
|
+
vm_state = await self._get_vm_state()
|
|
357
|
+
if vm_state == "poweroff":
|
|
358
|
+
break
|
|
359
|
+
await asyncio.sleep(1)
|
|
360
|
+
trial += 1
|
|
361
|
+
if trial >= 120:
|
|
362
|
+
await self._control_vm("poweroff")
|
|
363
|
+
break
|
|
364
|
+
self.status = "stopped"
|
|
365
|
+
log.debug(f"ACPI shutdown result: {result}")
|
|
366
|
+
else:
|
|
367
|
+
# power off the VM
|
|
368
|
+
result = await self._control_vm("poweroff")
|
|
369
|
+
self.status = "stopped"
|
|
370
|
+
log.debug(f"Stop result: {result}")
|
|
371
|
+
elif vm_state == "aborted":
|
|
372
|
+
self.status = "stopped"
|
|
373
|
+
|
|
374
|
+
if self.status == "stopped":
|
|
375
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] stopped")
|
|
376
|
+
await asyncio.sleep(0.5) # give some time for VirtualBox to unlock the VM
|
|
377
|
+
if self.on_close != "save_vm_state":
|
|
378
|
+
# do some cleaning when the VM is powered off
|
|
379
|
+
try:
|
|
380
|
+
# deactivate the first serial port
|
|
381
|
+
await self._modify_vm("--uart1 off")
|
|
382
|
+
except VirtualBoxError as e:
|
|
383
|
+
log.warning(f"Could not deactivate the first serial port: {e}")
|
|
384
|
+
|
|
385
|
+
for adapter_number in range(0, self._adapters):
|
|
386
|
+
nio = self._ethernet_adapters[adapter_number].get_nio(0)
|
|
387
|
+
if nio:
|
|
388
|
+
await self._modify_vm(f"--nictrace{adapter_number + 1} off")
|
|
389
|
+
await self._modify_vm(f"--cableconnected{adapter_number + 1} off")
|
|
390
|
+
await self._modify_vm(f"--nic{adapter_number + 1} null")
|
|
391
|
+
await super().stop()
|
|
392
|
+
|
|
393
|
+
async def suspend(self):
|
|
394
|
+
"""
|
|
395
|
+
Suspends this VirtualBox VM.
|
|
396
|
+
"""
|
|
397
|
+
|
|
398
|
+
vm_state = await self._get_vm_state()
|
|
399
|
+
if vm_state == "running":
|
|
400
|
+
await self._control_vm("pause")
|
|
401
|
+
self.status = "suspended"
|
|
402
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] suspended")
|
|
403
|
+
else:
|
|
404
|
+
log.warning(
|
|
405
|
+
"VirtualBox VM '{name}' [{id}] cannot be suspended, current state: {state}".format(
|
|
406
|
+
name=self.name, id=self.id, state=vm_state
|
|
407
|
+
)
|
|
408
|
+
)
|
|
409
|
+
|
|
410
|
+
async def resume(self):
|
|
411
|
+
"""
|
|
412
|
+
Resumes this VirtualBox VM.
|
|
413
|
+
"""
|
|
414
|
+
|
|
415
|
+
await self._control_vm("resume")
|
|
416
|
+
self.status = "started"
|
|
417
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] resumed")
|
|
418
|
+
|
|
419
|
+
async def reload(self):
|
|
420
|
+
"""
|
|
421
|
+
Reloads this VirtualBox VM.
|
|
422
|
+
"""
|
|
423
|
+
|
|
424
|
+
result = await self._control_vm("reset")
|
|
425
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] reloaded")
|
|
426
|
+
log.debug(f"Reload result: {result}")
|
|
427
|
+
|
|
428
|
+
async def _get_all_hdd_files(self):
|
|
429
|
+
|
|
430
|
+
hdds = []
|
|
431
|
+
properties = await self.manager.execute("list", ["hdds"])
|
|
432
|
+
for prop in properties:
|
|
433
|
+
try:
|
|
434
|
+
name, value = prop.split(":", 1)
|
|
435
|
+
except ValueError:
|
|
436
|
+
continue
|
|
437
|
+
if name.strip() == "Location":
|
|
438
|
+
hdds.append(value.strip())
|
|
439
|
+
return hdds
|
|
440
|
+
|
|
441
|
+
async def _reattach_linked_hdds(self):
|
|
442
|
+
"""
|
|
443
|
+
Reattach linked cloned hard disks.
|
|
444
|
+
"""
|
|
445
|
+
|
|
446
|
+
hdd_info_file = os.path.join(self.working_dir, self._vmname, "hdd_info.json")
|
|
447
|
+
try:
|
|
448
|
+
with open(hdd_info_file, encoding="utf-8") as f:
|
|
449
|
+
hdd_table = json.load(f)
|
|
450
|
+
except (ValueError, OSError) as e:
|
|
451
|
+
# The VM has never be started
|
|
452
|
+
return
|
|
453
|
+
|
|
454
|
+
for hdd_info in hdd_table:
|
|
455
|
+
hdd_file = os.path.join(self.working_dir, self._vmname, "Snapshots", hdd_info["hdd"])
|
|
456
|
+
if os.path.exists(hdd_file):
|
|
457
|
+
log.info(
|
|
458
|
+
"VirtualBox VM '{name}' [{id}] attaching HDD {controller} {port} {device} {medium}".format(
|
|
459
|
+
name=self.name,
|
|
460
|
+
id=self.id,
|
|
461
|
+
controller=hdd_info["controller"],
|
|
462
|
+
port=hdd_info["port"],
|
|
463
|
+
device=hdd_info["device"],
|
|
464
|
+
medium=hdd_file,
|
|
465
|
+
)
|
|
466
|
+
)
|
|
467
|
+
|
|
468
|
+
try:
|
|
469
|
+
await self._storage_attach(
|
|
470
|
+
'--storagectl "{}" --port {} --device {} --type hdd --medium "{}"'.format(
|
|
471
|
+
hdd_info["controller"], hdd_info["port"], hdd_info["device"], hdd_file
|
|
472
|
+
)
|
|
473
|
+
)
|
|
474
|
+
|
|
475
|
+
except VirtualBoxError as e:
|
|
476
|
+
log.warning(
|
|
477
|
+
"VirtualBox VM '{name}' [{id}] error reattaching HDD {controller} {port} {device} {medium}: {error}".format(
|
|
478
|
+
name=self.name,
|
|
479
|
+
id=self.id,
|
|
480
|
+
controller=hdd_info["controller"],
|
|
481
|
+
port=hdd_info["port"],
|
|
482
|
+
device=hdd_info["device"],
|
|
483
|
+
medium=hdd_file,
|
|
484
|
+
error=e,
|
|
485
|
+
)
|
|
486
|
+
)
|
|
487
|
+
continue
|
|
488
|
+
|
|
489
|
+
async def save_linked_hdds_info(self):
|
|
490
|
+
"""
|
|
491
|
+
Save linked cloned hard disks information.
|
|
492
|
+
|
|
493
|
+
:returns: disk table information
|
|
494
|
+
"""
|
|
495
|
+
|
|
496
|
+
hdd_table = []
|
|
497
|
+
if self.linked_clone:
|
|
498
|
+
if os.path.exists(self.working_dir):
|
|
499
|
+
hdd_files = await self._get_all_hdd_files()
|
|
500
|
+
vm_info = await self._get_vm_info()
|
|
501
|
+
for entry, value in vm_info.items():
|
|
502
|
+
match = re.search(
|
|
503
|
+
r"^([\s\w]+)\-(\d)\-(\d)$", entry
|
|
504
|
+
) # match Controller-PortNumber-DeviceNumber entry
|
|
505
|
+
if match:
|
|
506
|
+
controller = match.group(1)
|
|
507
|
+
port = match.group(2)
|
|
508
|
+
device = match.group(3)
|
|
509
|
+
if value in hdd_files and os.path.exists(
|
|
510
|
+
os.path.join(self.working_dir, self._vmname, "Snapshots", os.path.basename(value))
|
|
511
|
+
):
|
|
512
|
+
log.info(
|
|
513
|
+
"VirtualBox VM '{name}' [{id}] detaching HDD {controller} {port} {device}".format(
|
|
514
|
+
name=self.name, id=self.id, controller=controller, port=port, device=device
|
|
515
|
+
)
|
|
516
|
+
)
|
|
517
|
+
hdd_table.append(
|
|
518
|
+
{
|
|
519
|
+
"hdd": os.path.basename(value),
|
|
520
|
+
"controller": controller,
|
|
521
|
+
"port": port,
|
|
522
|
+
"device": device,
|
|
523
|
+
}
|
|
524
|
+
)
|
|
525
|
+
|
|
526
|
+
if hdd_table:
|
|
527
|
+
try:
|
|
528
|
+
hdd_info_file = os.path.join(self.working_dir, self._vmname, "hdd_info.json")
|
|
529
|
+
with open(hdd_info_file, "w", encoding="utf-8") as f:
|
|
530
|
+
json.dump(hdd_table, f, indent=4)
|
|
531
|
+
except OSError as e:
|
|
532
|
+
log.warning(
|
|
533
|
+
"VirtualBox VM '{name}' [{id}] could not write HHD info file: {error}".format(
|
|
534
|
+
name=self.name, id=self.id, error=e.strerror
|
|
535
|
+
)
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
return hdd_table
|
|
539
|
+
|
|
540
|
+
async def close(self):
|
|
541
|
+
"""
|
|
542
|
+
Closes this VirtualBox VM.
|
|
543
|
+
"""
|
|
544
|
+
|
|
545
|
+
if self._closed:
|
|
546
|
+
# VM is already closed
|
|
547
|
+
return
|
|
548
|
+
|
|
549
|
+
if not (await super().close()):
|
|
550
|
+
return False
|
|
551
|
+
|
|
552
|
+
log.debug(f"VirtualBox VM '{self.name}' [{self.id}] is closing")
|
|
553
|
+
if self._console:
|
|
554
|
+
self._manager.port_manager.release_tcp_port(self._console, self._project)
|
|
555
|
+
self._console = None
|
|
556
|
+
|
|
557
|
+
for adapter in self._ethernet_adapters.values():
|
|
558
|
+
if adapter is not None:
|
|
559
|
+
for nio in adapter.ports.values():
|
|
560
|
+
if nio and isinstance(nio, NIOUDP):
|
|
561
|
+
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
|
562
|
+
|
|
563
|
+
for udp_tunnel in self._local_udp_tunnels.values():
|
|
564
|
+
self.manager.port_manager.release_udp_port(udp_tunnel[0].lport, self._project)
|
|
565
|
+
self.manager.port_manager.release_udp_port(udp_tunnel[1].lport, self._project)
|
|
566
|
+
self._local_udp_tunnels = {}
|
|
567
|
+
|
|
568
|
+
self.on_close = "power_off"
|
|
569
|
+
await self.stop()
|
|
570
|
+
|
|
571
|
+
if self.linked_clone:
|
|
572
|
+
hdd_table = await self.save_linked_hdds_info()
|
|
573
|
+
for hdd in hdd_table.copy():
|
|
574
|
+
log.info(
|
|
575
|
+
"VirtualBox VM '{name}' [{id}] detaching HDD {controller} {port} {device}".format(
|
|
576
|
+
name=self.name, id=self.id, controller=hdd["controller"], port=hdd["port"], device=hdd["device"]
|
|
577
|
+
)
|
|
578
|
+
)
|
|
579
|
+
try:
|
|
580
|
+
await self._storage_attach(
|
|
581
|
+
'--storagectl "{}" --port {} --device {} --type hdd --medium none'.format(
|
|
582
|
+
hdd["controller"], hdd["port"], hdd["device"]
|
|
583
|
+
)
|
|
584
|
+
)
|
|
585
|
+
except VirtualBoxError as e:
|
|
586
|
+
log.warning(
|
|
587
|
+
"VirtualBox VM '{name}' [{id}] error detaching HDD {controller} {port} {device}: {error}".format(
|
|
588
|
+
name=self.name,
|
|
589
|
+
id=self.id,
|
|
590
|
+
controller=hdd["controller"],
|
|
591
|
+
port=hdd["port"],
|
|
592
|
+
device=hdd["device"],
|
|
593
|
+
error=e,
|
|
594
|
+
)
|
|
595
|
+
)
|
|
596
|
+
continue
|
|
597
|
+
|
|
598
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] unregistering")
|
|
599
|
+
await self.manager.execute("unregistervm", [self._name])
|
|
600
|
+
|
|
601
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] closed")
|
|
602
|
+
self._closed = True
|
|
603
|
+
|
|
604
|
+
@property
|
|
605
|
+
def headless(self):
|
|
606
|
+
"""
|
|
607
|
+
Returns either the VM will start in headless mode
|
|
608
|
+
|
|
609
|
+
:returns: boolean
|
|
610
|
+
"""
|
|
611
|
+
|
|
612
|
+
return self._headless
|
|
613
|
+
|
|
614
|
+
@headless.setter
|
|
615
|
+
def headless(self, headless):
|
|
616
|
+
"""
|
|
617
|
+
Sets either the VM will start in headless mode
|
|
618
|
+
|
|
619
|
+
:param headless: boolean
|
|
620
|
+
"""
|
|
621
|
+
|
|
622
|
+
if headless:
|
|
623
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] has enabled the headless mode")
|
|
624
|
+
else:
|
|
625
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] has disabled the headless mode")
|
|
626
|
+
self._headless = headless
|
|
627
|
+
|
|
628
|
+
@property
|
|
629
|
+
def on_close(self):
|
|
630
|
+
"""
|
|
631
|
+
Returns the action to execute when the VM is stopped/closed
|
|
632
|
+
|
|
633
|
+
:returns: string
|
|
634
|
+
"""
|
|
635
|
+
|
|
636
|
+
return self._on_close
|
|
637
|
+
|
|
638
|
+
@on_close.setter
|
|
639
|
+
def on_close(self, on_close):
|
|
640
|
+
"""
|
|
641
|
+
Sets the action to execute when the VM is stopped/closed
|
|
642
|
+
|
|
643
|
+
:param on_close: string
|
|
644
|
+
"""
|
|
645
|
+
|
|
646
|
+
log.info(f'VirtualBox VM "{self._name}" [{self._id}] set the close action to "{on_close}"')
|
|
647
|
+
self._on_close = on_close
|
|
648
|
+
|
|
649
|
+
@property
|
|
650
|
+
def ram(self):
|
|
651
|
+
"""
|
|
652
|
+
Returns the amount of RAM allocated to this VirtualBox VM.
|
|
653
|
+
|
|
654
|
+
:returns: amount RAM in MB (integer)
|
|
655
|
+
"""
|
|
656
|
+
|
|
657
|
+
return self._ram
|
|
658
|
+
|
|
659
|
+
async def set_ram(self, ram):
|
|
660
|
+
"""
|
|
661
|
+
Set the amount of RAM allocated to this VirtualBox VM.
|
|
662
|
+
|
|
663
|
+
:param ram: amount RAM in MB (integer)
|
|
664
|
+
"""
|
|
665
|
+
|
|
666
|
+
if ram == 0:
|
|
667
|
+
return
|
|
668
|
+
|
|
669
|
+
await self._modify_vm(f"--memory {ram}")
|
|
670
|
+
|
|
671
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] has set amount of RAM to {ram}")
|
|
672
|
+
self._ram = ram
|
|
673
|
+
|
|
674
|
+
@property
|
|
675
|
+
def vmname(self):
|
|
676
|
+
"""
|
|
677
|
+
Returns the VirtualBox VM name.
|
|
678
|
+
|
|
679
|
+
:returns: VirtualBox VM name
|
|
680
|
+
"""
|
|
681
|
+
|
|
682
|
+
return self._vmname
|
|
683
|
+
|
|
684
|
+
async def set_vmname(self, vmname):
|
|
685
|
+
"""
|
|
686
|
+
Renames the VirtualBox VM.
|
|
687
|
+
|
|
688
|
+
:param vmname: VirtualBox VM name
|
|
689
|
+
"""
|
|
690
|
+
|
|
691
|
+
if vmname == self._vmname:
|
|
692
|
+
return
|
|
693
|
+
|
|
694
|
+
if self.linked_clone:
|
|
695
|
+
if self.status == "started":
|
|
696
|
+
raise VirtualBoxError(f"Cannot change the name of running VM {self._name}")
|
|
697
|
+
# We can't rename a VM to name that already exists
|
|
698
|
+
vms = await self.manager.list_vms(allow_clone=True)
|
|
699
|
+
if vmname in [vm["vmname"] for vm in vms]:
|
|
700
|
+
raise VirtualBoxError(f"Cannot change the name to {vmname}, it is already used in VirtualBox")
|
|
701
|
+
await self._modify_vm(f'--name "{vmname}"')
|
|
702
|
+
|
|
703
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] has set the VM name to '{vmname}'")
|
|
704
|
+
self._vmname = vmname
|
|
705
|
+
|
|
706
|
+
@property
|
|
707
|
+
def adapters(self):
|
|
708
|
+
"""
|
|
709
|
+
Returns the number of adapters configured for this VirtualBox VM.
|
|
710
|
+
|
|
711
|
+
:returns: number of adapters
|
|
712
|
+
"""
|
|
713
|
+
|
|
714
|
+
return self._adapters
|
|
715
|
+
|
|
716
|
+
async def set_adapters(self, adapters):
|
|
717
|
+
"""
|
|
718
|
+
Sets the number of Ethernet adapters for this VirtualBox VM instance.
|
|
719
|
+
|
|
720
|
+
:param adapters: number of adapters
|
|
721
|
+
"""
|
|
722
|
+
|
|
723
|
+
# check for the maximum adapters supported by the VM
|
|
724
|
+
vm_info = await self._get_vm_info()
|
|
725
|
+
chipset = "piix3" # default chipset for VirtualBox VMs
|
|
726
|
+
self._maximum_adapters = 8 # default maximum network adapter count for PIIX3 chipset
|
|
727
|
+
if "chipset" in vm_info:
|
|
728
|
+
chipset = vm_info["chipset"]
|
|
729
|
+
max_adapter_string = f"Maximum {chipset.upper()} Network Adapter count"
|
|
730
|
+
if max_adapter_string in self._system_properties:
|
|
731
|
+
try:
|
|
732
|
+
self._maximum_adapters = int(self._system_properties[max_adapter_string])
|
|
733
|
+
except ValueError:
|
|
734
|
+
log.error(
|
|
735
|
+
f"Could not convert system property to integer: {max_adapter_string} = {self._system_properties[max_adapter_string]}"
|
|
736
|
+
)
|
|
737
|
+
else:
|
|
738
|
+
log.warning(f"Could not find system property '{max_adapter_string}' for chipset {chipset}")
|
|
739
|
+
|
|
740
|
+
log.info(
|
|
741
|
+
"VirtualBox VM '{name}' [{id}] can have a maximum of {max} network adapters for chipset {chipset}".format(
|
|
742
|
+
name=self.name, id=self.id, max=self._maximum_adapters, chipset=chipset.upper()
|
|
743
|
+
)
|
|
744
|
+
)
|
|
745
|
+
if adapters > self._maximum_adapters:
|
|
746
|
+
raise VirtualBoxError(
|
|
747
|
+
"The configured {} chipset limits the VM to {} network adapters. The chipset can be changed outside GNS3 in the VirtualBox VM settings.".format(
|
|
748
|
+
chipset.upper(), self._maximum_adapters
|
|
749
|
+
)
|
|
750
|
+
)
|
|
751
|
+
|
|
752
|
+
self._ethernet_adapters.clear()
|
|
753
|
+
for adapter_number in range(0, adapters):
|
|
754
|
+
self._ethernet_adapters[adapter_number] = EthernetAdapter()
|
|
755
|
+
|
|
756
|
+
self._adapters = len(self._ethernet_adapters)
|
|
757
|
+
log.info(
|
|
758
|
+
"VirtualBox VM '{name}' [{id}] has changed the number of Ethernet adapters to {adapters}".format(
|
|
759
|
+
name=self.name, id=self.id, adapters=adapters
|
|
760
|
+
)
|
|
761
|
+
)
|
|
762
|
+
|
|
763
|
+
@property
|
|
764
|
+
def use_any_adapter(self):
|
|
765
|
+
"""
|
|
766
|
+
Returns either GNS3 can use any VirtualBox adapter on this instance.
|
|
767
|
+
|
|
768
|
+
:returns: boolean
|
|
769
|
+
"""
|
|
770
|
+
|
|
771
|
+
return self._use_any_adapter
|
|
772
|
+
|
|
773
|
+
@use_any_adapter.setter
|
|
774
|
+
def use_any_adapter(self, use_any_adapter):
|
|
775
|
+
"""
|
|
776
|
+
Allows GNS3 to use any VirtualBox adapter on this instance.
|
|
777
|
+
|
|
778
|
+
:param use_any_adapter: boolean
|
|
779
|
+
"""
|
|
780
|
+
|
|
781
|
+
if use_any_adapter:
|
|
782
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] is allowed to use any adapter")
|
|
783
|
+
else:
|
|
784
|
+
log.info(f"VirtualBox VM '{self.name}' [{self.id}] is not allowed to use any adapter")
|
|
785
|
+
self._use_any_adapter = use_any_adapter
|
|
786
|
+
|
|
787
|
+
@property
|
|
788
|
+
def adapter_type(self):
|
|
789
|
+
"""
|
|
790
|
+
Returns the adapter type for this VirtualBox VM instance.
|
|
791
|
+
|
|
792
|
+
:returns: adapter type (string)
|
|
793
|
+
"""
|
|
794
|
+
|
|
795
|
+
return self._adapter_type
|
|
796
|
+
|
|
797
|
+
@adapter_type.setter
|
|
798
|
+
def adapter_type(self, adapter_type):
|
|
799
|
+
"""
|
|
800
|
+
Sets the adapter type for this VirtualBox VM instance.
|
|
801
|
+
|
|
802
|
+
:param adapter_type: adapter type (string)
|
|
803
|
+
"""
|
|
804
|
+
|
|
805
|
+
self._adapter_type = adapter_type
|
|
806
|
+
log.info(
|
|
807
|
+
"VirtualBox VM '{name}' [{id}]: adapter type changed to {adapter_type}".format(
|
|
808
|
+
name=self.name, id=self.id, adapter_type=adapter_type
|
|
809
|
+
)
|
|
810
|
+
)
|
|
811
|
+
|
|
812
|
+
async def _get_vm_info(self):
|
|
813
|
+
"""
|
|
814
|
+
Returns this VM info.
|
|
815
|
+
|
|
816
|
+
:returns: dict of info
|
|
817
|
+
"""
|
|
818
|
+
|
|
819
|
+
vm_info = {}
|
|
820
|
+
results = await self.manager.execute(
|
|
821
|
+
"showvminfo", ["--machinereadable", "--", self._vmname]
|
|
822
|
+
) # "--" is to protect against vm names containing the "-" character
|
|
823
|
+
for info in results:
|
|
824
|
+
try:
|
|
825
|
+
name, value = info.split("=", 1)
|
|
826
|
+
except ValueError:
|
|
827
|
+
continue
|
|
828
|
+
vm_info[name.strip('"')] = value.strip('"')
|
|
829
|
+
return vm_info
|
|
830
|
+
|
|
831
|
+
def _get_pipe_name(self):
|
|
832
|
+
"""
|
|
833
|
+
Returns the pipe name to create a serial connection.
|
|
834
|
+
|
|
835
|
+
:returns: pipe path (string)
|
|
836
|
+
"""
|
|
837
|
+
|
|
838
|
+
pipe_name = os.path.join(tempfile.gettempdir(), "gns3_vbox", f"{self.id}")
|
|
839
|
+
try:
|
|
840
|
+
os.makedirs(os.path.dirname(pipe_name), exist_ok=True)
|
|
841
|
+
except OSError as e:
|
|
842
|
+
raise VirtualBoxError(f"Could not create the VirtualBox pipe directory: {e}")
|
|
843
|
+
return pipe_name
|
|
844
|
+
|
|
845
|
+
async def _set_serial_console(self):
|
|
846
|
+
"""
|
|
847
|
+
Configures the first serial port to allow a serial console connection.
|
|
848
|
+
"""
|
|
849
|
+
|
|
850
|
+
# activate the first serial port
|
|
851
|
+
await self._modify_vm("--uart1 0x3F8 4")
|
|
852
|
+
|
|
853
|
+
# set server mode with a pipe on the first serial port
|
|
854
|
+
pipe_name = self._get_pipe_name()
|
|
855
|
+
args = [self._uuid, "--uartmode1", "server", pipe_name]
|
|
856
|
+
await self.manager.execute("modifyvm", args)
|
|
857
|
+
|
|
858
|
+
async def _storage_attach(self, params):
|
|
859
|
+
"""
|
|
860
|
+
Change storage medium in this VM.
|
|
861
|
+
|
|
862
|
+
:param params: params to use with sub-command storageattach
|
|
863
|
+
"""
|
|
864
|
+
|
|
865
|
+
args = shlex.split(params)
|
|
866
|
+
await self.manager.execute("storageattach", [self._uuid] + args)
|
|
867
|
+
|
|
868
|
+
async def _get_nic_attachements(self, maximum_adapters):
|
|
869
|
+
"""
|
|
870
|
+
Returns NIC attachements.
|
|
871
|
+
|
|
872
|
+
:param maximum_adapters: maximum number of supported adapters
|
|
873
|
+
:returns: list of adapters with their Attachment setting (NAT, bridged etc.)
|
|
874
|
+
"""
|
|
875
|
+
|
|
876
|
+
nics = []
|
|
877
|
+
vm_info = await self._get_vm_info()
|
|
878
|
+
for adapter_number in range(0, maximum_adapters):
|
|
879
|
+
entry = f"nic{adapter_number + 1}"
|
|
880
|
+
if entry in vm_info:
|
|
881
|
+
value = vm_info[entry]
|
|
882
|
+
nics.append(value.lower())
|
|
883
|
+
else:
|
|
884
|
+
nics.append(None)
|
|
885
|
+
return nics
|
|
886
|
+
|
|
887
|
+
async def _set_network_options(self):
|
|
888
|
+
"""
|
|
889
|
+
Configures network options.
|
|
890
|
+
"""
|
|
891
|
+
|
|
892
|
+
nic_attachments = await self._get_nic_attachements(self._maximum_adapters)
|
|
893
|
+
for adapter_number in range(0, self._adapters):
|
|
894
|
+
attachment = nic_attachments[adapter_number]
|
|
895
|
+
if attachment == "null":
|
|
896
|
+
# disconnect the cable if no backend is attached.
|
|
897
|
+
await self._modify_vm(f"--cableconnected{adapter_number + 1} off")
|
|
898
|
+
if attachment == "none":
|
|
899
|
+
# set the backend to null to avoid a difference in the number of interfaces in the Guest.
|
|
900
|
+
await self._modify_vm(f"--nic{adapter_number + 1} null")
|
|
901
|
+
await self._modify_vm(f"--cableconnected{adapter_number + 1} off")
|
|
902
|
+
|
|
903
|
+
# use a local UDP tunnel to connect to uBridge instead
|
|
904
|
+
if adapter_number not in self._local_udp_tunnels:
|
|
905
|
+
self._local_udp_tunnels[adapter_number] = self._create_local_udp_tunnel()
|
|
906
|
+
nio = self._local_udp_tunnels[adapter_number][0]
|
|
907
|
+
|
|
908
|
+
if nio:
|
|
909
|
+
if not self._use_any_adapter and attachment in ("nat", "bridged", "intnet", "hostonly", "natnetwork"):
|
|
910
|
+
continue
|
|
911
|
+
|
|
912
|
+
await self._modify_vm(f"--nictrace{adapter_number + 1} off")
|
|
913
|
+
|
|
914
|
+
custom_adapter = self._get_custom_adapter_settings(adapter_number)
|
|
915
|
+
adapter_type = custom_adapter.get("adapter_type", self._adapter_type)
|
|
916
|
+
|
|
917
|
+
vbox_adapter_type = "82540EM"
|
|
918
|
+
if adapter_type == "PCnet-PCI II (Am79C970A)":
|
|
919
|
+
vbox_adapter_type = "Am79C970A"
|
|
920
|
+
if adapter_type == "PCNet-FAST III (Am79C973)":
|
|
921
|
+
vbox_adapter_type = "Am79C973"
|
|
922
|
+
if adapter_type == "Intel PRO/1000 MT Desktop (82540EM)":
|
|
923
|
+
vbox_adapter_type = "82540EM"
|
|
924
|
+
if adapter_type == "Intel PRO/1000 T Server (82543GC)":
|
|
925
|
+
vbox_adapter_type = "82543GC"
|
|
926
|
+
if adapter_type == "Intel PRO/1000 MT Server (82545EM)":
|
|
927
|
+
vbox_adapter_type = "82545EM"
|
|
928
|
+
if adapter_type == "Paravirtualized Network (virtio-net)":
|
|
929
|
+
vbox_adapter_type = "virtio"
|
|
930
|
+
args = [self._uuid, f"--nictype{adapter_number + 1}", vbox_adapter_type]
|
|
931
|
+
await self.manager.execute("modifyvm", args)
|
|
932
|
+
|
|
933
|
+
if isinstance(nio, NIOUDP):
|
|
934
|
+
log.debug(f"setting UDP params on adapter {adapter_number}")
|
|
935
|
+
await self._modify_vm(f"--nic{adapter_number + 1} generic")
|
|
936
|
+
await self._modify_vm(f"--nicgenericdrv{adapter_number + 1} UDPTunnel")
|
|
937
|
+
await self._modify_vm(f"--nicproperty{adapter_number + 1} sport={nio.lport}")
|
|
938
|
+
await self._modify_vm(f"--nicproperty{adapter_number + 1} dest={nio.rhost}")
|
|
939
|
+
await self._modify_vm(f"--nicproperty{adapter_number + 1} dport={nio.rport}")
|
|
940
|
+
if nio.suspend:
|
|
941
|
+
await self._modify_vm(f"--cableconnected{adapter_number + 1} off")
|
|
942
|
+
else:
|
|
943
|
+
await self._modify_vm(f"--cableconnected{adapter_number + 1} on")
|
|
944
|
+
|
|
945
|
+
if nio.capturing:
|
|
946
|
+
await self._modify_vm(f"--nictrace{adapter_number + 1} on")
|
|
947
|
+
await self._modify_vm(f'--nictracefile{adapter_number + 1} "{nio.pcap_output_file}"')
|
|
948
|
+
|
|
949
|
+
if not self._ethernet_adapters[adapter_number].get_nio(0):
|
|
950
|
+
await self._modify_vm(f"--cableconnected{adapter_number + 1} off")
|
|
951
|
+
|
|
952
|
+
for adapter_number in range(self._adapters, self._maximum_adapters):
|
|
953
|
+
log.debug(f"disabling remaining adapter {adapter_number}")
|
|
954
|
+
await self._modify_vm(f"--nic{adapter_number + 1} none")
|
|
955
|
+
|
|
956
|
+
async def _create_linked_clone(self):
|
|
957
|
+
"""
|
|
958
|
+
Creates a new linked clone.
|
|
959
|
+
"""
|
|
960
|
+
|
|
961
|
+
gns3_snapshot_exists = False
|
|
962
|
+
vm_info = await self._get_vm_info()
|
|
963
|
+
for entry, value in vm_info.items():
|
|
964
|
+
if entry.startswith("SnapshotName") and value == "GNS3 Linked Base for clones":
|
|
965
|
+
gns3_snapshot_exists = True
|
|
966
|
+
|
|
967
|
+
if not gns3_snapshot_exists:
|
|
968
|
+
result = await self.manager.execute("snapshot", [self._uuid, "take", "GNS3 Linked Base for clones"])
|
|
969
|
+
log.debug(f"GNS3 snapshot created: {result}")
|
|
970
|
+
|
|
971
|
+
args = [
|
|
972
|
+
self._uuid,
|
|
973
|
+
"--snapshot",
|
|
974
|
+
"GNS3 Linked Base for clones",
|
|
975
|
+
"--options",
|
|
976
|
+
"link",
|
|
977
|
+
"--name",
|
|
978
|
+
self.name,
|
|
979
|
+
"--basefolder",
|
|
980
|
+
self.working_dir,
|
|
981
|
+
"--register",
|
|
982
|
+
]
|
|
983
|
+
|
|
984
|
+
result = await self.manager.execute("clonevm", args)
|
|
985
|
+
log.debug(f"VirtualBox VM: {result} cloned")
|
|
986
|
+
|
|
987
|
+
# refresh the UUID and vmname to match with the clone
|
|
988
|
+
self._vmname = self._name
|
|
989
|
+
await self._refresh_vm_uuid()
|
|
990
|
+
await self.manager.execute("setextradata", [self._uuid, "GNS3/Clone", "yes"])
|
|
991
|
+
|
|
992
|
+
# We create a reset snapshot in order to simplify life of user who want to rollback their VM
|
|
993
|
+
# Warning: Do not document this it's seem buggy we keep it because Raizo students use it.
|
|
994
|
+
try:
|
|
995
|
+
args = [self._uuid, "take", "reset"]
|
|
996
|
+
result = await self.manager.execute("snapshot", args)
|
|
997
|
+
log.debug(f"Snapshot 'reset' created: {result}")
|
|
998
|
+
# It seem sometimes this failed due to internal race condition of Vbox
|
|
999
|
+
# we have no real explanation of this.
|
|
1000
|
+
except VirtualBoxError:
|
|
1001
|
+
log.warning("Snapshot 'reset' not created")
|
|
1002
|
+
|
|
1003
|
+
os.makedirs(os.path.join(self.working_dir, self._vmname), exist_ok=True)
|
|
1004
|
+
|
|
1005
|
+
async def _start_console(self):
|
|
1006
|
+
"""
|
|
1007
|
+
Starts remote console support for this VM.
|
|
1008
|
+
"""
|
|
1009
|
+
|
|
1010
|
+
if self.console and self.console_type == "telnet":
|
|
1011
|
+
pipe_name = self._get_pipe_name()
|
|
1012
|
+
try:
|
|
1013
|
+
self._remote_pipe = await asyncio_open_serial(pipe_name)
|
|
1014
|
+
except OSError as e:
|
|
1015
|
+
raise VirtualBoxError(f"Could not open serial pipe '{pipe_name}': {e}")
|
|
1016
|
+
server = AsyncioTelnetServer(reader=self._remote_pipe, writer=self._remote_pipe, binary=True, echo=True)
|
|
1017
|
+
try:
|
|
1018
|
+
self._telnet_server = await asyncio.start_server(
|
|
1019
|
+
server.run, self._manager.port_manager.console_host, self.console
|
|
1020
|
+
)
|
|
1021
|
+
except OSError as e:
|
|
1022
|
+
self.project.emit(
|
|
1023
|
+
"log.warning",
|
|
1024
|
+
{
|
|
1025
|
+
"message": f"Could not start Telnet server on socket {self._manager.port_manager.console_host}:{self.console}: {e}"
|
|
1026
|
+
},
|
|
1027
|
+
)
|
|
1028
|
+
|
|
1029
|
+
async def _stop_remote_console(self):
|
|
1030
|
+
"""
|
|
1031
|
+
Stops remote console support for this VM.
|
|
1032
|
+
"""
|
|
1033
|
+
if self._telnet_server:
|
|
1034
|
+
self._telnet_server.close()
|
|
1035
|
+
await self._telnet_server.wait_closed()
|
|
1036
|
+
self._remote_pipe.close()
|
|
1037
|
+
self._telnet_server = None
|
|
1038
|
+
|
|
1039
|
+
async def reset_console(self):
|
|
1040
|
+
"""
|
|
1041
|
+
Reset the console.
|
|
1042
|
+
"""
|
|
1043
|
+
|
|
1044
|
+
await self._stop_remote_console()
|
|
1045
|
+
await self._start_console()
|
|
1046
|
+
|
|
1047
|
+
@BaseNode.console_type.setter
|
|
1048
|
+
def console_type(self, new_console_type):
|
|
1049
|
+
"""
|
|
1050
|
+
Sets the console type for this VirtualBox VM.
|
|
1051
|
+
|
|
1052
|
+
:param new_console_type: console type (string)
|
|
1053
|
+
"""
|
|
1054
|
+
|
|
1055
|
+
if self.is_running() and self.console_type != new_console_type:
|
|
1056
|
+
raise VirtualBoxError(f'"{self._name}" must be stopped to change the console type to {new_console_type}')
|
|
1057
|
+
|
|
1058
|
+
super(VirtualBoxVM, VirtualBoxVM).console_type.__set__(self, new_console_type)
|
|
1059
|
+
|
|
1060
|
+
async def adapter_add_nio_binding(self, adapter_number, nio):
|
|
1061
|
+
"""
|
|
1062
|
+
Adds an adapter NIO binding.
|
|
1063
|
+
|
|
1064
|
+
:param adapter_number: adapter number
|
|
1065
|
+
:param nio: NIO instance to add to the slot/port
|
|
1066
|
+
"""
|
|
1067
|
+
|
|
1068
|
+
try:
|
|
1069
|
+
adapter = self._ethernet_adapters[adapter_number]
|
|
1070
|
+
except KeyError:
|
|
1071
|
+
raise VirtualBoxError(
|
|
1072
|
+
"Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(
|
|
1073
|
+
name=self.name, adapter_number=adapter_number
|
|
1074
|
+
)
|
|
1075
|
+
)
|
|
1076
|
+
|
|
1077
|
+
# check if trying to connect to a nat, bridged, host-only or any other special adapter
|
|
1078
|
+
nic_attachments = await self._get_nic_attachements(self._maximum_adapters)
|
|
1079
|
+
attachment = nic_attachments[adapter_number]
|
|
1080
|
+
if attachment in ("nat", "bridged", "intnet", "hostonly", "natnetwork"):
|
|
1081
|
+
if not self._use_any_adapter:
|
|
1082
|
+
raise VirtualBoxError(
|
|
1083
|
+
"Attachment '{attachment}' is already configured on adapter {adapter_number}. "
|
|
1084
|
+
"Please remove it or allow VirtualBox VM '{name}' to use any adapter.".format(
|
|
1085
|
+
attachment=attachment, adapter_number=adapter_number, name=self.name
|
|
1086
|
+
)
|
|
1087
|
+
)
|
|
1088
|
+
elif self.is_running():
|
|
1089
|
+
# dynamically configure an UDP tunnel attachment if the VM is already running
|
|
1090
|
+
local_nio = self._local_udp_tunnels[adapter_number][0]
|
|
1091
|
+
if local_nio and isinstance(local_nio, NIOUDP):
|
|
1092
|
+
await self._control_vm(f"nic{adapter_number + 1} generic UDPTunnel")
|
|
1093
|
+
await self._control_vm(f"nicproperty{adapter_number + 1} sport={local_nio.lport}")
|
|
1094
|
+
await self._control_vm(f"nicproperty{adapter_number + 1} dest={local_nio.rhost}")
|
|
1095
|
+
await self._control_vm(f"nicproperty{adapter_number + 1} dport={local_nio.rport}")
|
|
1096
|
+
await self._control_vm(f"setlinkstate{adapter_number + 1} on")
|
|
1097
|
+
|
|
1098
|
+
if self.is_running():
|
|
1099
|
+
try:
|
|
1100
|
+
await self.add_ubridge_udp_connection(
|
|
1101
|
+
f"VBOX-{self._id}-{adapter_number}", self._local_udp_tunnels[adapter_number][1], nio
|
|
1102
|
+
)
|
|
1103
|
+
except KeyError:
|
|
1104
|
+
raise VirtualBoxError(
|
|
1105
|
+
"Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(
|
|
1106
|
+
name=self.name, adapter_number=adapter_number
|
|
1107
|
+
)
|
|
1108
|
+
)
|
|
1109
|
+
await self._control_vm(f"setlinkstate{adapter_number + 1} on")
|
|
1110
|
+
|
|
1111
|
+
adapter.add_nio(0, nio)
|
|
1112
|
+
log.info(
|
|
1113
|
+
"VirtualBox VM '{name}' [{id}]: {nio} added to adapter {adapter_number}".format(
|
|
1114
|
+
name=self.name, id=self.id, nio=nio, adapter_number=adapter_number
|
|
1115
|
+
)
|
|
1116
|
+
)
|
|
1117
|
+
|
|
1118
|
+
async def adapter_update_nio_binding(self, adapter_number, nio):
|
|
1119
|
+
"""
|
|
1120
|
+
Update an adapter NIO binding.
|
|
1121
|
+
|
|
1122
|
+
:param adapter_number: adapter number
|
|
1123
|
+
:param nio: NIO instance to update on the adapter
|
|
1124
|
+
"""
|
|
1125
|
+
|
|
1126
|
+
if self.is_running():
|
|
1127
|
+
try:
|
|
1128
|
+
await self.update_ubridge_udp_connection(
|
|
1129
|
+
f"VBOX-{self._id}-{adapter_number}", self._local_udp_tunnels[adapter_number][1], nio
|
|
1130
|
+
)
|
|
1131
|
+
if nio.suspend:
|
|
1132
|
+
await self._control_vm(f"setlinkstate{adapter_number + 1} off")
|
|
1133
|
+
else:
|
|
1134
|
+
await self._control_vm(f"setlinkstate{adapter_number + 1} on")
|
|
1135
|
+
except IndexError:
|
|
1136
|
+
raise VirtualBoxError(
|
|
1137
|
+
'Adapter {adapter_number} does not exist on VirtualBox VM "{name}"'.format(
|
|
1138
|
+
name=self._name, adapter_number=adapter_number
|
|
1139
|
+
)
|
|
1140
|
+
)
|
|
1141
|
+
|
|
1142
|
+
async def adapter_remove_nio_binding(self, adapter_number):
|
|
1143
|
+
"""
|
|
1144
|
+
Removes an adapter NIO binding.
|
|
1145
|
+
|
|
1146
|
+
:param adapter_number: adapter number
|
|
1147
|
+
|
|
1148
|
+
:returns: NIO instance
|
|
1149
|
+
"""
|
|
1150
|
+
|
|
1151
|
+
try:
|
|
1152
|
+
adapter = self._ethernet_adapters[adapter_number]
|
|
1153
|
+
except KeyError:
|
|
1154
|
+
raise VirtualBoxError(
|
|
1155
|
+
"Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(
|
|
1156
|
+
name=self.name, adapter_number=adapter_number
|
|
1157
|
+
)
|
|
1158
|
+
)
|
|
1159
|
+
|
|
1160
|
+
await self.stop_capture(adapter_number)
|
|
1161
|
+
if self.is_running():
|
|
1162
|
+
await self._ubridge_send("bridge delete {name}".format(name=f"VBOX-{self._id}-{adapter_number}"))
|
|
1163
|
+
vm_state = await self._get_vm_state()
|
|
1164
|
+
if vm_state == "running":
|
|
1165
|
+
await self._control_vm(f"setlinkstate{adapter_number + 1} off")
|
|
1166
|
+
|
|
1167
|
+
nio = adapter.get_nio(0)
|
|
1168
|
+
if isinstance(nio, NIOUDP):
|
|
1169
|
+
self.manager.port_manager.release_udp_port(nio.lport, self._project)
|
|
1170
|
+
adapter.remove_nio(0)
|
|
1171
|
+
|
|
1172
|
+
log.info(
|
|
1173
|
+
"VirtualBox VM '{name}' [{id}]: {nio} removed from adapter {adapter_number}".format(
|
|
1174
|
+
name=self.name, id=self.id, nio=nio, adapter_number=adapter_number
|
|
1175
|
+
)
|
|
1176
|
+
)
|
|
1177
|
+
return nio
|
|
1178
|
+
|
|
1179
|
+
def get_nio(self, adapter_number):
|
|
1180
|
+
"""
|
|
1181
|
+
Gets an adapter NIO binding.
|
|
1182
|
+
|
|
1183
|
+
:param adapter_number: adapter number
|
|
1184
|
+
|
|
1185
|
+
:returns: NIO instance
|
|
1186
|
+
"""
|
|
1187
|
+
|
|
1188
|
+
try:
|
|
1189
|
+
adapter = self.ethernet_adapters[adapter_number]
|
|
1190
|
+
except KeyError:
|
|
1191
|
+
raise VirtualBoxError(
|
|
1192
|
+
"Adapter {adapter_number} doesn't exist on VirtualBox VM '{name}'".format(
|
|
1193
|
+
name=self.name, adapter_number=adapter_number
|
|
1194
|
+
)
|
|
1195
|
+
)
|
|
1196
|
+
|
|
1197
|
+
nio = adapter.get_nio(0)
|
|
1198
|
+
|
|
1199
|
+
if not nio:
|
|
1200
|
+
raise VirtualBoxError(f"Adapter {adapter_number} is not connected")
|
|
1201
|
+
|
|
1202
|
+
return nio
|
|
1203
|
+
|
|
1204
|
+
def is_running(self):
|
|
1205
|
+
"""
|
|
1206
|
+
:returns: True if the vm is not stopped
|
|
1207
|
+
"""
|
|
1208
|
+
return self.ubridge is not None
|
|
1209
|
+
|
|
1210
|
+
async def start_capture(self, adapter_number, output_file):
|
|
1211
|
+
"""
|
|
1212
|
+
Starts a packet capture.
|
|
1213
|
+
|
|
1214
|
+
:param adapter_number: adapter number
|
|
1215
|
+
:param output_file: PCAP destination file for the capture
|
|
1216
|
+
"""
|
|
1217
|
+
|
|
1218
|
+
nio = self.get_nio(adapter_number)
|
|
1219
|
+
if nio.capturing:
|
|
1220
|
+
raise VirtualBoxError(f"Packet capture is already activated on adapter {adapter_number}")
|
|
1221
|
+
|
|
1222
|
+
nio.start_packet_capture(output_file)
|
|
1223
|
+
if self.ubridge:
|
|
1224
|
+
await self._ubridge_send(
|
|
1225
|
+
'bridge start_capture {name} "{output_file}"'.format(
|
|
1226
|
+
name=f"VBOX-{self._id}-{adapter_number}", output_file=output_file
|
|
1227
|
+
)
|
|
1228
|
+
)
|
|
1229
|
+
|
|
1230
|
+
log.info(
|
|
1231
|
+
"VirtualBox VM '{name}' [{id}]: starting packet capture on adapter {adapter_number}".format(
|
|
1232
|
+
name=self.name, id=self.id, adapter_number=adapter_number
|
|
1233
|
+
)
|
|
1234
|
+
)
|
|
1235
|
+
|
|
1236
|
+
async def stop_capture(self, adapter_number):
|
|
1237
|
+
"""
|
|
1238
|
+
Stops a packet capture.
|
|
1239
|
+
|
|
1240
|
+
:param adapter_number: adapter number
|
|
1241
|
+
"""
|
|
1242
|
+
|
|
1243
|
+
nio = self.get_nio(adapter_number)
|
|
1244
|
+
if not nio.capturing:
|
|
1245
|
+
return
|
|
1246
|
+
|
|
1247
|
+
nio.stop_packet_capture()
|
|
1248
|
+
if self.ubridge:
|
|
1249
|
+
await self._ubridge_send("bridge stop_capture {name}".format(name=f"VBOX-{self._id}-{adapter_number}"))
|
|
1250
|
+
|
|
1251
|
+
log.info(
|
|
1252
|
+
"VirtualBox VM '{name}' [{id}]: stopping packet capture on adapter {adapter_number}".format(
|
|
1253
|
+
name=self.name, id=self.id, adapter_number=adapter_number
|
|
1254
|
+
)
|
|
1255
|
+
)
|