* Fix mouse offset issues with VNC in Qemu. Fixes #2335
* Add project.created, project.opened and project.deleted controller notification stream. Move project.updated and project.closed from project notification to controller notification stream.
* Do not stop searching for Qemu binaries if one binary cannot be executed. Ref #2306
* Fix Ethernet switch and Ethernet hub port validations. Fixes #2334
* Update CORS policy
* Add custom executable paths on Windows
* Upgrade sentry-sdk and aiohttp
## 2.2.44.1 07/11/2023
* Catch exceptions when computing image checksums. Ref https://github.com/GNS3/gns3-server/issues/2228
<tr><td>cpu_throttling</td> <td> </td> <td>['integer', 'null']</td> <td>Percentage of CPU allowed for QEMU</td> </tr>
<tr><td>cpus</td> <td> </td> <td>['integer', 'null']</td> <td>Number of vCPUs</td> </tr>
<tr><td>create_config_disk</td> <td> </td> <td>['boolean', 'null']</td> <td>Automatically create a config disk on HDD disk interface (secondary slave)</td> </tr>
<tr><td>process_priority</td> <td> </td> <td>enum</td> <td>Possible values: realtime, very high, high, normal, low, very low, null</td> </tr>
<tr><td>qemu_path</td> <td> </td> <td>['string', 'null']</td> <td>Path to QEMU</td> </tr>
<tr><td>ram</td> <td> </td> <td>['integer', 'null']</td> <td>Amount of RAM in MB</td> </tr>
<tr><td>replicate_network_connection_state</td> <td> </td> <td>['boolean', 'null']</td> <td>Replicate the network connection state for links in Qemu</td> </tr>
<tr><td>tpm</td> <td> </td> <td>['boolean', 'null']</td> <td>Enable the Trusted Platform Module (TPM) in Qemu</td> </tr>
<tr><td>uefi</td> <td> </td> <td>['boolean', 'null']</td> <td>Enable the UEFI boot mode in Qemu</td> </tr>
<tr><td>usage</td> <td> </td> <td>string</td> <td>How to use the Qemu VM</td> </tr>
<tr><td>cpu_throttling</td> <td>✔</td> <td>integer</td> <td>Percentage of CPU allowed for QEMU</td> </tr>
<tr><td>cpus</td> <td>✔</td> <td>['integer', 'null']</td> <td>Number of vCPUs</td> </tr>
<tr><td>create_config_disk</td> <td>✔</td> <td>['boolean', 'null']</td> <td>Automatically create a config disk on HDD disk interface (secondary slave)</td> </tr>
<tr><td>hda_disk_image</td> <td>✔</td> <td>string</td> <td>QEMU hda disk image path</td> </tr>
<tr><td>hda_disk_image_md5sum</td> <td>✔</td> <td>['string', 'null']</td> <td>QEMU hda disk image checksum</td> </tr>
<tr><td>qemu_path</td> <td>✔</td> <td>string</td> <td>Path to QEMU</td> </tr>
<tr><td>ram</td> <td>✔</td> <td>integer</td> <td>Amount of RAM in MB</td> </tr>
<tr><td>replicate_network_connection_state</td> <td>✔</td> <td>boolean</td> <td>Replicate the network connection state for links in Qemu</td> </tr>
<tr><td>save_vm_state</td> <td> </td> <td>['boolean', 'null']</td> <td>Save VM state support</td> </tr>
<tr><td>cpu_throttling</td> <td>✔</td> <td>integer</td> <td>Percentage of CPU allowed for QEMU</td> </tr>
<tr><td>cpus</td> <td>✔</td> <td>['integer', 'null']</td> <td>Number of vCPUs</td> </tr>
<tr><td>create_config_disk</td> <td>✔</td> <td>['boolean', 'null']</td> <td>Automatically create a config disk on HDD disk interface (secondary slave)</td> </tr>
<tr><td>hda_disk_image</td> <td>✔</td> <td>string</td> <td>QEMU hda disk image path</td> </tr>
<tr><td>hda_disk_image_md5sum</td> <td>✔</td> <td>['string', 'null']</td> <td>QEMU hda disk image checksum</td> </tr>
<tr><td>qemu_path</td> <td>✔</td> <td>string</td> <td>Path to QEMU</td> </tr>
<tr><td>ram</td> <td>✔</td> <td>integer</td> <td>Amount of RAM in MB</td> </tr>
<tr><td>replicate_network_connection_state</td> <td>✔</td> <td>boolean</td> <td>Replicate the network connection state for links in Qemu</td> </tr>
<tr><td>save_vm_state</td> <td> </td> <td>['boolean', 'null']</td> <td>Save VM state support</td> </tr>
<tr><td>cpu_throttling</td> <td> </td> <td>['integer', 'null']</td> <td>Percentage of CPU allowed for QEMU</td> </tr>
<tr><td>cpus</td> <td> </td> <td>['integer', 'null']</td> <td>Number of vCPUs</td> </tr>
<tr><td>create_config_disk</td> <td> </td> <td>['boolean', 'null']</td> <td>Automatically create a config disk on HDD disk interface (secondary slave)</td> </tr>
<tr><td>process_priority</td> <td> </td> <td>enum</td> <td>Possible values: realtime, very high, high, normal, low, very low, null</td> </tr>
<tr><td>qemu_path</td> <td> </td> <td>['string', 'null']</td> <td>Path to QEMU</td> </tr>
<tr><td>ram</td> <td> </td> <td>['integer', 'null']</td> <td>Amount of RAM in MB</td> </tr>
<tr><td>replicate_network_connection_state</td> <td> </td> <td>['boolean', 'null']</td> <td>Replicate the network connection state for links in Qemu</td> </tr>
<tr><td>tpm</td> <td> </td> <td>['boolean', 'null']</td> <td>Enable the Trusted Platform Module (TPM) in Qemu</td> </tr>
<tr><td>uefi</td> <td> </td> <td>['boolean', 'null']</td> <td>Enable the UEFI boot mode in Qemu</td> </tr>
<tr><td>usage</td> <td> </td> <td>string</td> <td>How to use the QEMU VM</td> </tr>
<tr><td>cpu_throttling</td> <td>✔</td> <td>integer</td> <td>Percentage of CPU allowed for QEMU</td> </tr>
<tr><td>cpus</td> <td>✔</td> <td>['integer', 'null']</td> <td>Number of vCPUs</td> </tr>
<tr><td>create_config_disk</td> <td>✔</td> <td>['boolean', 'null']</td> <td>Automatically create a config disk on HDD disk interface (secondary slave)</td> </tr>
<tr><td>hda_disk_image</td> <td>✔</td> <td>string</td> <td>QEMU hda disk image path</td> </tr>
<tr><td>hda_disk_image_md5sum</td> <td>✔</td> <td>['string', 'null']</td> <td>QEMU hda disk image checksum</td> </tr>
<tr><td>qemu_path</td> <td>✔</td> <td>string</td> <td>Path to QEMU</td> </tr>
<tr><td>ram</td> <td>✔</td> <td>integer</td> <td>Amount of RAM in MB</td> </tr>
<tr><td>replicate_network_connection_state</td> <td>✔</td> <td>boolean</td> <td>Replicate the network connection state for links in Qemu</td> </tr>
<tr><td>save_vm_state</td> <td> </td> <td>['boolean', 'null']</td> <td>Save VM state support</td> </tr>
<tr><td>cpu_throttling</td> <td>✔</td> <td>integer</td> <td>Percentage of CPU allowed for QEMU</td> </tr>
<tr><td>cpus</td> <td>✔</td> <td>['integer', 'null']</td> <td>Number of vCPUs</td> </tr>
<tr><td>create_config_disk</td> <td>✔</td> <td>['boolean', 'null']</td> <td>Automatically create a config disk on HDD disk interface (secondary slave)</td> </tr>
<tr><td>hda_disk_image</td> <td>✔</td> <td>string</td> <td>QEMU hda disk image path</td> </tr>
<tr><td>hda_disk_image_md5sum</td> <td>✔</td> <td>['string', 'null']</td> <td>QEMU hda disk image checksum</td> </tr>
<tr><td>qemu_path</td> <td>✔</td> <td>string</td> <td>Path to QEMU</td> </tr>
<tr><td>ram</td> <td>✔</td> <td>integer</td> <td>Amount of RAM in MB</td> </tr>
<tr><td>replicate_network_connection_state</td> <td>✔</td> <td>boolean</td> <td>Replicate the network connection state for links in Qemu</td> </tr>
<tr><td>save_vm_state</td> <td> </td> <td>['boolean', 'null']</td> <td>Save VM state support</td> </tr>
"usage": "Configure interfaces in /opt/bootlocal.sh, BIRD configuration is done in /usr/local/etc/bird",
"usage": "\n*** BIRD v1 is end-of-life ***\nPlease use the BIRD2 appliance.\n\nConfigure interfaces in /opt/bootlocal.sh, BIRD configuration is done in /usr/local/etc/bird",
"usage": "Make sure the Boot priority of the configuration template is HDD or CD.\n\nAbort the BCM process and format the flash after first boot by entering these commands:\nen\nformat flash:\n\nSometimes the flash device is not available after boot.",
"usage": "Make sure the Boot priority of the configuration template is HDD or CD.\n\nFor FTOS 9.8, switch to vnc console, start the device, abort the BMP process and format the flash after first boot by entering these commands:\nen\nformat flash:\n\nSometimes the flash device is not available after boot.",
"usage": "You should download Red Hat Enterprise Linux KVM Guest Image from https://access.redhat.com/downloads/content/479/ver=/rhel---9/9.2/x86_64/product-software attach/customize cloud-init.iso and start.\nusername: cloud-user\npassword: redhat",
"maintainer": "Da-Geek",
"maintainer_email": "dageek@dageeks-geeks.gg",
"usage": "You should download Red Hat Enterprise Linux KVM Guest Image from https://access.redhat.com/downloads/content/479/ver=/rhel---9/9.3/x86_64/product-software attach/customize rhel-cloud-init.iso and start.\nusername: cloud-user\npassword: redhat",
!function(){"use strict";vare,v={},g={};functionn(e){vara=g[e];if(void0!==a)returna.exports;vart=g[e]={id:e,loaded:!1,exports:{}};returnv[e](t,t.exports,n),t.loaded=!0,t.exports}n.m=v,e=[],n.O=function(a,t,u,o){if(!t){varr=1/0;for(i=0;i<e.length;i++){t=e[i][0],u=e[i][1],o=e[i][2];for(varl=!0,f=0;f<t.length;f++)(!1&o||r>=o)&&Object.keys(n.O).every(function(b){returnn.O[b](t[f])})?t.splice(f--,1):(l=!1,o<r&&(r=o));if(l){e.splice(i--,1);vars=u();void0!==s&&(a=s)}}returna}o=o||0;for(vari=e.length;i>0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,u,o]},n.n=function(e){vara=e&&e.__esModule?function(){returne.default}:function(){returne};returnn.d(a,{a:a}),a},n.d=function(e,a){for(vartina)n.o(a,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:a[t]})},n.f={},n.e=function(e){returnPromise.all(Object.keys(n.f).reduce(function(a,t){returnn.f[t](e,a),a},[]))},n.u=function(e){returne+".49028ab13de5de406c90.js"},n.miniCssF=function(e){return"styles.f8555f2eecf8cf87f666.css"},n.hmd=function(e){return(e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set:function(){thrownewError("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e},n.o=function(e,a){returnObject.prototype.hasOwnProperty.call(e,a)},function(){vare={},a="gns3-web-ui:";n.l=function(t,u,o,i){if(e[t])e[t].push(u);else{varr,l;if(void0!==o)for(varf=document.getElementsByTagName("script"),s=0;s<f.length;s++){varc=f[s];if(c.getAttribute("src")==t||c.getAttribute("data-webpack")==a+o){r=c;break}}r||(l=!0,(r=document.createElement("script")).charset="utf-8",r.timeout=120,n.nc&&r.setAttribute("nonce",n.nc),r.setAttribute("data-webpack",a+o),r.src=n.tu(t)),e[t]=[u];vard=function(h,b){r.onerror=r.onload=null,clearTimeout(p);var_=e[t];if(deletee[t],r.parentNode&&r.parentNode.removeChild(r),_&&_.forEach(function(m){returnm(b)}),h)returnh(b)},p=setTimeout(d.bind(null,void0,{type:"timeout",target:r}),12e4);r.onerror=d.bind(null,r.onerror),r.onload=d.bind(null,r.onload),l&&document.head.appendChild(r)}}}(),n.r=function(e){"undefined"!=typeofSymbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},function(){vare;n.tu=function(a){returnvoid0===e&&(e={createScriptURL:function(t){returnt}},"undefined"!=typeoftrustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e.createScriptURL(a)}}(),n.p="",function(){vare={666:0};n.f.j=function(u,o){vari=n.o(e,u)?e[u]:void0;if(0!==i)if(i)o.push(i[2]);elseif(666!=u){varr=newPromise(function(c,d){i=e[u]=[c,d]});o.push(i[2]=r);varl=n.p+n.u(u),f=newError;n.l(l,function(c){if(n.o(e,u)&&(0!==(i=e[u])&&(e[u]=void0),i)){vard=c&&("load"===c.type?"missing":c.type),p=c&&c.target&&c.target.src;f.message="Loading chunk "+u+" failed.\n("+d+": "+p+")",f.name="ChunkLoadError",f.type=d,f.request=p,i[1](f)}},"chunk-"+u,u)}elsee[u]=0},n.O.j=function(u){return0===e[u]};vara=function(u,o){varf,s,i=o[0],r=o[1],l=o[2],c=0;for(finr)n.o(r,f)&&(n.m[f]=r[f]);if(l)vard=l(n);for(u&&u(o);c<i.length;c++)n.o(e,s=i[c])&&e[s]&&e[s][0](),e[i[c]]=0;returnn.O(d)},t=self.webpackChunkgns3_web_ui=self.webpackChunkgns3_web_ui||[];t.forEach(a.bind(null,0)),t.push=a.bind(null,t.push.bind(t))}()}();
!function(){"use strict";vare,v={},g={};functionn(e){vara=g[e];if(void0!==a)returna.exports;vart=g[e]={id:e,loaded:!1,exports:{}};returnv[e].call(t.exports,t,t.exports,n),t.loaded=!0,t.exports}n.m=v,e=[],n.O=function(a,t,u,o){if(!t){varr=1/0;for(i=0;i<e.length;i++){t=e[i][0],u=e[i][1],o=e[i][2];for(varl=!0,f=0;f<t.length;f++)(!1&o||r>=o)&&Object.keys(n.O).every(function(b){returnn.O[b](t[f])})?t.splice(f--,1):(l=!1,o<r&&(r=o));if(l){e.splice(i--,1);vars=u();void0!==s&&(a=s)}}returna}o=o||0;for(vari=e.length;i>0&&e[i-1][2]>o;i--)e[i]=e[i-1];e[i]=[t,u,o]},n.n=function(e){vara=e&&e.__esModule?function(){returne.default}:function(){returne};returnn.d(a,{a:a}),a},n.d=function(e,a){for(vartina)n.o(a,t)&&!n.o(e,t)&&Object.defineProperty(e,t,{enumerable:!0,get:a[t]})},n.f={},n.e=function(e){returnPromise.all(Object.keys(n.f).reduce(function(a,t){returnn.f[t](e,a),a},[]))},n.u=function(e){returne+".49028ab13de5de406c90.js"},n.miniCssF=function(e){return"styles.f8555f2eecf8cf87f666.css"},n.hmd=function(e){return(e=Object.create(e)).children||(e.children=[]),Object.defineProperty(e,"exports",{enumerable:!0,set:function(){thrownewError("ES Modules may not assign module.exports or exports.*, Use ESM export syntax, instead: "+e.id)}}),e},n.o=function(e,a){returnObject.prototype.hasOwnProperty.call(e,a)},function(){vare={},a="gns3-web-ui:";n.l=function(t,u,o,i){if(e[t])e[t].push(u);else{varr,l;if(void0!==o)for(varf=document.getElementsByTagName("script"),s=0;s<f.length;s++){varc=f[s];if(c.getAttribute("src")==t||c.getAttribute("data-webpack")==a+o){r=c;break}}r||(l=!0,(r=document.createElement("script")).charset="utf-8",r.timeout=120,n.nc&&r.setAttribute("nonce",n.nc),r.setAttribute("data-webpack",a+o),r.src=n.tu(t)),e[t]=[u];vard=function(h,b){r.onerror=r.onload=null,clearTimeout(p);var_=e[t];if(deletee[t],r.parentNode&&r.parentNode.removeChild(r),_&&_.forEach(function(m){returnm(b)}),h)returnh(b)},p=setTimeout(d.bind(null,void0,{type:"timeout",target:r}),12e4);r.onerror=d.bind(null,r.onerror),r.onload=d.bind(null,r.onload),l&&document.head.appendChild(r)}}}(),n.r=function(e){"undefined"!=typeofSymbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},function(){vare;n.tu=function(a){returnvoid0===e&&(e={createScriptURL:function(t){returnt}},"undefined"!=typeoftrustedTypes&&trustedTypes.createPolicy&&(e=trustedTypes.createPolicy("angular#bundler",e))),e.createScriptURL(a)}}(),n.p="",function(){vare={666:0};n.f.j=function(u,o){vari=n.o(e,u)?e[u]:void0;if(0!==i)if(i)o.push(i[2]);elseif(666!=u){varr=newPromise(function(c,d){i=e[u]=[c,d]});o.push(i[2]=r);varl=n.p+n.u(u),f=newError;n.l(l,function(c){if(n.o(e,u)&&(0!==(i=e[u])&&(e[u]=void0),i)){vard=c&&("load"===c.type?"missing":c.type),p=c&&c.target&&c.target.src;f.message="Loading chunk "+u+" failed.\n("+d+": "+p+")",f.name="ChunkLoadError",f.type=d,f.request=p,i[1](f)}},"chunk-"+u,u)}elsee[u]=0},n.O.j=function(u){return0===e[u]};vara=function(u,o){varf,s,i=o[0],r=o[1],l=o[2],c=0;for(finr)n.o(r,f)&&(n.m[f]=r[f]);if(l)vard=l(n);for(u&&u(o);c<i.length;c++)n.o(e,s=i[c])&&e[s]&&e[s][0](),e[i[c]]=0;returnn.O(d)},t=self.webpackChunkgns3_web_ui=self.webpackChunkgns3_web_ui||[];t.forEach(a.bind(null,0)),t.push=a.bind(null,t.push.bind(t))}()}();