From fefcbb3ecb27ccbec36a21ffe43043d13a159097 Mon Sep 17 00:00:00 2001 From: innobead Date: Tue, 28 May 2024 05:17:03 +0000 Subject: [PATCH] deploy: 196d0671daa23b26b0a273e8c1a22aa02dfa77a9 --- 404.html | 8 +++---- ...token-5c960a532d60ee118583a1ace83445af.png | Bin 0 -> 129067 bytes ...ntial-e9e796433e854c0e298536bee7b63ac4.png | Bin 0 -> 128715 bytes assets/js/0bae4d63.1a0ef17d.js | 1 - assets/js/0bae4d63.acfad681.js | 1 + assets/js/0e8a02fe.0752395a.js | 1 - assets/js/0e8a02fe.745d4dc7.js | 1 + assets/js/1981d4a9.cf98e349.js | 1 + assets/js/363c8c79.dbe42e21.js | 1 + assets/js/4da27a57.9a69a742.js | 1 + assets/js/500c69b0.1b6223bd.js | 1 - assets/js/500c69b0.e99dd8be.js | 1 + assets/js/59455c69.fb062781.js | 1 + assets/js/6817044f.74724a1b.js | 1 + assets/js/6817044f.a630664b.js | 1 - assets/js/7a1ef0d5.9cb24a9f.js | 1 + assets/js/7a1ef0d5.df98e5c9.js | 1 - ...1b631.8b1ea9aa.js => 7fd1b631.355e0309.js} | 2 +- ...ce478.0743eddd.js => 91cce478.b6a34e80.js} | 2 +- ...7d83e.0f706d3b.js => 96b7d83e.59ff2d58.js} | 2 +- ...95991.9f8bccbc.js => bbd95991.9f5b50f0.js} | 2 +- assets/js/c4fb252f.477b0c9a.js | 1 + assets/js/c6f0cebc.26dab8f4.js | 1 + assets/js/e146e4a6.9c2fd683.js | 1 + assets/js/f91b0440.6a867aeb.js | 1 + assets/js/main.2ae3201e.js | 2 ++ ...CENSE.txt => main.2ae3201e.js.LICENSE.txt} | 0 assets/js/main.a5ae1e14.js | 2 -- assets/js/runtime~main.0bee2a75.js | 1 - assets/js/runtime~main.601d7081.js | 1 + authentication/index.html | 8 +++---- blog/archive/index.html | 8 +++---- development/dev-mode/index.html | 8 +++---- harvester-network/index.html | 8 +++---- import-image/index.html | 8 +++---- index.html | 8 +++---- .../harvester-configuration/index.html | 8 +++---- installation/iso-install/index.html | 8 +++---- installation/pxe-boot-install/index.html | 8 +++---- intro/index.html | 8 +++---- kb/archive/index.html | 10 ++++----- kb/atom.xml | 21 +++++++++++++++++- .../index.html | 10 ++++----- .../index.html | 10 ++++----- .../index.html | 10 ++++----- .../index.html | 10 ++++----- kb/index.html | 12 +++++----- .../index.html | 12 +++++----- kb/install_netapp_trident_csi/index.html | 10 ++++----- kb/multiple-nics-vm-connectivity/index.html | 10 ++++----- kb/nic-naming-scheme/index.html | 10 ++++----- kb/package_your_own_toolbox_image/index.html | 10 ++++----- kb/page/2/index.html | 10 ++++----- .../index.html | 21 ++++++++++++++++++ kb/rss.xml | 13 ++++++++++- .../index.html | 10 ++++----- kb/tags/best-practices/index.html | 10 ++++----- kb/tags/calculation/index.html | 10 ++++----- kb/tags/ceph/index.html | 10 ++++----- kb/tags/cloud-credentials/index.html | 21 ++++++++++++++++++ kb/tags/cloud-provider/index.html | 10 ++++----- kb/tags/configuration/index.html | 10 ++++----- kb/tags/container/index.html | 10 ++++----- kb/tags/csi/index.html | 10 ++++----- kb/tags/debug/index.html | 10 ++++----- kb/tags/disk-performance/index.html | 10 ++++----- kb/tags/disk/index.html | 10 ++++----- kb/tags/filesystem-trim/index.html | 10 ++++----- kb/tags/filesystem/index.html | 10 ++++----- kb/tags/harvester/index.html | 14 ++++++------ kb/tags/harvester/page/2/index.html | 21 ++++++++++++++++++ kb/tags/index.html | 10 ++++----- kb/tags/ip-pool/index.html | 10 ++++----- kb/tags/live-migration/index.html | 10 ++++----- kb/tags/load-balancer/index.html | 10 ++++----- kb/tags/longhorn/index.html | 10 ++++----- kb/tags/network/index.html | 10 ++++----- kb/tags/policy/index.html | 10 ++++----- kb/tags/priority-class/index.html | 10 ++++----- kb/tags/rancher-integration/index.html | 10 ++++----- kb/tags/rancher/index.html | 21 ++++++++++++++++++ kb/tags/reserved-resource/index.html | 10 ++++----- kb/tags/resource-metrics/index.html | 10 ++++----- kb/tags/rook/index.html | 10 ++++----- kb/tags/root/index.html | 10 ++++----- kb/tags/scheduling/index.html | 10 ++++----- kb/tags/storage/index.html | 10 ++++----- kb/tags/strategy/index.html | 10 ++++----- kb/tags/upgrade/index.html | 10 ++++----- kb/tags/virtual-machine/index.html | 10 ++++----- kb/tags/vm/index.html | 10 ++++----- .../index.html | 10 ++++----- .../index.html | 10 ++++----- kb/use_rook_ceph_external_storage/index.html | 10 ++++----- kb/vm-scheduling/index.html | 10 ++++----- .../index.html | 10 ++++----- markdown-page/index.html | 8 +++---- rancher-intergration/node-driver/index.html | 8 +++---- .../rancher-integration/index.html | 8 +++---- sitemap.xml | 2 +- upgrade/index.html | 8 +++---- vm-management/access-to-the-vm/index.html | 8 +++---- vm-management/backup-restore/index.html | 8 +++---- vm-management/create-vm/index.html | 8 +++---- vm-management/live-migration/index.html | 8 +++---- 105 files changed, 467 insertions(+), 345 deletions(-) create mode 100644 assets/images/api-token-5c960a532d60ee118583a1ace83445af.png create mode 100644 assets/images/identify-cloud-credential-e9e796433e854c0e298536bee7b63ac4.png delete mode 100644 assets/js/0bae4d63.1a0ef17d.js create mode 100644 assets/js/0bae4d63.acfad681.js delete mode 100644 assets/js/0e8a02fe.0752395a.js create mode 100644 assets/js/0e8a02fe.745d4dc7.js create mode 100644 assets/js/1981d4a9.cf98e349.js create mode 100644 assets/js/363c8c79.dbe42e21.js create mode 100644 assets/js/4da27a57.9a69a742.js delete mode 100644 assets/js/500c69b0.1b6223bd.js create mode 100644 assets/js/500c69b0.e99dd8be.js create mode 100644 assets/js/59455c69.fb062781.js create mode 100644 assets/js/6817044f.74724a1b.js delete mode 100644 assets/js/6817044f.a630664b.js create mode 100644 assets/js/7a1ef0d5.9cb24a9f.js delete mode 100644 assets/js/7a1ef0d5.df98e5c9.js rename assets/js/{7fd1b631.8b1ea9aa.js => 7fd1b631.355e0309.js} (80%) rename assets/js/{91cce478.0743eddd.js => 91cce478.b6a34e80.js} (80%) rename assets/js/{96b7d83e.0f706d3b.js => 96b7d83e.59ff2d58.js} (52%) rename assets/js/{bbd95991.9f8bccbc.js => bbd95991.9f5b50f0.js} (75%) create mode 100644 assets/js/c4fb252f.477b0c9a.js create mode 100644 assets/js/c6f0cebc.26dab8f4.js create mode 100644 assets/js/e146e4a6.9c2fd683.js create mode 100644 assets/js/f91b0440.6a867aeb.js create mode 100644 assets/js/main.2ae3201e.js rename assets/js/{main.a5ae1e14.js.LICENSE.txt => main.2ae3201e.js.LICENSE.txt} (100%) delete mode 100644 assets/js/main.a5ae1e14.js delete mode 100644 assets/js/runtime~main.0bee2a75.js create mode 100644 assets/js/runtime~main.601d7081.js create mode 100644 kb/renew_harvester_cloud_credentials/index.html create mode 100644 kb/tags/cloud-credentials/index.html create mode 100644 kb/tags/harvester/page/2/index.html create mode 100644 kb/tags/rancher/index.html diff --git a/404.html b/404.html index 6abd1efb..49ca539f 100644 --- a/404.html +++ b/404.html @@ -9,13 +9,13 @@ Page Not Found | The open-source hyperconverged infrastructure solution for a cloud-native world - - + +
Skip to main content

Page Not Found

We could not find what you were looking for.

Please contact the owner of the site that linked you to the original URL and let them know their link is broken.

- - + + \ No newline at end of file diff --git a/assets/images/api-token-5c960a532d60ee118583a1ace83445af.png b/assets/images/api-token-5c960a532d60ee118583a1ace83445af.png new file mode 100644 index 0000000000000000000000000000000000000000..c92af1df324802f3bfc621cddd91b7cc936a740e GIT binary patch literal 129067 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ŠX5PEo7>})DM6X=1&;+oBSGx#^(wl|TXF=|fj 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 Z_ncfBdyI8DTLt=T+2HJ0@vHam{{iY@>9ha< literal 0 HcmV?d00001 diff --git a/assets/images/identify-cloud-credential-e9e796433e854c0e298536bee7b63ac4.png b/assets/images/identify-cloud-credential-e9e796433e854c0e298536bee7b63ac4.png new file mode 100644 index 0000000000000000000000000000000000000000..a82a768af44b246e34b84a5b60b5c53053ed7b5e GIT binary patch literal 128715 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 literal 0 HcmV?d00001 diff --git a/assets/js/0bae4d63.1a0ef17d.js b/assets/js/0bae4d63.1a0ef17d.js deleted file mode 100644 index 5c60f521..00000000 --- a/assets/js/0bae4d63.1a0ef17d.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[910],{3905:function(e,t,n){n.d(t,{Zo:function(){return c},kt:function(){return p}});var a=n(7294);function i(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function o(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var a=Object.getOwnPropertySymbols(e);t&&(a=a.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,a)}return n}function r(e){for(var t=1;t=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=d(n),p=i,h=u["".concat(l,".").concat(p)]||u[p]||m[p]||o;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function p(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var d=2;d=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=d(n),p=i,h=u["".concat(l,".").concat(p)]||u[p]||m[p]||o;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function p(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var d=2;d=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=d(n),p=i,h=u["".concat(l,".").concat(p)]||u[p]||m[p]||o;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function p(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var d=2;d=0||(i[n]=e[n]);return i}(e,t);if(Object.getOwnPropertySymbols){var o=Object.getOwnPropertySymbols(e);for(a=0;a=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(i[n]=e[n])}return i}var l=a.createContext({}),d=function(e){var t=a.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):r(r({},t),e)),n},c=function(e){var t=d(e.components);return a.createElement(l.Provider,{value:t},e.children)},m={inlineCode:"code",wrapper:function(e){var t=e.children;return a.createElement(a.Fragment,{},t)}},u=a.forwardRef((function(e,t){var n=e.components,i=e.mdxType,o=e.originalType,l=e.parentName,c=s(e,["components","mdxType","originalType","parentName"]),u=d(n),p=i,h=u["".concat(l,".").concat(p)]||u[p]||m[p]||o;return n?a.createElement(h,r(r({ref:t},c),{},{components:n})):a.createElement(h,r({ref:t},c))}));function p(e,t){var n=arguments,i=t&&t.mdxType;if("string"==typeof e||i){var o=n.length,r=new Array(o);r[0]=u;var s={};for(var l in t)hasOwnProperty.call(t,l)&&(s[l]=t[l]);s.originalType=e,s.mdxType="string"==typeof e?e:i,r[1]=s;for(var d=2;d ${patch_file} < fsutil behavior query DisableDeleteNotify\\nNTFS DisableDeleteNotify = 0 (Allows TRIM operations to be sent to the storage device)\\nReFS DisableDeleteNotify = 0 (Allows TRIM operations to be sent to the storage device)\\n```\\n\\n`DisableDeleteNotify = 0` indicates that TRIM operations are enabled. For more information, see [fsutil behavior](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-behavior) in the Microsoft documentation.\\n\\n## Risk Mitigation\\n\\n### Linux\\n\\nOne way to mitigate the described risks is to disable fstrim services in VMs. fstrim services is enabled by default in many modern Linux distributions.\\nYou can determine if fstrim is enabled in VMs that use affected Longhorn volumes by checking the following:\\n\\n - `/etc/fstab`: Some root filesystems mount with the *discard* option.\\n\\n Example:\\n ```\\n /dev/mapper/rootvg-rootlv / xfs defaults,discard 0 0\\n ```\\n \\n You can disable fstrim on the root filesystem by removing the *discard* option.\\n ```\\n /dev/mapper/rootvg-rootlv / xfs defaults 0 0 <-- remove the discard option\\n ```\\n \\n After removing the *discard* option, you can remount the root filesystem using the command `mount -o remount /` or by rebooting the VM.\\n\\n - `fstrim.timer`: When this service is enabled, fstrim executes weekly by default. You can either disable the service or edit the service file to prevent simultaneous fstrim execution on VMs.\\n\\n You can disable the service using the following command:\\n ```\\n systemctl disable fstrim.timer\\n ```\\n\\n To prevent simultaneous fstrim execution, use the following values in the service file (located at `/usr/lib/systemd/system/fstrim.timer`):\\n ```\\n [Timer]\\n OnCalendar=weekly\\n AccuracySec=1h\\n Persistent=true\\n RandomizedDelaySec=6000\\n ```\\n\\n### Windows\\n\\nTo mitigate the described risks, you can disable TRIM operations using the following commands:\\n\\n- ReFS v2\\n ```\\n C:\\\\> fsutil behavior set DisableDeleteNotify ReFS 1\\n ```\\n\\n- NTFS and ReFS v1\\n ```\\n C:\\\\> fsutil behavior set DisableDeleteNotify 1\\n ```"},{"id":"calculation_of_resource_metrics_in_harvester","metadata":{"permalink":"/kb/calculation_of_resource_metrics_in_harvester","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2024-01-23/harvester_resource_metrics_calculation.md","source":"@site/kb/2024-01-23/harvester_resource_metrics_calculation.md","title":"Calculation of Resource Metrics in Harvester","description":"Understand how resource metrics are calculated.","date":"2024-01-23T00:00:00.000Z","formattedDate":"January 23, 2024","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"resource metrics","permalink":"/kb/tags/resource-metrics"},{"label":"reserved resource","permalink":"/kb/tags/reserved-resource"},{"label":"calculation","permalink":"/kb/tags/calculation"}],"readingTime":2.835,"truncated":false,"authors":[{"name":"Jian Wang","title":"Staff Software Engineer","url":"https://github.com/w13915984028","image_url":"https://github.com/w13915984028.png","imageURL":"https://github.com/w13915984028.png"}],"frontMatter":{"title":"Calculation of Resource Metrics in Harvester","description":"Understand how resource metrics are calculated.","slug":"calculation_of_resource_metrics_in_harvester","authors":[{"name":"Jian Wang","title":"Staff Software Engineer","url":"https://github.com/w13915984028","image_url":"https://github.com/w13915984028.png","imageURL":"https://github.com/w13915984028.png"}],"tags":["harvester","resource metrics","reserved resource","calculation"],"hide_table_of_contents":false},"prevItem":{"title":"Mitigating filesystem trim Risk","permalink":"/kb/the_potential_risk_with_filesystem_trim"},"nextItem":{"title":"Best Practices for Optimizing Longhorn Disk Performance","permalink":"/kb/best_practices_for_optimizing_longhorn_disk_performance"}},"content":"Harvester calculates the resource metrics using data that is dynamically collected from the system. Host-level resource metrics are calculated and then aggregated to obtain the cluster-level metrics.\\n\\nYou can view resource-related metrics on the Harvester UI.\\n\\n- **Hosts** screen: Displays host-level metrics\\n\\n ![host level resources metrics](./imgs/host-resource-usage.png)\\n\\n- **Dashboard** screen: Displays cluster-level metrics\\n\\n ![cluster level resources metrics](./imgs/cluster-resource-usage.png)\\n\\n## CPU and Memory\\n\\nThe following sections describe the data sources and calculation methods for CPU and memory resources.\\n\\n- Resource capacity: Baseline data\\n- Resource usage: Data source for the **Used** field on the **Hosts** screen\\n- Resource reservation: Data source for the **Reserved** field on the **Hosts** screen\\n\\n### Resource Capacity \\n\\nIn Kubernetes, a `Node` object is created for each host.\\n\\nThe `.status.allocatable.cpu` and `.status.allocatable.memory` represent the available CPU and Memory resources of a host.\\n\\n```\\n# kubectl get nodes -A -oyaml\\napiVersion: v1\\nitems:\\n- apiVersion: v1\\n kind: Node\\n metadata:\\n..\\n management.cattle.io/pod-limits: \'{\\"cpu\\":\\"12715m\\",\\"devices.kubevirt.io/kvm\\":\\"1\\",\\"devices.kubevirt.io/tun\\":\\"1\\",\\"devices.kubevirt.io/vhost-net\\":\\"1\\",\\"memory\\":\\"17104951040\\"}\'\\n management.cattle.io/pod-requests: \'{\\"cpu\\":\\"5657m\\",\\"devices.kubevirt.io/kvm\\":\\"1\\",\\"devices.kubevirt.io/tun\\":\\"1\\",\\"devices.kubevirt.io/vhost-net\\":\\"1\\",\\"ephemeral-storage\\":\\"50M\\",\\"memory\\":\\"9155862208\\",\\"pods\\":\\"78\\"}\'\\n node.alpha.kubernetes.io/ttl: \\"0\\"\\n..\\n name: harv41\\n resourceVersion: \\"2170215\\"\\n uid: b6f5850a-2fbc-4aef-8fbe-121dfb671b67\\n spec:\\n podCIDR: 10.52.0.0/24\\n podCIDRs:\\n - 10.52.0.0/24\\n providerID: rke2://harv41\\n status:\\n addresses:\\n - address: 192.168.122.141\\n type: InternalIP\\n - address: harv41\\n type: Hostname\\n allocatable:\\n cpu: \\"10\\"\\n devices.kubevirt.io/kvm: 1k\\n devices.kubevirt.io/tun: 1k\\n devices.kubevirt.io/vhost-net: 1k\\n ephemeral-storage: \\"149527126718\\"\\n hugepages-1Gi: \\"0\\"\\n hugepages-2Mi: \\"0\\"\\n memory: 20464216Ki\\n pods: \\"200\\"\\n capacity:\\n cpu: \\"10\\"\\n devices.kubevirt.io/kvm: 1k\\n devices.kubevirt.io/tun: 1k\\n devices.kubevirt.io/vhost-net: 1k\\n ephemeral-storage: 153707984Ki\\n hugepages-1Gi: \\"0\\"\\n hugepages-2Mi: \\"0\\"\\n memory: 20464216Ki\\n pods: \\"200\\"\\n```\\n\\n### Resource Usage\\n\\nCPU and memory usage data is continuously collected and stored in the `NodeMetrics` object. Harvester reads the data from `usage.cpu` and `usage.memory`.\\n\\n```\\n# kubectl get NodeMetrics -A -oyaml\\napiVersion: v1\\nitems:\\n- apiVersion: metrics.k8s.io/v1beta1\\n kind: NodeMetrics\\n metadata:\\n...\\n name: harv41\\n timestamp: \\"2024-01-23T12:04:44Z\\"\\n usage:\\n cpu: 891736742n\\n memory: 9845008Ki\\n window: 10.149s\\n```\\n\\n### Resource Reservation\\n\\nHarvester dynamically calculates the resource limits and requests of all pods running on a host, and updates the information to the annotations of the `NodeMetrics` object.\\n\\n```\\n management.cattle.io/pod-limits: \'{\\"cpu\\":\\"12715m\\",...,\\"memory\\":\\"17104951040\\"}\'\\n management.cattle.io/pod-requests: \'{\\"cpu\\":\\"5657m\\",...,\\"memory\\":\\"9155862208\\"}\'\\n```\\n\\nFor more information, see [Requests and Limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits) in the Kubernetes documentation.\\n\\n## Storage\\n\\nLonghorn is the default Container Storage Interface (CSI) driver of Harvester, providing storage management features such as distributed block storage and tiering.\\n\\n### Reserved Storage in Longhorn\\n\\nLonghorn allows you to specify the percentage of disk space that is not allocated to the default disk on each new Longhorn node. The default value is \\"30\\". For more information, see [Storage Reserved Percentage For Default Disk](https://longhorn.io/docs/1.5.3/references/settings/#storage-reserved-percentage-for-default-disk) in the Longhorn documentation.\\n\\nDepending on the disk size, you can modify the default value using the [embedded Longhorn UI](https://docs.harvesterhci.io/v1.2/troubleshooting/harvester/#access-embedded-rancher-and-longhorn-dashboards).\\n\\n:::note\\n\\nBefore changing the settings, read the Longhorn documentation carefully.\\n\\n:::\\n\\n### Data Sources and Calculation\\n\\nHarvester uses the following data to calculate metrics for storage resources.\\n\\n- Sum of the `storageMaximum` values of all disks (`status.diskStatus.disk-name`): Total storage capacity\\n\\n- Total storage capacity - Sum of the `storageAvailable` values of all disks (`status.diskStatus.disk-name`): Data source for the **Used** field on the **Hosts** screen\\n\\n- Sum of the `storageReserved` values of all disks (`spec.disks`): Data source for the **Reserved** field on the **Hosts** screen\\n\\n```\\n# kubectl get nodes.longhorn.io -n longhorn-system -oyaml\\n\\napiVersion: v1\\nitems:\\n- apiVersion: longhorn.io/v1beta2\\n kind: Node\\n metadata:\\n..\\n name: harv41\\n namespace: longhorn-system\\n..\\n spec:\\n allowScheduling: true\\n disks:\\n default-disk-ef11a18c36b01132:\\n allowScheduling: true\\n diskType: filesystem\\n evictionRequested: false\\n path: /var/lib/harvester/defaultdisk\\n storageReserved: 24220101427\\n tags: []\\n..\\n status:\\n..\\n diskStatus:\\n default-disk-ef11a18c36b01132:\\n..\\n diskType: filesystem\\n diskUUID: d2788933-8817-44c6-b688-dee414cc1f73\\n scheduledReplica:\\n pvc-95561210-c39c-4c2e-ac9a-4a9bd72b3100-r-20affeca: 2147483648\\n pvc-9e83b2dc-6a4b-4499-ba70-70dc25b2d9aa-r-4ad05c86: 32212254720\\n pvc-bc25be1e-ca4e-4818-a16d-48353a0f2f96-r-c7b88c60: 3221225472\\n pvc-d9d3e54d-8d67-4740-861e-6373f670f1e4-r-f4c7c338: 2147483648\\n pvc-e954b5fe-bbd7-4d44-9866-6ff6684d5708-r-ba6b87b6: 5368709120\\n storageAvailable: 77699481600\\n storageMaximum: 80733671424\\n storageScheduled: 45097156608\\n region: \\"\\"\\n snapshotCheckStatus: {}\\n zone: \\"\\"\\n```"},{"id":"best_practices_for_optimizing_longhorn_disk_performance","metadata":{"permalink":"/kb/best_practices_for_optimizing_longhorn_disk_performance","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-12-27/best_practices_disk_performance.md","source":"@site/kb/2023-12-27/best_practices_disk_performance.md","title":"Best Practices for Optimizing Longhorn Disk Performance","description":"Follow the recommendations for achieving optimal disk performance.","date":"2023-12-27T00:00:00.000Z","formattedDate":"December 27, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"longhorn","permalink":"/kb/tags/longhorn"},{"label":"best practices","permalink":"/kb/tags/best-practices"},{"label":"disk performance","permalink":"/kb/tags/disk-performance"}],"readingTime":1.585,"truncated":false,"authors":[{"name":"David Ko","title":"Senior Software Engineering Manager","url":"https://github.com/innobead","image_url":"https://github.com/innobead.png","imageURL":"https://github.com/innobead.png"},{"name":"Jillian Maroket","title":"Technical Writer","url":"https://github.com/jillian-maroket/","image_url":"https://github.com/jillian-maroket.png","imageURL":"https://github.com/jillian-maroket.png"}],"frontMatter":{"title":"Best Practices for Optimizing Longhorn Disk Performance","description":"Follow the recommendations for achieving optimal disk performance.","slug":"best_practices_for_optimizing_longhorn_disk_performance","authors":[{"name":"David Ko","title":"Senior Software Engineering Manager","url":"https://github.com/innobead","image_url":"https://github.com/innobead.png","imageURL":"https://github.com/innobead.png"},{"name":"Jillian Maroket","title":"Technical Writer","url":"https://github.com/jillian-maroket/","image_url":"https://github.com/jillian-maroket.png","imageURL":"https://github.com/jillian-maroket.png"}],"tags":["harvester","longhorn","best practices","disk performance"],"hide_table_of_contents":false},"prevItem":{"title":"Calculation of Resource Metrics in Harvester","permalink":"/kb/calculation_of_resource_metrics_in_harvester"},"nextItem":{"title":"VM Live Migration Policy and Configuration","permalink":"/kb/vm_live_migration_policy_and_configuration"}},"content":"The Longhorn documentation provides [best practice recommendations](https://longhorn.io/docs/1.5.3/best-practices/) for deploying Longhorn in production environments. Before configuring workloads, ensure that you have set up the following basic requirements for optimal disk performance.\\n\\n- SATA/NVMe SSDs or disk drives with similar performance\\n- 10 Gbps network bandwidth between nodes\\n- Dedicated Priority Classes for system-managed and user-deployed Longhorn components\\n\\nThe following sections outline other recommendations for achieving optimal disk performance.\\n\\n## IO Performance\\n\\n- **Storage network**: Use a [dedicated storage network](https://docs.harvesterhci.io/v1.2/advanced/storagenetwork) to improve IO performance and stability. \\n\\n- **Longhorn disk**: Use a [dedicated disk](https://docs.harvesterhci.io/v1.2/host/#multi-disk-management) for Longhorn storage instead of using the root disk. \\n\\n- **Replica count**: Set the [default replica count](https://docs.harvesterhci.io/v1.2/advanced/storageclass#parameters-tab) to \\"2\\" to achieve data availability with better disk space usage or less impact to system performance. This practice is especially beneficial to data-intensive applications. \\n\\n- **Storage tag**: Use storage tags to define storage tiering for data-intensive applications. For example, only high-performance disks can be used for storing performance-sensitive data. You can either [add disks with tags](https://docs.harvesterhci.io/v1.2/host/#storage-tags) or [create StorageClasses with tags](https://docs.harvesterhci.io/v1.2/advanced/storageclass#disk-selector-optional). \\n\\n- **Data locality**: Use `best-effort` as the default [data locality](https://longhorn.io/docs/1.5.3/high-availability/data-locality/) of Longhorn Storage Classes. \\n\\n For applications that support data replication (for example, a distributed database), you can use the `strict-local` option to ensure that only one replica is created for each volume. This practice prevents the extra disk space usage and IO performance overhead associated with volume replication. \\n\\n For data-intensive applications, you can use pod scheduling functions such as node selector or taint toleration. These functions allow you to schedule the workload to a specific storage-tagged node together with one replica. \\n\\n## Space Efficiency \\n\\n- **Recurring snapshots**: Periodically clean up system-generated snapshots and retain only the number of snapshots that makes sense for your implementation. \\n\\n For applications with replication capability, periodically [delete all types of snapshots](https://longhorn.io/docs/1.5.3/concepts/#243-deleting-snapshots).\\n\\n## Disaster Recovery\\n\\n- **Recurring backups**: Create [recurring backup jobs](https://longhorn.io/docs/1.5.3/volumes-and-nodes/trim-filesystem/) for mission-critical application volumes.\\n\\n- **System backup**: Run periodic system backups."},{"id":"vm_live_migration_policy_and_configuration","metadata":{"permalink":"/kb/vm_live_migration_policy_and_configuration","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-09-01/vm_live_migration_policy_and_configuration.md","source":"@site/kb/2023-09-01/vm_live_migration_policy_and_configuration.md","title":"VM Live Migration Policy and Configuration","description":"Know how VM live migration works, the migration policies, how to tune the policies and check status","date":"2023-09-01T00:00:00.000Z","formattedDate":"September 1, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"virtual machine","permalink":"/kb/tags/virtual-machine"},{"label":"VM","permalink":"/kb/tags/vm"},{"label":"live migration","permalink":"/kb/tags/live-migration"},{"label":"policy","permalink":"/kb/tags/policy"},{"label":"strategy","permalink":"/kb/tags/strategy"},{"label":"configuration","permalink":"/kb/tags/configuration"}],"readingTime":10.58,"truncated":false,"authors":[{"name":"Jian Wang","title":"Staff Software Engineer","url":"https://github.com/w13915984028","image_url":"https://github.com/w13915984028.png","imageURL":"https://github.com/w13915984028.png"}],"frontMatter":{"title":"VM Live Migration Policy and Configuration","description":"Know how VM live migration works, the migration policies, how to tune the policies and check status","slug":"vm_live_migration_policy_and_configuration","authors":[{"name":"Jian Wang","title":"Staff Software Engineer","url":"https://github.com/w13915984028","image_url":"https://github.com/w13915984028.png","imageURL":"https://github.com/w13915984028.png"}],"tags":["harvester","virtual machine","VM","live migration","policy","strategy","configuration"],"hide_table_of_contents":false},"prevItem":{"title":"Best Practices for Optimizing Longhorn Disk Performance","permalink":"/kb/best_practices_for_optimizing_longhorn_disk_performance"},"nextItem":{"title":"Use Rook Ceph External Storage with Harvester","permalink":"/kb/use_rook_ceph_external_storage"}},"content":"In Harvester, the **VM Live Migration** is well supported by the UI. Please refer to [Harvester VM Live Migration](https://docs.harvesterhci.io/v1.1/vm/live-migration) for more details.\\n\\nThe VM Live Migration process is finished smoothly in most cases. However, sometimes the migration may get stuck and not end as expected.\\n\\nThis article dives into the VM Live Migration process in more detail. There are three main parts:\\n\\n- General Process of VM Live Migration\\n- VM Live Migration Strategies\\n- VM Live Migration Configurations\\n\\nRelated issues:\\n\\n- [Migration should show the proper status and progress in the UI](https://github.com/harvester/harvester/issues/4352)\\n- [VM Migration policy and status](https://github.com/harvester/harvester/issues/4376)\\n\\n:::note\\n\\nA big part of the following contents are copied from `kubevirt` document https://kubevirt.io/user-guide/operations/live_migration/, some contents/formats are adjusted to fit in this document.\\n\\n:::\\n\\n## General Process of VM Live Migration\\n\\n### Starting a Migration from Harvester UI\\n\\n1. Go to the **Virtual Machines** page.\\n1. Find the virtual machine that you want to migrate and select **\u22ee** > **Migrate**.\\n1. Choose the node to which you want to migrate the virtual machine and select **Apply**.\\n\\nAfter successfully selecting **Apply**, a CRD `VirtualMachineInstanceMigration` object is created, and the related `controller/operator` will start the process.\\n\\n### Migration CRD Object\\n\\nYou can also create the CRD `VirtualMachineInstanceMigration` object manually via `kubectl` or other tools.\\n\\nThe example below starts a migration process for a virtual machine instance (VMI) `new-vm`.\\n\\n```\\napiVersion: kubevirt.io/v1\\nkind: VirtualMachineInstanceMigration\\nmetadata:\\n name: migration-job\\nspec:\\n vmiName: new-vm\\n```\\n\\nUnder the hood, the open source projects `Kubevirt, Libvirt, QEMU, ... ` perform most of the `VM Live Migration`. [References.](#references)\\n\\n### Migration Status Reporting\\n\\nWhen starting a virtual machine instance (VMI), it has also been calculated whether the machine is live migratable. The result is being stored in the VMI `VMI.status.conditions`. The calculation can be based on multiple parameters of the VMI, however, at the moment, the calculation is largely based on the Access Mode of the VMI volumes. Live migration is only permitted when the volume access mode is set to ReadWriteMany. Requests to migrate a non-LiveMigratable VMI will be rejected.\\n\\nThe reported Migration Method is also being calculated during VMI start. `BlockMigration` indicates that some of the VMI disks require copying from the source to the destination. `LiveMigration` means that only the instance memory will be copied.\\n\\n```\\nStatus:\\n Conditions:\\n Status: True\\n Type: LiveMigratable\\n Migration Method: BlockMigration\\n```\\n\\n### Migration Status\\n\\nThe migration progress status is reported in `VMI.status`. Most importantly, it indicates whether the migration has been completed or failed.\\n\\nBelow is an example of a successful migration.\\n\\n```\\nMigration State:\\n Completed: true\\n End Timestamp: 2019-03-29T03:37:52Z\\n Migration Config:\\n Completion Timeout Per GiB: 800\\n Progress Timeout: 150\\n Migration UID: c64d4898-51d3-11e9-b370-525500d15501\\n Source Node: node02\\n Start Timestamp: 2019-03-29T04:02:47Z\\n Target Direct Migration Node Ports:\\n 35001: 0\\n 41068: 49152\\n 38284: 49153\\n Target Node: node01\\n Target Node Address: 10.128.0.46\\n Target Node Domain Detected: true\\n Target Pod: virt-launcher-testvmimcbjgw6zrzcmp8wpddvztvzm7x2k6cjbdgktwv8tkq\\n```\\n\\n## VM Live Migration Strategies\\n\\nVM Live Migration is a process during which a running Virtual Machine Instance moves to another compute node while the guest workload continues to run and remain accessible.\\n\\n### Understanding Different VM Live Migration Strategies\\n\\nVM Live Migration is a complex process. During a migration, the source VM needs to transfer its whole state (mainly RAM) to the target VM. If there are enough resources available, such as network bandwidth and CPU power, migrations should converge nicely. If this is not the scenario, however, the migration might get stuck without an ability to progress.\\n\\nThe main factor that affects migrations from the guest perspective is its dirty rate, which is the rate by which the VM dirties memory. Guests with high dirty rate lead to a race during migration. On the one hand, memory would be transferred continuously to the target, and on the other, the same memory would get dirty by the guest. On such scenarios, one could consider to use more advanced migration strategies. Refer to [Understanding different migration strategies](https://kubevirt.io/user-guide/operations/live_migration/#understanding-different-migration-strategies) for more details.\\n\\nThere are 3 `VM Live Migration` strategies/policies:\\n\\n#### VM Live Migration Strategy: Pre-copy\\n\\nPre-copy is the default strategy. It should be used for most cases.\\n\\nThe way it works is as following:\\n1. The target VM is created, but the guest keeps running on the source VM.\\n1. The source starts sending chunks of VM state (mostly memory) to the target. This continues until all of the state has been transferred to the target.\\n1. The guest starts executing on the target VM. 4. The source VM is being removed.\\n\\nPre-copy is the safest and fastest strategy for most cases. Furthermore, it can be easily cancelled, can utilize multithreading, and more. If there is no real reason to use another strategy, this is definitely the strategy to go with.\\n\\nHowever, on some cases migrations might not converge easily, that is, by the time the chunk of source VM state would be received by the target VM, it would already be mutated by the source VM (which is the VM the guest executes on). There are many reasons for migrations to fail converging, such as a high dirty-rate or low resources like network bandwidth and CPU. On such scenarios, see the following alternative strategies below.\\n\\n#### VM Live Migration Strategy: Post-copy\\n\\nThe way post-copy migrations work is as following:\\n1. The target VM is created.\\n1. The guest is being run on the target VM.\\n1. The source starts sending chunks of VM state (mostly memory) to the target.\\n1. When the guest, running on the target VM, would access memory: 1. If the memory exists on the target VM, the guest can access it. 2. Otherwise, the target VM asks for a chunk of memory from the source VM.\\n1. Once all of the memory state is updated at the target VM, the source VM is being removed.\\n\\nThe main idea here is that the guest starts to run immediately on the target VM. This approach has advantages and disadvantages:\\n\\n**Advantages:**\\n\\n- The same memory chink is never being transferred twice. This is possible due to the fact that with post-copy it doesn\'t matter that a page had been dirtied since the guest is already running on the target VM.\\n- This means that a high dirty-rate has much less effect.\\n- Consumes less network bandwidth.\\n\\n**Disadvantages:**\\n\\n- When using post-copy, the VM state has no one source of truth. When the guest (running on the target VM) writes to memory, this memory is one part of the guest\'s state, but some other parts of it may still be updated only at the source VM. This situation is generally dangerous, since, for example, if either the target or guest VMs crash the state cannot be recovered.\\n- Slow warmup: when the guest starts executing, no memory is present at the target VM. Therefore, the guest would have to wait for a lot of memory in a short period of time.\\n- Slower than pre-copy on most cases.\\n- Harder to cancel a migration.\\n\\n#### VM Live Migration Strategy: Auto-converge\\n\\nAuto-converge is a technique to help pre-copy migrations converge faster without changing the core algorithm of how the migration works.\\n\\nSince a high dirty-rate is usually the most significant factor for migrations to not converge, auto-converge simply throttles the guest\'s CPU. If the migration would converge fast enough, the guest\'s CPU would not be throttled or throttled negligibly. But, if the migration would not converge fast enough, the CPU would be throttled more and more as time goes.\\n\\nThis technique dramatically increases the probability of the migration converging eventually.\\n\\n### Observe the VM Live Migration Progress and Result\\n\\n#### Migration Timeouts\\n\\nDepending on the type, the live migration process will copy virtual machine memory pages and disk blocks to the destination. During this process non-locked pages and blocks are being copied and become free for the instance to use again. To achieve a successful migration, it is assumed that the instance will write to the free pages and blocks (pollute the pages) at a lower rate than these are being copied.\\n\\n#### Completion Time\\n\\nIn some cases the virtual machine can write to different memory pages / disk blocks at a higher rate than these can be copied, which will prevent the migration process from completing in a reasonable amount of time. In this case, live migration will be aborted if it is running for a long period of time. The timeout is calculated base on the size of the VMI, it\'s memory and the ephemeral disks that are needed to be copied. The configurable parameter completionTimeoutPerGiB, which defaults to 800s is the time for GiB of data to wait for the migration to be completed before aborting it. A VMI with 8Gib of memory will time out after 6400 seconds.\\n\\n#### Progress Timeout\\n\\nA VM Live Migration will also be aborted when it notices that copying memory doesn\'t make any progress. The time to wait for live migration to make progress in transferring data is configurable by the `progressTimeout` parameter, which defaults to 150 seconds.\\n\\n## VM Live Migration Configurations\\n\\n### Changing Cluster Wide Migration Limits\\n\\nKubeVirt puts some limits in place so that migrations don\'t overwhelm the cluster. By default, it is to only run 5 migrations in parallel with an additional limit of a maximum of 2 outbound migrations per node. Finally, every migration is limited to a bandwidth of 64MiB/s.\\n\\nYou can change these values in the `kubevirt` CR:\\n```\\n apiVersion: kubevirt.io/v1\\n kind: Kubevirt\\n metadata:\\n name: kubevirt\\n namespace: kubevirt\\n spec:\\n configuration:\\n migrations:\\n parallelMigrationsPerCluster: 5\\n parallelOutboundMigrationsPerNode: 2\\n bandwidthPerMigration: 64Mi\\n completionTimeoutPerGiB: 800\\n progressTimeout: 150\\n disableTLS: false\\n nodeDrainTaintKey: \\"kubevirt.io/drain\\"\\n allowAutoConverge: false ---------------------\x3e related to: Auto-converge\\n allowPostCopy: false -------------------------\x3e related to: Post-copy\\n unsafeMigrationOverride: false\\n```\\n\\nRemember that most of these configurations can be overridden and fine-tuned to a specified group of VMs. For more information, please refer to the Migration Policies section below.\\n\\n### Migration Policies\\n\\n[Migration policies](https://kubevirt.io/user-guide/operations/migration_policies/) provides a new way of applying migration configurations to Virtual Machines. The policies can refine Kubevirt CR\'s `MigrationConfiguration` that sets the cluster-wide migration configurations. This way, the cluster-wide settings default how the migration policy can be refined (i.e., changed, removed, or added).\\n\\nRemember that migration policies are in version `v1alpha1`. This means that this API is not fully stable yet and that APIs may change in the future.\\n\\n#### Migration Configurations\\n\\nCurrently, the `MigrationPolicy` spec only includes the following configurations from Kubevirt CR\'s `MigrationConfiguration`. (In the future, more configurations that aren\'t part of Kubevirt CR will be added):\\n\\n```\\napiVersion: migrations.kubevirt.io/v1alpha1\\nkind: MigrationPolicy\\n spec:\\n allowAutoConverge: true\\n bandwidthPerMigration: 217Ki\\n completionTimeoutPerGiB: 23\\n allowPostCopy: false\\n```\\n\\nAll the above fields are optional. When omitted, the configuration will be applied as defined in KubevirtCR\'s `MigrationConfiguration`. This way, KubevirtCR will serve as a configurable set of defaults for both VMs that are not bound to any `MigrationPolicy` and VMs that are bound to a `MigrationPolicy` that does not define all fields of the configurations.\\n\\n##### Matching Policies to VMs\\n\\nNext in the spec are the selectors defining the group of VMs to apply the policy. The options to do so are the following.\\n\\nThis policy applies to the VMs in namespaces that have all the required labels:\\n\\n```\\napiVersion: migrations.kubevirt.io/v1alpha1\\nkind: MigrationPolicy\\n spec:\\n selectors:\\n namespaceSelector:\\n hpc-workloads: true # Matches a key and a value\\n```\\n\\nThe policy below applies to the VMs that have all the required labels:\\n\\n```\\napiVersion: migrations.kubevirt.io/v1alpha1\\nkind: MigrationPolicy\\n spec:\\n selectors:\\n virtualMachineInstanceSelector:\\n workload-type: db # Matches a key and a value\\n```\\n\\n## References\\n\\n### Documents\\n\\n### Libvirt Guest Migration\\n\\n`Libvirt` has a chapter to describe the pricipal of `VM/Guest Live Migration`.\\n\\nhttps://libvirt.org/migration.html\\n\\n### Kubevirt Live Migration\\n\\nhttps://kubevirt.io/user-guide/operations/live_migration/\\n\\n### Source Code\\n\\nThe `VM Live Migration` related configuration options are passed to each layer correspondingly.\\n\\n#### Kubevirt\\n\\nhttps://github.com/kubevirt/kubevirt/blob/d425593ae392111dab80403ef0cde82625e37653/pkg/virt-launcher/virtwrap/live-migration-source.go#L103\\n\\n```\\n...\\nimport \\"libvirt.org/go/libvirt\\"\\n\\n...\\n\\nfunc generateMigrationFlags(isBlockMigration, migratePaused bool, options *cmdclient.MigrationOptions) libvirt.DomainMigrateFlags {\\n...\\n\\tif options.AllowAutoConverge {\\n\\t\\tmigrateFlags |= libvirt.MIGRATE_AUTO_CONVERGE\\n\\t}\\n\\tif options.AllowPostCopy {\\n\\t\\tmigrateFlags |= libvirt.MIGRATE_POSTCOPY\\n\\t}\\n...\\n}\\n```\\n\\n#### Go Package Libvirt\\n\\nhttps://pkg.go.dev/libvirt.org/go/libvirt\\n\\n```\\nconst (\\n...\\n\\tMIGRATE_AUTO_CONVERGE = DomainMigrateFlags(C.VIR_MIGRATE_AUTO_CONVERGE)\\n\\tMIGRATE_RDMA_PIN_ALL = DomainMigrateFlags(C.VIR_MIGRATE_RDMA_PIN_ALL)\\n\\tMIGRATE_POSTCOPY = DomainMigrateFlags(C.VIR_MIGRATE_POSTCOPY)\\n...\\n)\\n```\\n\\n#### Libvirt\\n\\nhttps://github.com/libvirt/libvirt/blob/bfe53e9145cd5996a791c5caff0686572b850f82/include/libvirt/libvirt-domain.h#L1030\\n\\n```\\n /* Enable algorithms that ensure a live migration will eventually converge.\\n * This usually means the domain will be slowed down to make sure it does\\n * not change its memory faster than a hypervisor can transfer the changed\\n * memory to the destination host. VIR_MIGRATE_PARAM_AUTO_CONVERGE_*\\n * parameters can be used to tune the algorithm.\\n *\\n * Since: 1.2.3\\n */\\n VIR_MIGRATE_AUTO_CONVERGE = (1 << 13),\\n...\\n /* Setting the VIR_MIGRATE_POSTCOPY flag tells libvirt to enable post-copy\\n * migration. However, the migration will start normally and\\n * virDomainMigrateStartPostCopy needs to be called to switch it into the\\n * post-copy mode. See virDomainMigrateStartPostCopy for more details.\\n *\\n * Since: 1.3.3\\n */\\n VIR_MIGRATE_POSTCOPY = (1 << 15),\\n```"},{"id":"use_rook_ceph_external_storage","metadata":{"permalink":"/kb/use_rook_ceph_external_storage","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-08-23/using_rook_ceph_storage.md","source":"@site/kb/2023-08-23/using_rook_ceph_storage.md","title":"Use Rook Ceph External Storage with Harvester","description":"Use Rook Ceph External Storage with Harvester","date":"2023-08-23T00:00:00.000Z","formattedDate":"August 23, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"rook","permalink":"/kb/tags/rook"},{"label":"ceph","permalink":"/kb/tags/ceph"},{"label":"csi","permalink":"/kb/tags/csi"}],"readingTime":3.86,"truncated":false,"authors":[{"name":"Hang Yu","title":"Staff Software Engineer","url":"https://github.com/futuretea","image_url":"https://github.com/futuretea.png","imageURL":"https://github.com/futuretea.png"}],"frontMatter":{"title":"Use Rook Ceph External Storage with Harvester","description":"Use Rook Ceph External Storage with Harvester","slug":"use_rook_ceph_external_storage","authors":[{"name":"Hang Yu","title":"Staff Software Engineer","url":"https://github.com/futuretea","image_url":"https://github.com/futuretea.png","imageURL":"https://github.com/futuretea.png"}],"tags":["harvester","rook","ceph","csi"],"hide_table_of_contents":false},"prevItem":{"title":"VM Live Migration Policy and Configuration","permalink":"/kb/vm_live_migration_policy_and_configuration"},"nextItem":{"title":"Upgrade Guest Kubernetes Clusters to be Compatible with Harvester IP Pools","permalink":"/kb/upgrading_guest_clusters_with_harvester_ip_pool_compatibility"}},"content":"Starting with Harvester v1.2.0, it offers the capability to install a Container Storage Interface (CSI) in your Harvester cluster. This allows you to leverage external storage for the Virtual Machine\'s non-system data disk, giving you the flexibility to use different drivers tailored for specific needs, whether it\'s for performance optimization or seamless integration with your existing in-house storage solutions.\\n\\nIt\'s important to note that, despite this enhancement, the provisioner for the Virtual Machine (VM) image in Harvester still relies on Longhorn. Prior to version 1.2.0, Harvester exclusively supported Longhorn for storing VM data and did not offer support for external storage as a destination for VM data.\\n\\nOne of the options for integrating external storage with Harvester is Rook, an open-source cloud-native storage orchestrator. Rook provides a robust platform, framework, and support for Ceph storage, enabling seamless integration with cloud-native environments.\\n\\n[Ceph](https://ceph.io) is a software-defined distributed storage system that offers versatile storage capabilities, including file, block, and object storage. It is designed for large-scale production clusters and can be deployed effectively in such environments.\\n\\n[Rook](https://rook.io) simplifies the deployment and management of Ceph, offering self-managing, self-scaling, and self-healing storage services. It leverages Kubernetes resources to automate the deployment, configuration, provisioning, scaling, upgrading, and monitoring of Ceph.\\n\\nIn this article, we will walk you through the process of installing, configuring, and utilizing [Rook](https://rook.io/docs/rook/v1.12/Getting-Started/intro/) to use storage from an [existing external Ceph cluster](https://www.rook.io/docs/rook/v1.12/CRDs/Cluster/external-cluster/) as a data disk for a VM within the Harvester environment.\\n\\n## Install Harvester Cluster\\n\\nHarvester\'s operating system follows an immutable design, meaning that most OS files revert to their pre-configured state after a reboot. To accommodate Rook Ceph\'s requirements, you need to add specific persistent paths to the `os.persistentStatePaths` section in the [Harvester configuration](https://docs.harvesterhci.io/dev/install/harvester-configuration#ospersistent_state_paths). These paths include:\\n\\n```yaml\\nos:\\n persistent_state_paths:\\n - /var/lib/rook\\n - /var/lib/ceph\\n modules:\\n - rbd\\n - nbd\\n```\\n\\nAfter the cluster is installed, refer to [How can I access the kubeconfig file of the Harvester cluster?](https://docs.harvesterhci.io/v1.1/faq#how-can-i-access-the-kubeconfig-file-of-the-harvester-cluster) to get the kubeconfig of the Harvester cluster.\\n\\n## Install Rook to Harvester\\n\\nInstall Rook to the Harvester cluster by referring to [Rook Quickstart](https://rook.io/docs/rook/v1.12/Getting-Started/quickstart/).\\n\\n```bash\\ncurl -fsSLo rook.tar.gz https://github.com/rook/rook/archive/refs/tags/v1.12.2.tar.gz \\\\\\n && tar -zxf rook.tar.gz && cd rook-1.12.2/deploy/examples\\n# apply configurations ref: https://rook.github.io/docs/rook/v1.12/Getting-Started/example-configurations/\\nkubectl apply -f crds.yaml -f common.yaml -f operator.yaml\\nkubectl -n rook-ceph wait --for=condition=Available deploy rook-ceph-operator --timeout=10m\\n```\\n\\n## Using an existing external Ceph cluster\\n\\n1. Run the python script `create-external-cluster-resources.py` in the [existing external Ceph cluster](https://www.rook.io/docs/rook/v1.12/CRDs/Cluster/external-cluster/) for creating all users and keys.\\n```bash\\n# script help ref: https://www.rook.io/docs/rook/v1.12/CRDs/Cluster/external-cluster/#1-create-all-users-and-keys\\ncurl -s https://raw.githubusercontent.com/rook/rook/v1.12.2/deploy/examples/create-external-cluster-resources.py > create-external-cluster-resources.py\\npython3 create-external-cluster-resources.py --rbd-data-pool-name --namespace rook-ceph-external --format bash\\n```\\n\\n2. Copy the Bash output.\\n\\nExample output:\\n```\\nexport NAMESPACE=rook-ceph-external\\nexport ROOK_EXTERNAL_FSID=b3b47828-4c60-11ee-be38-51902f85c805\\nexport ROOK_EXTERNAL_USERNAME=client.healthchecker\\nexport ROOK_EXTERNAL_CEPH_MON_DATA=ceph-1=192.168.5.99:6789\\nexport ROOK_EXTERNAL_USER_SECRET=AQDd6/dkFyu/IhAATv/uCMbHtWk4AYK2KXzBhQ==\\nexport ROOK_EXTERNAL_DASHBOARD_LINK=https://192.168.5.99:8443/\\nexport CSI_RBD_NODE_SECRET=AQDd6/dk2HsjIxAA06Yw9UcOg0dfwV/9IFBRhA==\\nexport CSI_RBD_NODE_SECRET_NAME=csi-rbd-node\\nexport CSI_RBD_PROVISIONER_SECRET=AQDd6/dkEY1kIxAAAzrXZnVRf4x+wDUz1zyaQg==\\nexport CSI_RBD_PROVISIONER_SECRET_NAME=csi-rbd-provisioner\\nexport MONITORING_ENDPOINT=192.168.5.99\\nexport MONITORING_ENDPOINT_PORT=9283\\nexport RBD_POOL_NAME=test\\nexport RGW_POOL_PREFIX=default\\n```\\n\\n3. Consume the external Ceph cluster resources on the Harvester cluster.\\n\\n```bash\\n# Paste the above output from create-external-cluster-resources.py into import-env.sh\\nvim import-env.sh\\nsource import-env.sh\\n# this script will create a StorageClass ceph-rbd\\nsource import-external-cluster.sh\\n```\\n\\n```bash\\nkubectl apply -f common-external.yaml\\nkubectl apply -f cluster-external.yaml\\n# wait for all pods to become Ready\\nwatch \'kubectl --namespace rook-ceph get pods\'\\n```\\n\\n4. Create the VolumeSnapshotClass `csi-rbdplugin-snapclass-external`.\\n\\n```bash\\ncat >./csi/rbd/snapshotclass-external.yaml < **Settings**.\\n1. Find and select **csi-driver-config**, and then click on the **\u22ee** > **Edit Setting** to access the configuration options.\\n1. In the settings, set the **Provisioner** to `rook-ceph.rbd.csi.ceph.com`.\\n2. Next, specify the **Volume Snapshot Class Name** as `csi-rbdplugin-snapclass-external`. This setting points to the name of the `VolumeSnapshotClass` used for creating volume snapshots or VM snapshots.\\n3. Similarly, set the **Backup Volume Snapshot Class Name** to `csi-rbdplugin-snapclass-external`. This corresponds to the name of the `VolumeSnapshotClass` responsible for creating VM backups.\\n\\n![csi-driver-config-external](./imgs/csi-driver-config-external.png)\\n\\n## Use Rook Ceph in Harvester\\n\\nAfter successfully configuring these settings, you can proceed to utilize the Rook Ceph StorageClass, which is named `rook-ceph-block` for the internal Ceph cluster or named `ceph-rbd` for the external Ceph cluster. You can apply this StorageClass when creating an empty volume or adding a new block volume to a VM, enhancing your Harvester cluster\'s storage capabilities.\\n\\nWith these configurations in place, your Harvester cluster is ready to make the most of the Rook Ceph storage integration.\\n\\n![rook-ceph-volume-external](./imgs/rook-ceph-volume-external.png)\\n\\n![rook-ceph-vm-external](./imgs/rook-ceph-vm-external.png)"},{"id":"upgrading_guest_clusters_with_harvester_ip_pool_compatibility","metadata":{"permalink":"/kb/upgrading_guest_clusters_with_harvester_ip_pool_compatibility","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-08-21/compatible_with_ip_pool_new_feature.md","source":"@site/kb/2023-08-21/compatible_with_ip_pool_new_feature.md","title":"Upgrade Guest Kubernetes Clusters to be Compatible with Harvester IP Pools","description":"Explain how to keep load balancer IP during upgrading guest cluster","date":"2023-08-21T00:00:00.000Z","formattedDate":"August 21, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"load balancer","permalink":"/kb/tags/load-balancer"},{"label":"cloud provider","permalink":"/kb/tags/cloud-provider"},{"label":"ip pool","permalink":"/kb/tags/ip-pool"},{"label":"upgrade","permalink":"/kb/tags/upgrade"}],"readingTime":2.675,"truncated":false,"authors":[{"name":"Canwu Yao","title":"Software Engineer","url":"https://github.com/yaocw2020","image_url":"https://avatars.githubusercontent.com/u/7421463?s=400&v=4","imageURL":"https://avatars.githubusercontent.com/u/7421463?s=400&v=4"}],"frontMatter":{"title":"Upgrade Guest Kubernetes Clusters to be Compatible with Harvester IP Pools","description":"Explain how to keep load balancer IP during upgrading guest cluster","slug":"upgrading_guest_clusters_with_harvester_ip_pool_compatibility","authors":[{"name":"Canwu Yao","title":"Software Engineer","url":"https://github.com/yaocw2020","image_url":"https://avatars.githubusercontent.com/u/7421463?s=400&v=4","imageURL":"https://avatars.githubusercontent.com/u/7421463?s=400&v=4"}],"tags":["harvester","load balancer","cloud provider","ip pool","upgrade"],"hide_table_of_contents":false},"prevItem":{"title":"Use Rook Ceph External Storage with Harvester","permalink":"/kb/use_rook_ceph_external_storage"},"nextItem":{"title":"Using NetApp Storage on Harvester","permalink":"/kb/install_netapp_trident_csi"}},"content":"As **Harvester v1.2.0** is released, a new Harvester cloud provider version **0.2.2** is integrated into RKE2 **v1.24.15+rke2r1**, **v1.25.11+rke2r1**, **v1.26.6+rke2r1**, **v1.27.3+rke2r1**, and newer versions.\\n\\nWith Harvester v1.2.0, the new Harvester cloud provider offers enhanced load balancing capabilities for guest Kubernetes services. Specifically, it introduces the Harvester IP Pool feature, a built-in IP address management (IPAM) solution for the Harvester load balancer. It allows you to define an IP pool specific to a particular guest cluster by specifying the guest cluster name. For example, you can create an IP pool exclusively for the guest cluster named cluster2:\\n\\n![image](ippoolforcluster2.png)\\n\\nHowever, after upgrading, the feature is not automatically compatible with existing guest Kubernetes clusters, as they do not pass the correct cluster name to the Harvester cloud provider. Refer to [issue 4232](https://github.com/harvester/harvester/issues/4232) for more details. Users can manually upgrade the Harvester cloud provider using Helm as a workaround and provide the correct cluster name after upgrading. However, this would result in a change in the load balancer IPs. \\n\\nThis article outlines a workaround that allows you to leverage the new IP pool feature while keeping the load balancer IPs unchanged.\\n\\n## Prerequisites\\n\\n- Download the Harvester kubeconfig file from the Harvester UI. If you have imported Harvester into Rancher, do not use the kubeconfig file from the Rancher UI. Refer to [Access Harvester Cluster](https://docs.harvesterhci.io/v1.1/faq#how-can-i-access-the-kubeconfig-file-of-the-harvester-cluster) to get the desired one.\\n\\n- Download the kubeconfig file for the guest Kubernetes cluster you plan to upgrade. Refer to [Accessing Clusters with kubectl from Your Workstation](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/manage-clusters/access-clusters/use-kubectl-and-kubeconfig#accessing-clusters-with-kubectl-from-your-workstation) for instructions on how to download the kubeconfig file.\\n\\n## Steps to Keep Load Balancer IP\\n\\n1. Execute the following script before upgrading.\\n ```\\n curl -sfL https://raw.githubusercontent.com/harvester/harvesterhci.io/main/kb/2023-08-21/keepip.sh | sh -s before_upgrade \\n ```\\n\\n - ``: Path to the Harvester kubeconfig file.\\n - ``: Path to the kubeconfig file of your guest Kubernetes cluster.\\n - ``: Name of your guest cluster.\\n - ``: Namespace where the VMs of the guest cluster are located.\\n\\n The script will help users copy the DHCP information to the service annotation and modify the IP pool allocated history to make sure the IP is unchanged.\\n\\n ![image](before-upgrade.png)\\n\\n After executing the script, the load balancer service with DHCP mode will be annotated with the DHCP information. For example:\\n\\n ``` yaml\\n apiVersion: v1\\n kind: Service\\n metadata:\\n annotations:\\n kube-vip.io/hwaddr: 00:00:6c:4f:18:68\\n kube-vip.io/requestedIP: 172.19.105.215\\n name: lb0\\n namespace: default\\n ```\\n\\n As for the load balancer service with pool mode, the IP pool allocated history will be modified as the new load balancer name. For example:\\n\\n ``` yaml\\n apiVersion: loadbalancer.harvesterhci.io/v1beta1\\n kind: IPPool\\n metadata:\\n name: default\\n spec:\\n ...\\n status:\\n allocatedHistory:\\n 192.168.100.2: default/cluster-name-default-lb1-ddc13071 # replace the new load balancer name\\n ```\\n\\n2. Add network selector for the pool.\\n\\n For example, the following cluster is under the VM network `default/mgmt-untagged`. The network selector should be `default/mgmt-untagged`.\\n\\n ![image](network.png)\\n\\n ![image](network-selector.png)\\n\\n3. Upgrade the RKE2 cluster in the Rancher UI and select the new version.\\n \\n ![image](upgrade.png)\\n\\n1. Execute the script after upgrading.\\n ```\\n curl -sfL https://raw.githubusercontent.com/harvester/harvesterhci.io/main/kb/2023-08-21/keepip.sh | sh -s after_upgrade \\n ```\\n ![image](before-upgrade.png)\\n \\n In this step, the script wraps the operations to upgrade the Harvester cloud provider to set the cluster name. After the Harvester cloud provider is running, the new Harvester load balancers will be created with the unchanged IPs."},{"id":"install_netapp_trident_csi","metadata":{"permalink":"/kb/install_netapp_trident_csi","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-08-11/using_netapp_third_party_storage.md","source":"@site/kb/2023-08-11/using_netapp_third_party_storage.md","title":"Using NetApp Storage on Harvester","description":"Installation procedure for NetApp Astra Trident CSI Driver","date":"2023-08-11T00:00:00.000Z","formattedDate":"August 11, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"}],"readingTime":6.08,"truncated":false,"authors":[{"name":"Jeff Radick","title":"Staff Software Engineer"}],"frontMatter":{"title":"Using NetApp Storage on Harvester","description":"Installation procedure for NetApp Astra Trident CSI Driver","slug":"install_netapp_trident_csi","authors":[{"name":"Jeff Radick","title":"Staff Software Engineer"}],"tags":["harvester"],"hide_table_of_contents":false},"prevItem":{"title":"Upgrade Guest Kubernetes Clusters to be Compatible with Harvester IP Pools","permalink":"/kb/upgrading_guest_clusters_with_harvester_ip_pool_compatibility"},"nextItem":{"title":"Configure PriorityClass on Longhorn System Components","permalink":"/kb/configure_priority_class_longhorn"}},"content":"This article covers instructions for installing the Netapp Astra Trident CSI driver into a Harvester cluster, which enables NetApp storage systems to store storage volumes usable by virtual machines running in Harvester.\\n\\nThe NetApp storage will be an option in addition to the normal Longhorn storage; it will not replace Longhorn. Virtual machine images will still be stored using Longhorn.\\n\\nThis has been tested with Harvester 1.2.0 and Trident v23.07.0.\\n\\nThis procedure only works to access storage via iSCSI, not NFS.\\n\\n:::note\\n3rd party storage classes (including those based on Trident) can only be used for non-boot volumes of Harvester VMs.\\n:::\\n\\n# Detailed Instructions\\n\\nWe assume that before beginning this procedure, a Harvester cluster and a NetApp ONTAP storage system are both installed and configured for use.\\n\\nMost of these steps can be performed on any system with the `helm` and `kubectl` commands installed and network connectivity to the management port of the Harvester cluster. Let\'s call this your workstation. Certain steps must be performed on one or more cluster nodes themselves. The steps described below should be done on your workstation unless otherwise indicated.\\n\\nThe last step (enabling multipathd) should be done on all nodes after the Trident CSI has been installed.\\n\\nCertain parameters of your installation will require modification of details in the examples in the procedure given below. Those which you may wish to modify include:\\n\\n* The namespace. `trident` is used as the namespace in the examples, but you may prefer to use another.\\n* The name of the deployment. `mytrident` is used but you can change this to something else.\\n* The management IP address of the ONTAP storage system\\n* Login credentials (username and password) of the ONTAP storage system\\n\\nThe procedure is as follows.\\n\\n1. Read the NetApp Astra Trident documentation:\\n\\n * https://docs.netapp.com/us-en/trident/\\n * https://docs.netapp.com/us-en/trident/trident-get-started/kubernetes-deploy-operator.html\\n * https://docs.netapp.com/us-en/trident/trident-get-started/kubernetes-deploy-helm.html#deploy-the-trident-operator-and-install-astra-trident-using-helm\\n\\n The simplest method is to install using Helm; that process is described here.\\n\\n1. Download the KubeConfig from the Harvester cluster.\\n\\n * Open the web UI for your Harvester cluster\\n * In the lower left corner, click the \\"Support\\" link. This will take you to a \\"Harvester Support\\" page.\\n * Click the button labeled \\"Download KubeConfig\\". This will download a your cluster config in a file called \\"local.yaml\\" by default.\\n * Move this file to a convenient location and set your `KUBECONFIG` environment variable to the path of this file.\\n\\n1. Prepare the cluster for installation of the Helm chart.\\n\\n Before starting installation of the helm chart, special authorization must be provided to enable certain modifications to be made during the installation.\\n This addresses the issue described here: https://github.com/NetApp/trident/issues/839\\n\\n * Put the following text into a file. For this example we\'ll call it `authorize_trident.yaml`.\\n\\n ```yaml\\n ---\\n apiVersion: rbac.authorization.k8s.io/v1\\n kind: ClusterRole\\n metadata:\\n name: trident-operator-psa\\n rules:\\n - apiGroups:\\n - management.cattle.io\\n resources:\\n - projects\\n verbs:\\n - updatepsa\\n ---\\n apiVersion: rbac.authorization.k8s.io/v1\\n kind: ClusterRoleBinding\\n metadata:\\n name: trident-operator-psa\\n roleRef:\\n apiGroup: rbac.authorization.k8s.io\\n kind: ClusterRole\\n name: trident-operator-psa\\n subjects:\\n - kind: ServiceAccount\\n name: trident-operator\\n namespace: trident\\n ```\\n\\n * Apply this manifest via the command `kubectl apply -f authorize_trident.yaml`.\\n\\n1. Install the helm chart.\\n\\n * First you will need to add the Astra Trident Helm repository:\\n\\n ```shell\\n helm repo add netapp-trident https://netapp.github.io/trident-helm-chart\\n ```\\n\\n * Next, install the Helm chart. This example uses `mytrident` as the deployment name, `trident` as the namespace, and 23.07.0 as the version number to install:\\n\\n ```shell\\n helm install mytrident netapp-trident/trident-operator --version 23.07.0 --create-namespace --namespace trident\\n ```\\n\\n * The NetApp documentation describes variations on how you can do this.\\n\\n1. Download and extract the tridentctl command, which will be needed for the next few steps.\\n\\n This and the next few steps need to be performed logged into a master node of the Harvester cluster, using root access.\\n\\n ```shell\\n cd /tmp\\n curl -L -o trident-installer-23.07.0.tar.gz https://github.com/NetApp/trident/releases/download/v23.07.0/trident-installer-23.07.0.tar.gz\\n tar -xf trident-installer-23.07.0.tar.gz\\n cd trident-installer\\n ```\\n\\n1. Install a backend.\\n\\n This part is specific to Harvester.\\n\\n 1. Put the following into a text file, for example /tmp/backend.yaml\\n\\n ```yaml\\n version: 1\\n backendName: default_backend_san\\n storageDriverName: ontap-san-economy\\n managementLIF: 172.19.97.114\\n svm: default_backend\\n username: admin\\n password: password1234\\n labels:\\n name: default_backend_san\\n ```\\n\\n The LIF IP address, username, and password of this file\\n should be replaced with the management LIF and credentials\\n for the ONTAP system.\\n\\n 1. Create the backend\\n\\n ```shell\\n ./tridentctl create backend -f /tmp/backend.yaml -n trident\\n ```\\n\\n 1. Check that it is created\\n\\n ```shell\\n ./tridentctl get backend -n trident\\n ```\\n\\n1. Define a StorageClass and SnapshotClass.\\n\\n 1. Put the following into a file, for example `/tmp/storage.yaml`\\n\\n ```yaml\\n ---\\n apiVersion: storage.k8s.io/v1\\n kind: StorageClass\\n metadata:\\n name: ontap-san-economy\\n provisioner: csi.trident.netapp.io\\n parameters:\\n selector: \\"name=default_backend_san\\"\\n ---\\n apiVersion: snapshot.storage.k8s.io/v1\\n kind: VolumeSnapshotClass\\n metadata:\\n name: csi-snapclass\\n driver: csi.trident.netapp.io\\n deletionPolicy: Delete\\n ```\\n\\n 1. Apply the definitions:\\n\\n ```shell\\n kubectl apply -f /tmp/storage.yaml\\n ```\\n\\n1. Enable multipathd\\n\\n The following is required to enable multipathd.\\n This must be done on every node of the Harvester cluster, using root access.\\n The preceding steps should only be done once on a single node.\\n\\n 1. Create this file in `/oem/99_multipathd.yaml`:\\n\\n ```yaml\\n stages:\\n default:\\n - name: \\"Setup multipathd\\"\\n systemctl:\\n enable:\\n - multipathd\\n start:\\n - multipathd\\n ```\\n\\n 1. Configure `multipathd` to exclude pathnames used by Longhorn.\\n\\n This part is a little tricky. `multipathd` will automatically discover\\n device names matching a certain pattern, and attempt to set up multipathing on them.\\n Unfortunately, Longhorn\'s device names follow the same pattern, and\\n will not work correctly if `multipathd` tries to use those devices.\\n\\n Therefore the file `/etc/multipath.conf` must be set up on each node\\n so as to prevent `multipathd` from touching any of the devices\\n that Longhorn will use. Unfortunately, it is not possible to know\\n in advance which device names will be used until the volumes are attached\\n to a VM when the VM is started, or when the volumes are hot-added to a running VM.\\n The recommended method is to \\"whitelist\\" the Trident devices using device\\n properties rather than device naming. The properties to allow are the\\n device vendor and product. Here is an example of what you\'ll want in `/etc/multipath.conf`:\\n\\n ```text\\n blacklist {\\n device {\\n vendor \\"!NETAPP\\"\\n product \\"!LUN\\"\\n }\\n }\\n blacklist_exceptions {\\n device {\\n vendor \\"NETAPP\\"\\n product \\"LUN\\"\\n }\\n }\\n ```\\n\\n This example only works if NetApp is the only storage provider in the system for which `multipathd` must be used. More complex environments will require more complex configuration.\\n\\n Explicitly putting that content into `/etc/multipath.conf` will work when you start `multipathd` as described below, but the change in `/etc` will not persist across node reboots. To solve that problem, you should add another file to `/oem` that will re-generate `/etc/multipath.conf` when the node reboots. The following example will create the `/etc/multipath.conf` given in the example above, but may need to be modified for your environment if you have a more complex iSCSI configuration:\\n\\n ```text\\n stages:\\n initramfs:\\n - name: \\"Configure multipath blacklist and whitelist\\"\\n files:\\n - path: /etc/multipath.conf\\n permissions: 0644\\n owner: 0\\n group: 0\\n content: |\\n blacklist {\\n device {\\n vendor \\"!NETAPP\\"\\n product \\"!LUN\\"\\n }\\n }\\n blacklist_exceptions {\\n device {\\n vendor \\"NETAPP\\"\\n product \\"LUN\\"\\n }\\n }\\n ```\\n\\n Remember, this has to be done on every node.\\n\\n 1. Enable multipathd.\\n\\n Adding the above files to `/oem` will take effect on the next reboot of the node; `multipathd` can be enabled immediately without rebooting the node using the following commands:\\n\\n ```shell\\n systemctl enable multipathd\\n systemctl start multipathd\\n ```\\n\\n After the above steps, the `ontap-san-economy` storage class should be available when creating a volume for a Harvester VM."},{"id":"configure_priority_class_longhorn","metadata":{"permalink":"/kb/configure_priority_class_longhorn","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-07-25/configure_priority_class_longhorn.md","source":"@site/kb/2023-07-25/configure_priority_class_longhorn.md","title":"Configure PriorityClass on Longhorn System Components","description":"Configure priority classes on Longhorn system components","date":"2023-07-25T00:00:00.000Z","formattedDate":"July 25, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"longhorn","permalink":"/kb/tags/longhorn"},{"label":"priority class","permalink":"/kb/tags/priority-class"}],"readingTime":6.405,"truncated":false,"authors":[{"name":"Kiefer Chang","title":"Engineer Manager","url":"https://github.com/bk201","image_url":"https://github.com/bk201.png","imageURL":"https://github.com/bk201.png"}],"frontMatter":{"title":"Configure PriorityClass on Longhorn System Components","description":"Configure priority classes on Longhorn system components","slug":"configure_priority_class_longhorn","authors":[{"name":"Kiefer Chang","title":"Engineer Manager","url":"https://github.com/bk201","image_url":"https://github.com/bk201.png","imageURL":"https://github.com/bk201.png"}],"tags":["harvester","longhorn","priority class"],"hide_table_of_contents":false},"prevItem":{"title":"Using NetApp Storage on Harvester","permalink":"/kb/install_netapp_trident_csi"},"nextItem":{"title":"Package your own Toolbox Image","permalink":"/kb/package_your_own_toolbox_image"}},"content":"**Harvester v1.2.0** introduces a new enhancement where Longhorn system-managed components in newly-deployed clusters are automatically assigned a `system-cluster-critical` priority class by default. However, when upgrading your Harvester clusters from previous versions, you may notice that Longhorn system-managed components do not have any priority class set.\\n\\nThis behavior is intentional and aimed at supporting zero-downtime upgrades. Longhorn does not allow changing the `priority-class` setting when attached volumes exist. For more details, please refer to [Setting Priority Class During Longhorn Installation](https://longhorn.io/docs/1.4.3/advanced-resources/deploy/priority-class/#setting-priority-class-during-longhorn-installation)).\\n\\nThis article explains how to manually configure priority classes for Longhorn system-managed components after upgrading your Harvester cluster, ensuring that your Longhorn components have the appropriate priority class assigned and maintaining the stability and performance of your system.\\n\\n## Stop all virtual machines\\n\\nStop all virtual machines (VMs) to detach all volumes. Please back up any work before doing this.\\n1. [Login to a Harvester controller node and become root](https://docs.harvesterhci.io/v1.1/troubleshooting/os#how-to-log-into-a-harvester-node).\\n2. Get all running VMs and write down their namespaces and names:\\n\\n ```bash\\n kubectl get vmi -A\\n ```\\n\\n Alternatively, you can get this information by backing up the Virtual Machine Instance (VMI) manifests with the following command:\\n ```bash\\n kubectl get vmi -A -o json > vmi-backup.json\\n ```\\n\\n3. Shut down all VMs. Log in to all running VMs and shut them down gracefully (recommended). Or use the following command to send shutdown signals to all VMs:\\n ```bash\\n kubectl get vmi -A -o json | jq -r \'.items[] | [.metadata.name, .metadata.namespace] | @tsv\' | while IFS=$\'\\\\t\' read -r name namespace; do\\n if [ -z \\"$name\\" ]; then\\n break\\n fi\\n echo \\"Stop ${namespace}/${name}\\"\\n virtctl stop $name -n $namespace\\n done\\n ```\\n\\n :::note\\n You can also stop all VMs from the Harvester UI:\\n 1. Go to the **Virtual Machines** page.\\n 2. For each VM, select **\u22ee** > **Stop**.\\n :::\\n\\n4. Ensure there are no running VMs:\\n\\n Run the command:\\n\\n ```bash\\n kubectl get vmi -A\\n ```\\n\\n The above command must return:\\n\\n ```bash\\n No resources found\\n\\n## Scale down monitoring pods\\n\\n1. Scale down the Prometheus deployment. Run the following command and wait for all Prometheus pods to terminate:\\n\\n ```bash\\n kubectl patch -n cattle-monitoring-system prometheus/rancher-monitoring-prometheus --patch \'{\\"spec\\": {\\"replicas\\": 0}}\' --type merge && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system statefulset/prometheus-rancher-monitoring-prometheus\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n prometheus.monitoring.coreos.com/rancher-monitoring-prometheus patched\\n statefulset rolling update complete 0 pods at revision prometheus-rancher-monitoring-prometheus-cbf6bd5f7...\\n ```\\n\\n2. Scale down the AlertManager deployment. Run the following command and wait for all AlertManager pods to terminate:\\n\\n ```bash\\n kubectl patch -n cattle-monitoring-system alertmanager/rancher-monitoring-alertmanager --patch \'{\\"spec\\": {\\"replicas\\": 0}}\' --type merge && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system statefulset/alertmanager-rancher-monitoring-alertmanager\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n alertmanager.monitoring.coreos.com/rancher-monitoring-alertmanager patched\\n statefulset rolling update complete 0 pods at revision alertmanager-rancher-monitoring-alertmanager-c8c459dff...\\n ```\\n\\n3. Scale down the Grafana deployment. Run the following command and wait for all Grafana pods to terminate:\\n\\n ```bash\\n kubectl scale --replicas=0 deployment/rancher-monitoring-grafana -n cattle-monitoring-system && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system deployment/rancher-monitoring-grafana\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n deployment.apps/rancher-monitoring-grafana scaled\\n deployment \\"rancher-monitoring-grafana\\" successfully rolled out\\n ```\\n\\n## Scale down vm-import-controller pods\\n\\n1. Check if the [`vm-import-controller`](https://docs.harvesterhci.io/v1.1/advanced/vmimport) addon is enabled and configured with a persistent volume with the following command:\\n\\n ```bash\\n kubectl get pvc -n harvester-system harvester-vm-import-controller\\n ```\\n\\n If the above command returns an output like this, you must scale down the `vm-import-controller` pod. Otherwise, you can skip the following step.\\n ```\\n NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE\\n harvester-vm-import-controller Bound pvc-eb23e838-4c64-4650-bd8f-ba7075ab0559 200Gi RWO harvester-longhorn 2m53s\\n ```\\n\\n2. Scale down the `vm-import-controller` pods with the following command:\\n\\n ```bash\\n kubectl scale --replicas=0 deployment/harvester-vm-import-controller -n harvester-system && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n harvester-system deployment/harvester-vm-import-controller\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n deployment.apps/harvester-vm-import-controller scaled\\n deployment \\"harvester-vm-import-controller\\" successfully rolled out\\n ```\\n\\n## Set the `priority-class` setting\\n\\n1. Before applying the `priority-class` setting, you need to verify all volumes are detached. Run the following command to verify the `STATE` of each volume is `detached`:\\n\\n ```bash\\n kubectl get volumes.longhorn.io -A\\n ```\\n\\n Verify the output looks like this:\\n ```\\n NAMESPACE NAME STATE ROBUSTNESS SCHEDULED SIZE NODE AGE\\n longhorn-system pvc-5743fd02-17a3-4403-b0d3-0e9b401cceed detached unknown 5368709120 15d\\n longhorn-system pvc-7e389fe8-984c-4049-9ba8-5b797cb17278 detached unknown 53687091200 15d\\n longhorn-system pvc-8df64e54-ecdb-4d4e-8bab-28d81e316b8b detached unknown 2147483648 15d\\n longhorn-system pvc-eb23e838-4c64-4650-bd8f-ba7075ab0559 detached unknown 214748364800 11m\\n ```\\n\\n1. Set the `priority-class` setting with the following command:\\n\\n ```bash\\n kubectl patch -n longhorn-system settings.longhorn.io priority-class --patch \'{\\"value\\": \\"system-cluster-critical\\"}\' --type merge\\n ```\\n\\n Longhorn system-managed pods will restart and then you need to check if all the system-managed components have a priority class set:\\n\\n Get the value of the priority class `system-cluster-critical`:\\n ```bash\\n kubectl get priorityclass system-cluster-critical\\n ```\\n\\n Verify the output looks like this:\\n ```\\n NAME VALUE GLOBAL-DEFAULT AGE\\n system-cluster-critical 2000000000 false 15d\\n ```\\n\\n3. Use the following command to get pods\' priority in the `longhorn-system` namespace:\\n\\n ```bash\\n kubectl get pods -n longhorn-system -o custom-columns=\\"Name\\":metadata.name,\\"Priority\\":.spec.priority\\n ```\\n\\n4. Verify all system-managed components\' pods have the correct priority. System-managed components include:\\n\\n - `csi-attacher`\\n - `csi-provisioner`\\n - `csi-resizer`\\n - `csi-snapshotter`\\n - `engine-image-ei`\\n - `instance-manager-e`\\n - `instance-manager-r`\\n - `longhorn-csi-plugin`\\n\\n## Scale up vm-import-controller pods\\n\\nIf you scale down the `vm-import-controller` pods, you must scale it up again. \\n\\n1. Scale up the `vm-import-controller` pod. Run the command: \\n\\n ```bash\\n kubectl scale --replicas=1 deployment/harvester-vm-import-controller -n harvester-system && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n harvester-system deployment/harvester-vm-import-controller\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n deployment.apps/harvester-vm-import-controller scaled\\n Waiting for deployment \\"harvester-vm-import-controller\\" rollout to finish: 0 of 1 updated replicas are available...\\n deployment \\"harvester-vm-import-controller\\" successfully rolled out\\n ```\\n\\n2. Verify `vm-import-controller` is running using the following command:\\n ```bash\\n kubectl get pods --selector app.kubernetes.io/instance=vm-import-controller -A\\n ```\\n\\n A sample output looks like this, the pod\'s `STATUS` must be `Running`:\\n ```\\n NAMESPACE NAME READY STATUS RESTARTS AGE\\n harvester-system harvester-vm-import-controller-6bd8f44f55-m9k86 1/1 Running 0 4m53s\\n ```\\n\\n## Scale up monitoring pods\\n\\n1. Scale up the Prometheus deployment. Run the following command and wait for all Prometheus pods to roll out:\\n\\n ```bash\\n kubectl patch -n cattle-monitoring-system prometheus/rancher-monitoring-prometheus --patch \'{\\"spec\\": {\\"replicas\\": 1}}\' --type merge && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system statefulset/prometheus-rancher-monitoring-prometheus\\n ```\\n\\n A sample output looks like:\\n ```\\n prometheus.monitoring.coreos.com/rancher-monitoring-prometheus patched\\n Waiting for 1 pods to be ready...\\n statefulset rolling update complete 1 pods at revision prometheus-rancher-monitoring-prometheus-cbf6bd5f7...\\n ```\\n\\n2. Scale down the AlertManager deployment. Run the following command and wait for all AlertManager pods to roll out:\\n\\n ```bash\\n kubectl patch -n cattle-monitoring-system alertmanager/rancher-monitoring-alertmanager --patch \'{\\"spec\\": {\\"replicas\\": 1}}\' --type merge && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system statefulset/alertmanager-rancher-monitoring-alertmanager\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n alertmanager.monitoring.coreos.com/rancher-monitoring-alertmanager patched\\n Waiting for 1 pods to be ready...\\n statefulset rolling update complete 1 pods at revision alertmanager-rancher-monitoring-alertmanager-c8bd4466c...\\n ```\\n\\n3. Scale down the Grafana deployment. Run the following command and wait for all Grafana pods to roll out:\\n\\n ```bash\\n kubectl scale --replicas=1 deployment/rancher-monitoring-grafana -n cattle-monitoring-system && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system deployment/rancher-monitoring-grafana\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n deployment.apps/rancher-monitoring-grafana scaled\\n Waiting for deployment \\"rancher-monitoring-grafana\\" rollout to finish: 0 of 1 updated replicas are available...\\n deployment \\"rancher-monitoring-grafana\\" successfully rolled out\\n ```\\n\\n## Start virtual machines\\n\\n1. Start a VM with the command:\\n\\n ```bash\\n virtctl start $name -n $namespace\\n ```\\n\\n Replace `$name` with the VM\'s name and `$namespace` with the VM\'s namespace. You can list all virtual machines with the command:\\n\\n ```bash\\n kubectl get vms -A\\n ```\\n\\n :::note\\n You can also stop all VMs from the Harvester UI:\\n 1. Go to the **Virtual Machines** page.\\n 2. For each VM, select **\u22ee** > **Start**.\\n :::\\n\\n Alternatively, you can start all running VMs with the following command:\\n\\n ```bash\\n cat vmi-backup.json | jq -r \'.items[] | [.metadata.name, .metadata.namespace] | @tsv\' | while IFS=$\'\\\\t\' read -r name namespace; do\\n if [ -z \\"$name\\" ]; then\\n break\\n fi\\n echo \\"Start ${namespace}/${name}\\"\\n virtctl start $name -n $namespace || true\\n done\\n ```"},{"id":"package_your_own_toolbox_image","metadata":{"permalink":"/kb/package_your_own_toolbox_image","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-07-06/package_your_own_toolbox_image.md","source":"@site/kb/2023-07-06/package_your_own_toolbox_image.md","title":"Package your own Toolbox Image","description":"How to package your own toolbox image","date":"2023-07-06T00:00:00.000Z","formattedDate":"July 6, 2023","tags":[{"label":"debug","permalink":"/kb/tags/debug"},{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"container","permalink":"/kb/tags/container"}],"readingTime":1.655,"truncated":false,"authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"frontMatter":{"title":"Package your own Toolbox Image","description":"How to package your own toolbox image","slug":"package_your_own_toolbox_image","authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"tags":["debug","harvester","container"],"hide_table_of_contents":false},"prevItem":{"title":"Configure PriorityClass on Longhorn System Components","permalink":"/kb/configure_priority_class_longhorn"},"nextItem":{"title":"Scan and Repair Root Filesystem of VirtualMachine","permalink":"/kb/scan-and-repair-vm-root-filesystem"}},"content":"Harvester OS is designed as an immutable operating system, which means you cannot directly install additional packages on it. While there is a way to [install packages](https://docs.harvesterhci.io/dev/troubleshooting/os#how-can-i-install-packages-why-are-some-paths-read-only), it is strongly advised against doing so, as it may lead to system instability.\\n\\nIf you only want to debug with the system, the preferred way is to package the toolbox image with all the needed packages. \\n\\nThis article shares how to package your toolbox image and how to install any packages on the toolbox image that help you debug the system.\\n\\nFor example, if you want to analyze a storage performance issue, you can install `blktrace` on the toolbox image.\\n\\n\\n## Create a Dockerfile\\n\\n```bash\\nFROM opensuse/leap:15.4\\n\\n# Install blktrace\\nRUN zypper in -y \\\\\\n blktrace\\n\\nRUN zypper clean --all\\n```\\n\\n## Build the image and push\\n```bash\\n# assume you are in the directory of Dockerfile\\n$ docker build -t harvester/toolbox:dev .\\n.\\n.\\n.\\nnaming to docker.io/harvester/toolbox:dev ...\\n$ docker push harvester/toolbox:dev\\n.\\n.\\nd4b76d0683d4: Pushed \\na605baa225e2: Pushed \\n9e9058bdf63c: Layer already exists \\n```\\n\\nAfter you build and push the image, you can run the toolbox using this image to trace storage performance.\\n\\n## Run the toolbox\\n```bash\\n# use `privileged` flag only when you needed. blktrace need debugfs, so I add extra mountpoint.\\ndocker run -it --privileged -v /sys/kernel/debug/:/sys/kernel/debug/ --rm harvester/toolbox:dev bash\\n\\n# test blktrace\\n6ffa8eda3aaf:/ $ blktrace -d /dev/nvme0n1 -o - | blkparse -i -\\n259,0 10 3414 0.020814875 34084 Q WS 2414127984 + 8 [fio]\\n259,0 10 3415 0.020815190 34084 G WS 2414127984 + 8 [fio]\\n259,0 10 3416 0.020815989 34084 C WS 3206896544 + 8 [0]\\n259,0 10 3417 0.020816652 34084 C WS 2140319184 + 8 [0]\\n259,0 10 3418 0.020817992 34084 P N [fio]\\n259,0 10 3419 0.020818227 34084 U N [fio] 1\\n259,0 10 3420 0.020818437 34084 D WS 2414127984 + 8 [fio]\\n259,0 10 3421 0.020821826 34084 Q WS 1743934904 + 8 [fio]\\n259,0 10 3422 0.020822150 34084 G WS 1743934904 + 8 [fio]\\n\\n```"},{"id":"scan-and-repair-vm-root-filesystem","metadata":{"permalink":"/kb/scan-and-repair-vm-root-filesystem","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-02-01/scan_and_repair_filesystem.md","source":"@site/kb/2023-02-01/scan_and_repair_filesystem.md","title":"Scan and Repair Root Filesystem of VirtualMachine","description":"Scan and repair root filesystem of VM","date":"2023-02-01T00:00:00.000Z","formattedDate":"February 1, 2023","tags":[{"label":"storage","permalink":"/kb/tags/storage"},{"label":"longhorn","permalink":"/kb/tags/longhorn"},{"label":"root","permalink":"/kb/tags/root"},{"label":"filesystem","permalink":"/kb/tags/filesystem"}],"readingTime":3.37,"truncated":false,"authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"frontMatter":{"title":"Scan and Repair Root Filesystem of VirtualMachine","description":"Scan and repair root filesystem of VM","slug":"scan-and-repair-vm-root-filesystem","authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"tags":["storage","longhorn","root","filesystem"],"hide_table_of_contents":false},"prevItem":{"title":"Package your own Toolbox Image","permalink":"/kb/package_your_own_toolbox_image"},"nextItem":{"title":"Evicting Replicas From a Disk (the CLI way)","permalink":"/kb/evicting-replicas-from-a-disk-the-cli-way"}},"content":"In earlier versions of Harvester (v1.0.3 and prior), Longhorn volumes may get corrupted during the replica rebuilding process (reference: [Analysis: Potential Data/Filesystem Corruption](https://longhorn.io/kb/troubleshooting-volume-filesystem-corruption/#solution)). In Harvester v1.1.0 and later versions, the Longhorn team has fixed this issue. This article covers manual steps you can take to scan the VM\'s filesystem and repair it if needed.\\n\\n\\n## Stop The VM And Backup Volume\\n\\nBefore you scan the filesystem, it is recommend you back up the volume first. For an example, refer to the following steps to stop the VM and backup the volume.\\n\\n- Find the target VM.\\n\\n![finding the target VM](./imgs/finding_the_target_vm.png)\\n\\n- Stop the target VM.\\n\\n![Stop the target VM](./imgs/stop_the_target_vm.png)\\n\\nThe target VM is stopped and the related volumes are detached. Now go to the Longhorn UI to backup this volume.\\n\\n- Enable `Developer Tools & Features` (Preferences -> Enable Developer Tools & Features).\\n\\n![Preferences then enable developer mode](./imgs/preferences_enable_developer_mode.png)\\n![Enable the developer mode](./imgs/enable_the_developer_mode.png)\\n\\n- Click the `\u22ee` button and select **Edit Config** to edit the config page of the VM.\\n\\n![goto edit config page of VM](./imgs/goto_vm_edit_config_page.png)\\n\\n- Go to the `Volumes` tab and select `Check volume details.`\\n\\n![link to longhorn volume page](./imgs/link_to_longhorn_volume.png)\\n\\n- Click the dropdown menu on the right side and select \'Attach\' to attach the volume again. \\n\\n![attach this volume again](./imgs/attach_this_volume_again.png)\\n\\n- Select the attached node. \\n\\n![choose the attached node](./imgs/choose_the_attached_node.png)\\n\\n- Check the volume attached under `Volume Details` and select `Take Snapshot` on this volume page.\\n\\n![take snapshot on volume page](./imgs/take_snapshot_on_volume_page.png)\\n\\n- Confirm that the snapshot is ready.\\n\\n![check the snapshot is ready](./imgs/check_the_snapshot_is_ready.png)\\n\\nNow that you completed the volume backup, you need to scan and repair the root filesystem.\\n\\n## Scanning the root filesystem and repairing\\n\\nThis section will introduce how to scan the filesystem (e.g., XFS, EXT4) using related tools.\\n\\nBefore scanning, you need to know the filesystem\'s device/partition.\\n\\n- Identify the filesystem\'s device by checking the major and minor numbers of that device.\\n\\n1. Obtain the major and minor numbers from the listed volume information.\\n \\n In the following example, the volume name is `pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58`.\\n ```\\n harvester-node-0:~ # ls /dev/longhorn/pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58 -al\\n brw-rw---- 1 root root 8, 0 Oct 23 14:43 /dev/longhorn/pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58\\n ```\\n The output indicates that the major and minor numbers are `8:0`.\\n \\n2. Obtain the device name from the output of the `lsblk` command.\\n ```\\n harvester-node-0:~ # lsblk\\n NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS\\n loop0 7:0 0 3G 1 loop /\\n sda 8:0 0 40G 0 disk\\n \u251c\u2500sda1 8:1 0 2M 0 part\\n \u251c\u2500sda2 8:2 0 20M 0 part\\n \u2514\u2500sda3 8:3 0 40G 0 part\\n ```\\n The output indicates that `8:0` are the major and minor numbers of the device named `sda`. Therefore, `/dev/sda` is related to the volume named `pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58`.\\n\\n- You should now know the filesystem\'s partition. In the example below, sda3 is the filesystem\'s partition.\\n- Use the Filesystem toolbox image to scan and repair.\\n\\n```\\n# docker run -it --rm --privileged registry.opensuse.org/isv/rancher/harvester/toolbox/main/fs-toolbox:latest -- bash\\n```\\n\\nThen we try to scan with this target device.\\n\\n### XFS\\n\\nWhen scanning an XFS filesystem, use the `xfs_repair` command and specify the problematic partition of the device.\\n\\nIn the following example, `/dev/sda3` is the problematic partition.\\n```\\n# xfs_repair -n /dev/sda3\\n```\\n\\nTo repair the corrupted partition, run the following command.\\n\\n```\\n# xfs_repair /dev/sda3\\n```\\n\\n### EXT4\\n\\nWhen scanning a EXT4 filesystem, use the `e2fsck` command as follows, where the `/dev/sde1` is the problematic partition of the device.\\n\\n```\\n# e2fsck -f /dev/sde1\\n```\\n\\nTo repair the corrupted partition, run the following command.\\n\\n```\\n# e2fsck -fp /dev/sde1\\n```\\n\\n\\nAfter using the \'e2fsck\' command, you should also see logs related to scanning and repairing the partition. Scanning and repairing the corrupted partition is successful if there are no errors in these logs. \\n\\n\\n## Detach and Start VM again.\\n\\nAfter the corrupted partition is scanned and repaired, detach the volume and try to start the related VM again.\\n\\n- Detach the volume from the Longhorn UI.\\n\\n![detach volume on longhorn UI](./imgs/detach_volume.png)\\n\\n- Start the related VM again from the Harvester UI.\\n\\n![Start VM again](./imgs/start_vm_again.png)\\n\\nYour VM should now work normally."},{"id":"evicting-replicas-from-a-disk-the-cli-way","metadata":{"permalink":"/kb/evicting-replicas-from-a-disk-the-cli-way","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-01-12/evict_replicas_from_a_disk.md","source":"@site/kb/2023-01-12/evict_replicas_from_a_disk.md","title":"Evicting Replicas From a Disk (the CLI way)","description":"Evicting replicas from a disk (the CLI way)","date":"2023-01-12T00:00:00.000Z","formattedDate":"January 12, 2023","tags":[{"label":"storage","permalink":"/kb/tags/storage"},{"label":"longhorn","permalink":"/kb/tags/longhorn"},{"label":"disk","permalink":"/kb/tags/disk"}],"readingTime":1.935,"truncated":false,"authors":[{"name":"Kiefer Chang","title":"Engineer Manager","url":"https://github.com/bk201","image_url":"https://github.com/bk201.png","imageURL":"https://github.com/bk201.png"}],"frontMatter":{"title":"Evicting Replicas From a Disk (the CLI way)","description":"Evicting replicas from a disk (the CLI way)","slug":"evicting-replicas-from-a-disk-the-cli-way","authors":[{"name":"Kiefer Chang","title":"Engineer Manager","url":"https://github.com/bk201","image_url":"https://github.com/bk201.png","imageURL":"https://github.com/bk201.png"}],"tags":["storage","longhorn","disk"],"hide_table_of_contents":false},"prevItem":{"title":"Scan and Repair Root Filesystem of VirtualMachine","permalink":"/kb/scan-and-repair-vm-root-filesystem"},"nextItem":{"title":"NIC Naming Scheme","permalink":"/kb/nic-naming-scheme"}},"content":"Harvester replicates volumes data across disks in a cluster. Before removing a disk, the user needs to evict replicas on the disk to other disks to preserve the volumes\' configured availability. For more information about eviction in Longhorn, please check [Evicting Replicas on Disabled Disks or Nodes](https://longhorn.io/docs/1.3.2/volumes-and-nodes/disks-or-nodes-eviction/).\\n\\n## Preparation\\n\\nThis document describes how to evict Longhorn disks using the `kubectl` command. Before that, users must ensure the environment is set up correctly.\\nThere are two recommended ways to do this:\\n\\n1. Log in to any management node and switch to root (`sudo -i`).\\n1. Download Kubeconfig file and use it locally\\n - Install `kubectl` and `yq` program manually.\\n - Open Harvester GUI, click `support` at the bottom left of the page and click `Download KubeConfig` to download the Kubeconfig file.\\n - Set the Kubeconfig file\'s path to `KUBECONFIG` environment variable. For example, `export KUBECONFIG=/path/to/kubeconfig`.\\n\\n\\n## Evicting replicas from a disk\\n\\n1. List Longhorn nodes (names are identical to Kubernetes nodes):\\n\\n ```\\n kubectl get -n longhorn-system nodes.longhorn.io\\n ```\\n\\n Sample output:\\n\\n ```\\n NAME READY ALLOWSCHEDULING SCHEDULABLE AGE\\n node1 True true True 24d\\n node2 True true True 24d\\n node3 True true True 24d\\n ```\\n\\n1. List disks on a node. Assume we want to evict replicas of a disk on `node1`:\\n\\n ```\\n kubectl get -n longhorn-system nodes.longhorn.io node1 -o yaml | yq e \'.spec.disks\'\\n ```\\n\\n Sample output:\\n\\n ```\\n default-disk-ed7af10f5b8356be:\\n allowScheduling: true\\n evictionRequested: false\\n path: /var/lib/harvester/defaultdisk\\n storageReserved: 36900254515\\n tags: []\\n ```\\n\\n1. Assume disk `default-disk-ed7af10f5b8356be` is the target we want to evict replicas out of.\\n\\n Edit the node:\\n ```\\n kubectl edit -n longhorn-system nodes.longhorn.io node1 \\n ```\\n\\n Update these two fields and save:\\n - `spec.disks..allowScheduling` to `false`\\n - `spec.disks..evictionRequested` to `true`\\n\\n Sample editing:\\n\\n ```\\n default-disk-ed7af10f5b8356be:\\n allowScheduling: false\\n evictionRequested: true\\n path: /var/lib/harvester/defaultdisk\\n storageReserved: 36900254515\\n tags: []\\n ```\\n\\n1. Wait for all replicas on the disk to be evicted.\\n\\n Get current scheduled replicas on the disk:\\n ```\\n kubectl get -n longhorn-system nodes.longhorn.io node1 -o yaml | yq e \'.status.diskStatus.default-disk-ed7af10f5b8356be.scheduledReplica\'\\n ```\\n\\n Sample output:\\n ```\\n pvc-86d3d212-d674-4c64-b69b-4a2eb1df2272-r-7b422db7: 5368709120\\n pvc-b06f0b09-f30c-4936-8a2a-425b993dd6cb-r-bb0fa6b3: 2147483648\\n pvc-b844bcc6-3b06-4367-a136-3909251cb560-r-08d1ab3c: 53687091200\\n pvc-ea6e0dff-f446-4a38-916a-b3bea522f51c-r-193ca5c6: 10737418240\\n ```\\n\\n Run the command repeatedly, and the output should eventually become an empty map:\\n ```\\n {}\\n ```\\n\\n This means Longhorn evicts replicas on the disk to other disks.\\n\\n :::note\\n \\n If a replica always stays in a disk, please open the [Longhorn GUI](https://docs.harvesterhci.io/v1.1/troubleshooting/harvester#access-embedded-rancher-and-longhorn-dashboards) and check if there is free space on other disks.\\n :::"},{"id":"nic-naming-scheme","metadata":{"permalink":"/kb/nic-naming-scheme","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2022-04-06/nic_naming_scheme.md","source":"@site/kb/2022-04-06/nic_naming_scheme.md","title":"NIC Naming Scheme","description":"NIC Naming Scheme changed after upgrading to v1.0.1","date":"2022-04-06T00:00:00.000Z","formattedDate":"April 6, 2022","tags":[{"label":"network","permalink":"/kb/tags/network"}],"readingTime":1.825,"truncated":false,"authors":[{"name":"Date Huang","title":"Software Engineer","url":"https://github.com/tjjh89017","image_url":"https://github.com/tjjh89017.png","imageURL":"https://github.com/tjjh89017.png"}],"frontMatter":{"title":"NIC Naming Scheme","descripion":"NIC Naming Scheme Change","slug":"nic-naming-scheme","authors":[{"name":"Date Huang","title":"Software Engineer","url":"https://github.com/tjjh89017","image_url":"https://github.com/tjjh89017.png","imageURL":"https://github.com/tjjh89017.png"}],"tags":["network"],"hide_table_of_contents":false},"prevItem":{"title":"Evicting Replicas From a Disk (the CLI way)","permalink":"/kb/evicting-replicas-from-a-disk-the-cli-way"},"nextItem":{"title":"Multiple NICs VM Connectivity","permalink":"/kb/multiple-nics-vm-connectivity"}},"content":"## NIC Naming Scheme changed after upgrading to v1.0.1\\n\\n`systemd` in OpenSUSE Leap 15.3 which is the base OS of Harvester is upgraded to `246.16-150300.7.39.1`. In this version, `systemd` will enable additional naming scheme `sle15-sp3` which is `v238` with `bridge_no_slot`. When there is a PCI bridge associated with NIC, `systemd` will never generate `ID_NET_NAME_SLOT` and naming policy in `/usr/lib/systemd/network/99-default.link` will fallback to `ID_NET_NAME_PATH`. According to this change, NIC names might be changed in your Harvester nodes during the upgrade process from `v1.0.0` to `v1.0.1-rc1` or above, and it will cause network issues that are associated with NIC names.\\n\\n## Effect Settings and Workaround\\n\\n### Startup Network Configuration\\n\\nNIC name changes will need to update the name in `/oem/99_custom.yaml`. You could use [migration script](https://github.com/harvester/upgrade-helpers/blob/main/hack/udev_v238_sle15-sp3.py) to change the NIC names which are associated with a PCI bridge.\\n\\n:::tip\\nYou could find an identical machine to test naming changes before applying the configuration to production machines\\n:::\\n\\nYou could simply execute the script with root account in `v1.0.0` via\\n```bash\\n# python3 udev_v238_sle15-sp3.py\\n```\\n\\nIt will output the patched configuration to the screen and you could compare it to the original one to ensure there is no exception. (e.g. We could use `vimdiff` to check the configuration)\\n```bash\\n# python3 udev_v238_sle15-spe3.py > /oem/test\\n# vimdiff /oem/test /oem/99_custom.yaml\\n```\\n\\nAfter checking the result, we could execute the script with `--really-want-to-do` to override the configuration. It will also back up the original configuration file with a timestamp before patching it.\\n```bash\\n# python3 udev_v238_sle15-sp3.py --really-want-to-do\\n```\\n\\n### Harvester VLAN Network Configuration\\n\\nIf your VLAN network is associated with NIC name directly without `bonding`, you will need to migrate `ClusterNetwork` and `NodeNetwork` with the previous section together.\\n\\n:::note\\nIf your VLAN network is associated with the `bonding` name in `/oem/99_custom.yaml`, you could skip this section.\\n:::\\n\\n#### Modify ClusterNetworks\\n\\nYou need to modify `ClusterNetworks` via \\n```bash\\n$ kubectl edit clusternetworks vlan\\n```\\nsearch this pattern\\n```yaml\\nconfig:\\n defaultPhysicalNIC: \\n```\\nand change to new NIC name\\n\\n#### Modify NodeNetworks\\n\\nYou need to modify `NodeNetworks` via\\n```bash\\n$ kubectl edit nodenetworks -vlan\\n```\\nsearch this pattern\\n```yaml\\nspec:\\n nic: \\n```\\nand change to new NIC name"},{"id":"multiple-nics-vm-connectivity","metadata":{"permalink":"/kb/multiple-nics-vm-connectivity","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2022-03-10/multiple_nics_vm_connectivity.md","source":"@site/kb/2022-03-10/multiple_nics_vm_connectivity.md","title":"Multiple NICs VM Connectivity","description":"What is the default behavior of a VM with multiple NICs","date":"2022-03-10T00:00:00.000Z","formattedDate":"March 10, 2022","tags":[{"label":"vm","permalink":"/kb/tags/vm"},{"label":"network","permalink":"/kb/tags/network"}],"readingTime":3.955,"truncated":false,"authors":[{"name":"Date Huang","title":"Software Engineer","url":"https://github.com/tjjh89017","image_url":"https://github.com/tjjh89017.png","imageURL":"https://github.com/tjjh89017.png"}],"frontMatter":{"title":"Multiple NICs VM Connectivity","descripion":"How to deal VMs with multiple NICs in Harvester","slug":"multiple-nics-vm-connectivity","authors":[{"name":"Date Huang","title":"Software Engineer","url":"https://github.com/tjjh89017","image_url":"https://github.com/tjjh89017.png","imageURL":"https://github.com/tjjh89017.png"}],"tags":["vm","network"],"hide_table_of_contents":false},"prevItem":{"title":"NIC Naming Scheme","permalink":"/kb/nic-naming-scheme"},"nextItem":{"title":"VM Scheduling","permalink":"/kb/vm-scheduling"}},"content":"## What is the default behavior of a VM with multiple NICs\\n\\nIn [some scenarios](https://github.com/harvester/harvester/issues/1059), you\'ll setup two or more NICs in your VM to serve different networking purposes. If all networks are setup by default with DHCP, you might get random connectivity issues. And while it might get fixed after rebooting the VM, it still will lose connection randomly after some period.\\n\\n## How-to identify connectivity issues\\n\\nIn a Linux VM, you can use commands from the `iproute2` package to identify the default route.\\n\\nIn your VM, execute the following command:\\n```bash\\nip route show default\\n```\\n:::tip\\nIf you get the `access denied` error, please run the command using `sudo`\\n:::\\n \\nThe output of this command will only show the default route with the gateway and VM IP of the primary network interface (`eth0` in the example below).\\n```\\ndefault via dev eth0 proto dhcp src metric 100\\n```\\n\\nHere is the full example:\\n```\\n$ ip route show default\\ndefault via 192.168.0.254 dev eth0 proto dhcp src 192.168.0.100 metric 100\\n```\\n\\nHowever, if the issue covered in this KB occurs, you\'ll only be able to connect to the VM via the VNC or serial console.\\n\\nOnce connected, you can run again the same command as before:\\n```bash\\n$ ip route show default\\n```\\n\\nHowever, this time you\'ll get a default route with an incorrect gateway IP.\\nFor example:\\n```\\ndefault via dev eth0 proto dhcp src metric 100\\n```\\n\\n## Why do connectivity issues occur randomly\\n\\nIn a standard setup, cloud-based VMs typically use DHCP for their NICs configuration. It will set an IP and a gateway for each NIC. Lastly, a default route to the gateway IP will also be added, so you can use its IP to connect to the VM.\\n\\nHowever, Linux distributions start multiple DHCP clients at the same time and do not have a **priority** system. This means that if you have two or more NICs configured with DHCP, the client will enter a **race condition** to configure the default route. And depending on the currently running Linux distribution DHCP script, there is no guarantee which default route will be configured.\\n\\nAs the default route might change in every DHCP renewing process or after every OS reboot, this will create network connectivity issues.\\n\\n## How to avoid the random connectivity issues\\n\\nYou can easily avoid these connectivity issues by having only one NIC attached to the VM and having only one IP and one gateway configured.\\n\\nHowever, for VMs in more complex infrastructures, it is often not possible to use just one NIC. For example, if your infrastructure has a storage network and a service network. For security reasons, the storage network will be isolated from the service network and have a separate subnet. In this case, you must have two NICs to connect to both the service and storage networks.\\n\\nYou can choose a solution below that meets your requirements and security policy.\\n\\n### Disable DHCP on secondary NIC\\n\\nAs mentioned above, the problem is caused by a `race condition` between two DHCP clients. One solution to avoid this problem is to disable DHCP for all NICs and configure them with static IPs only. Likewise, you can configure the secondary NIC with a static IP and keep the primary NIC enabled with DHCP.\\n\\n1. To configure the primary NIC with a static IP (`eth0` in this example), you can edit the file `/etc/sysconfig/network/ifcfg-eth0` with the following values:\\n\\n```\\nBOOTPROTO=\'static\'\\nIPADDR=\'192.168.0.100\'\\nNETMASK=\'255.255.255.0\'\\n```\\n\\nAlternatively, if you want to reserve the primary NIC using DHCP (`eth0` in this example), use the following values instead:\\n\\n```\\nBOOTPROTO=\'dhcp\'\\nDHCLIENT_SET_DEFAULT_ROUTE=\'yes\'\\n```\\n\\n\\n2. You need to configure the default route by editing the file `/etc/sysconfig/network/ifroute-eth0` (if you configured the primary NIC using DHCP, skip this step):\\n\\n\\n```\\n# Destination Dummy/Gateway Netmask Interface\\ndefault 192.168.0.254 - eth0\\n```\\n\\n:::warning\\nDo not put other default route for your secondary NIC\\n:::\\n \\n3. Finally, configure a static IP for the secondary NIC by editing the file `/etc/sysconfig/network/ifcfg-eth1`:\\n\\n```\\nBOOTPROTO=\'static\'\\nIPADDR=\'10.0.0.100\'\\nNETMASK=\'255.255.255.0\'\\n```\\n\\n#### Cloud-Init config\\n\\n```yaml\\nnetwork:\\n version: 1\\n config:\\n - type: physical\\n name: eth0\\n subnets:\\n - type: dhcp\\n - type: physical\\n name: eth1\\n subnets:\\n - type: static\\n address: 10.0.0.100/24\\n```\\n \\n### Disable secondary NIC default route from DHCP\\n\\nIf your secondary NIC requires to get its IP from DHCP, you\'ll need to disable the secondary NIC default route configuration.\\n\\n1. Confirm that the primary NIC configures its default route in the file `/etc/sysconfig/network/ifcfg-eth0`:\\n\\n```\\nBOOTPROTO=\'dhcp\'\\nDHCLIENT_SET_DEFAULT_ROUTE=\'yes\'\\n```\\n\\n2. Disable the secondary NIC default route configuration by editing the file `/etc/sysconfig/network/ifcfg-eth1`:\\n\\n```\\nBOOTPROTO=\'dhcp\'\\nDHCLIENT_SET_DEFAULT_ROUTE=\'no\'\\n```\\n\\n#### Cloud-Init config\\n\\nThis solution is not available in Cloud-Init. Cloud-Init didn\'t allow any option for DHCP."},{"id":"vm-scheduling","metadata":{"permalink":"/kb/vm-scheduling","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2022-03-07/vm-scheduling.md","source":"@site/kb/2022-03-07/vm-scheduling.md","title":"VM Scheduling","description":"How does Harvester schedule VMs?","date":"2022-03-07T00:00:00.000Z","formattedDate":"March 7, 2022","tags":[{"label":"vm","permalink":"/kb/tags/vm"},{"label":"scheduling","permalink":"/kb/tags/scheduling"}],"readingTime":15.44,"truncated":false,"authors":[{"name":"PoAn Yang","title":"Software Engineer","url":"https://github.com/FrankYang0529","image_url":"https://github.com/FrankYang0529.png","imageURL":"https://github.com/FrankYang0529.png"}],"frontMatter":{"title":"VM Scheduling","description":"How does Harvester schedule VMs?","slug":"vm-scheduling","authors":[{"name":"PoAn Yang","title":"Software Engineer","url":"https://github.com/FrankYang0529","image_url":"https://github.com/FrankYang0529.png","imageURL":"https://github.com/FrankYang0529.png"}],"tags":["vm","scheduling"],"hide_table_of_contents":false},"prevItem":{"title":"Multiple NICs VM Connectivity","permalink":"/kb/multiple-nics-vm-connectivity"}},"content":"## How does Harvester schedule a VM?\\n\\nHarvester doesn\'t directly schedule a VM in Kubernetes, it relies on [KubeVirt](http://kubevirt.io/) to create the custom resource `VirtualMachine`. When the request to create a new VM is sent, a `VirtualMachineInstance` object is created and it creates the corresponding `Pod`.\\n\\nThe whole VM creation processt leverages `kube-scheduler`, which allows Harvester to use `nodeSelector`, `affinity`, and resources request/limitation to influence where a VM will be deployed.\\n\\n## How does kube-scheduler decide where to deploy a VM?\\n\\nFirst, `kube-scheduler` finds Nodes available to run a pod. After that, `kube-scheduler` scores each available Node by a list of [plugins](https://github.com/kubernetes/kubernetes/tree/v1.22.7/pkg/scheduler/framework/plugins) like [ImageLocality](https://github.com/kubernetes/kubernetes/blob/v1.22.7/pkg/scheduler/framework/plugins/imagelocality/image_locality.go), [InterPodAffinity](https://github.com/kubernetes/kubernetes/tree/v1.22.7/pkg/scheduler/framework/plugins/interpodaffinity), [NodeAffinity](https://github.com/kubernetes/kubernetes/tree/v1.22.7/pkg/scheduler/framework/plugins/nodeaffinity), etc. \\n\\nFinally, `kube-scheduler` calculates the scores from the plugins results for each Node, and select the Node with the highest score to deploy the Pod.\\n\\nFor example, let\'s say we have a three nodes Harvester cluster with 6 cores CPU and 16G RAM each, and we want to deploy a VM with 1 CPU and 1G RAM (without resources overcommit). \\n\\n`kube-scheduler` will summarize the scores, as displayed in _Table 1_ below, and will select the node with the highest score, `harvester-node-2` in this case, to deploy the VM.\\n\\n
\\n kube-scheduler logs\\n\\n```\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 0,\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 45,\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 46,\\n\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 4,\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 34,\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 37,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=4\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=34\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=37\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=45\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=46\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" node=\\"harvester-node-0\\" score=1000358\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" node=\\"harvester-node-1\\" score=1000433\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" node=\\"harvester-node-2\\" score=1000437\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm-without-overcommit-75q9b\\", node \\"harvester-node-2\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm-without-overcommit-75q9b\\", node \\"harvester-node-2\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" node=\\"harvester-node-2\\"\\n```\\n
\\n\\n**Table 1 - kube-scheduler scores example**\\n\\n| | harvester-node-0 | harvester-node-1 | harvester-node-2 |\\n|:-------------------------------:|:----------------:|:----------------:|:----------------:|\\n| ImageLocality | 54 | 54 | 54 |\\n| InterPodAffinity | 0 | 0 | 0 |\\n| NodeResourcesLeastAllocated | 4 | 34 | 37 |\\n| NodeAffinity | 0 | 0 | 0 |\\n| NodePreferAvoidPods | 1000000 | 1000000 | 1000000 |\\n| PodTopologySpread | 200 | 200 | 200 |\\n| TaintToleration | 100 | 100 | 100 |\\n| NodeResourcesBalancedAllocation | 0 | 45 | 46 |\\n| Total | 1000358 | 1000433 | 1000437 |\\n\\n## Why VMs are distributed unevenly with overcommit?\\n\\nWith resources overcommit, Harvester modifies the resources request. By default, the `overcommit` configuration is `{\\"cpu\\": 1600, \\"memory\\": 150, \\"storage\\": 200}`. This means that if we request a VM with 1 CPU and 1G RAM, its `resources.requests.cpu` will become `62m`. \\n\\n!!! note\\n The unit suffix `m` stands for \\"thousandth of a core.\\"\\n\\nTo explain it, let\'s take the case of CPU overcommit. The default value of 1 CPU is equal to 1000m CPU, and with the default overcommit configuration of `\\"cpu\\": 1600`, the CPU resource will be 16x smaller. Here is the calculation: `1000m * 100 / 1600 = 62m`.\\n\\nNow, we can see how overcommitting influences `kube-scheduler` scores.\\n\\nIn this example, we use a three nodes Harvester cluster with 6 cores and 16G RAM each. We will deploy two VMs with 1 CPU and 1G RAM, and we will compare the scores for both cases of \\"with-overcommit\\" and \\"without-overcommit\\" resources. \\n\\nThe results of both tables _Table 2_ and _Table 3_ can be explained as follow:\\n\\nIn the \\"with-overcommit\\" case, both VMs are deployed on `harvester-node-2`, however in the \\"without-overcommit\\" case, the VM1 is deployed on `harvester-node-2`, and VM2 is deployed on `harvester-node-1`. \\n\\nIf we look at the detailed scores, we\'ll see a variation of `Total Score` for `harvester-node-2` from `1000459` to `1000461` in the \\"with-overcommit\\" case, and `1000437` to `1000382` in the \\"without-overcommit case\\". It\'s because resources overcommit influences `request-cpu` and `request-memory`. \\n\\nIn the \\"with-overcommit\\" case, the `request-cpu` changes from `4412m` to `4474m`. The difference between the two numbers is `62m`, which is what we calculated above. However, in the \\"without-overcommit\\" case, we send **real** requests to `kube-scheduler`, so the `request-cpu` changes from `5350m` to `6350m`.\\n\\nFinally, since most plugins give the same scores for each node except `NodeResourcesBalancedAllocation` and `NodeResourcesLeastAllocated`, we\'ll see a difference of these two scores for each node.\\n\\nFrom the results, we can see the overcommit feature influences the final score of each Node, so VMs are distributed unevenly. Although the `harvester-node-2` score for VM 2 is higher than VM 1, it\'s not always increasing. In _Table 4_, we keep deploying VM with 1 CPU and 1G RAM, and we can see the score of `harvester-node-2` starts decreasing from 11th VM. The behavior of `kube-scheduler` depends on your cluster resources and the workload you deployed.\\n\\n
\\n kube-scheduler logs for vm1-with-overcommit\\n\\n```\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 0,\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 58,\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4412 memory:5581918208] ,score 59,\\n\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 5,\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 43,\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4412 memory:5581918208] ,score 46,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=5\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=43\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=46\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=58\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=59\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" node=\\"harvester-node-0\\" score=1000359\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" node=\\"harvester-node-1\\" score=1000455\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" node=\\"harvester-node-2\\" score=1000459\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm1-with-overcommit-ljlmq\\", node \\"harvester-node-2\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm1-with-overcommit-ljlmq\\", node \\"harvester-node-2\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" node=\\"harvester-node-2\\"\\n```\\n
\\n\\n
\\n kube-scheduler logs for vm2-with-overcommit\\n\\n```\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 0,\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 58,\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4474 memory:6476701696] ,score 64,\\n\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 5,\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 43,\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4474 memory:6476701696] ,score 43,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=58\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=64\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=5\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=43\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=43\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" node=\\"harvester-node-0\\" score=1000359\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" node=\\"harvester-node-1\\" score=1000455\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" node=\\"harvester-node-2\\" score=1000461\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm2-with-overcommit-pwrx4\\", node \\"harvester-node-2\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm2-with-overcommit-pwrx4\\", node \\"harvester-node-2\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" node=\\"harvester-node-2\\"\\n```\\n
\\n\\n
\\n kube-scheduler logs for vm1-without-overcommit\\n\\n```\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 0,\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 45,\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 46,\\n\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 4,\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 34,\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 37,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=4\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=34\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=37\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=45\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=46\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" node=\\"harvester-node-0\\" score=1000358\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" node=\\"harvester-node-1\\" score=1000433\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" node=\\"harvester-node-2\\" score=1000437\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm1-with-overcommit-6xqmq\\", node \\"harvester-node-2\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm1-with-overcommit-6xqmq\\", node \\"harvester-node-2\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" node=\\"harvester-node-2\\"\\n```\\n
\\n\\n
\\n kube-scheduler logs for vm2-without-overcommit\\n\\n```\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 0,\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 45,\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:6350 memory:7195328512] ,score 0,\\n\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 4,\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 34,\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:6350 memory:7195328512] ,score 28,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=45\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=4\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=34\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=28\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" node=\\"harvester-node-0\\" score=1000358\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" node=\\"harvester-node-1\\" score=1000433\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" node=\\"harvester-node-2\\" score=1000382\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm2-without-overcommit-mf5vk\\", node \\"harvester-node-1\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm2-without-overcommit-mf5vk\\", node \\"harvester-node-1\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" node=\\"harvester-node-1\\"\\n```\\n
\\n\\n**Table 2 - With Overcommit**\\n\\n| VM 1 / VM 2 | harvester-node-0 | harvester-node-1 | harvester-node-2 |\\n|:-------------------------------------:|--------------------------:|------------------------:|------------------------:|\\n| request-cpu (m) | 9022 / 9022 | 4622 / 4622 | **4412** / **4474** |\\n| request-memory | 14807289856 / 14807289856 | 5992960000 / 5992960000 | **5581918208** / **6476701696** |\\n| NodeResourcesBalancedAllocation Score | 0 / 0 | 58 / 58 | **59** / **64** |\\n| NodeResourcesLeastAllocated Score | 5 / 5 | 43 / 43 | **46** / **43** |\\n| Other Scores | 1000354 / 1000354 | 1000354 / 1000354 | 1000354 / 1000354 |\\n| Total Score | 1000359 / 1000359 | 1000455 / 1000455 | **1000459** / **1000461** |\\n\\n**Table 3 - Without Overcommit**\\n\\n| VM 1 / VM 2 | harvester-node-0 | harvester-node-1 | harvester-node-2 |\\n|:-------------------------------------:|--------------------------:|------------------------:|------------------------:|\\n| request-cpu (m) | 9960 / 9960 | 5560 / **5560** | **5350** / 6350 |\\n| request-memory | 15166603264 / 15166603264 | 6352273408 / **6352273408** | **5941231616** / 7195328512 |\\n| NodeResourcesBalancedAllocation Score | 0 / 0 | 45 / **45** | **46** / 0 |\\n| NodeResourcesLeastAllocated Score | 4 / 4 | 34 / **34** | **37** / 28 |\\n| Other Scores | 1000354 / 1000354 | 1000354 / **1000354** | **1000354** / 1000354 |\\n| Total Score | 1000358 / 1000358 | 1000358 / **1000433** | **1000437** / 1000382 |\\n\\n**Table 4**\\n\\n| Score | harvester-node-0 | harvester-node-1 | harvester-node-2 |\\n|:-----:|-----------------:|-----------------:|-----------------:|\\n| VM 1 | 1000359 | 1000455 | 1000459 |\\n| VM 2 | 1000359 | 1000455 | 1000461 |\\n| VM 3 | 1000359 | 1000455 | 1000462 |\\n| VM 4 | 1000359 | 1000455 | 1000462 |\\n| VM 5 | 1000359 | 1000455 | 1000463 |\\n| VM 6 | 1000359 | 1000455 | 1000465 |\\n| VM 7 | 1000359 | 1000455 | 1000466 |\\n| VM 8 | 1000359 | 1000455 | 1000467 |\\n| VM 9 | 1000359 | 1000455 | 1000469 |\\n| VM 10 | 1000359 | 1000455 | 1000469 |\\n| VM 11 | 1000359 | 1000455 | **1000465** |\\n| VM 12 | 1000359 | 1000455 | **1000457** |\\n\\n\\n## How to avoid uneven distribution of VMs?\\n\\nThere are many plugins in `kube-scheduler` which we can use to influence the scores. For example, we can add the `podAntiAffinity` plugin to avoid VMs with the same labels being deployed on the same node.\\n\\n```\\n affinity:\\n podAntiAffinity:\\n preferredDuringSchedulingIgnoredDuringExecution:\\n - podAffinityTerm:\\n labelSelector:\\n matchExpressions:\\n - key: harvesterhci.io/creator\\n operator: Exists\\n topologyKey: kubernetes.io/hostname\\n weight: 100\\n```\\n\\n## How to see scores in kube-scheduler?\\n\\n`kube-scheduler` is deployed as a static pod in Harvester. The file is under `/var/lib/rancher/rke2/agent/pod-manifests/kube-scheduler.yaml` in each Management Node. We can add `- --v=10` to the `kube-scheduler` container to show score logs.\\n\\n```\\nkind: Pod\\nmetadata:\\n labels:\\n component: kube-scheduler\\n tier: control-plane\\n name: kube-scheduler\\n namespace: kube-system\\nspec:\\n containers:\\n - command:\\n - kube-scheduler\\n # ...\\n - --v=10\\n```"}]}')}}]); \ No newline at end of file diff --git a/assets/js/7a1ef0d5.df98e5c9.js b/assets/js/7a1ef0d5.df98e5c9.js deleted file mode 100644 index 531448a9..00000000 --- a/assets/js/7a1ef0d5.df98e5c9.js +++ /dev/null @@ -1 +0,0 @@ -"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[4950],{3287:function(e){e.exports=JSON.parse('{"blogPosts":[{"id":"install_iscsi_firmware_install_boot","metadata":{"permalink":"/kb/install_iscsi_firmware_install_boot","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2024-03-05/booting_harvester_via_iscsi_ibt.md","source":"@site/kb/2024-03-05/booting_harvester_via_iscsi_ibt.md","title":"Configuring Harvester to Boot from an iSCSI Root Disk in Special Circumstances","description":"How to modify GRUB configuration so Harvester will use system firmware to access an iSCSI boot/root disk","date":"2024-03-05T00:00:00.000Z","formattedDate":"March 5, 2024","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"}],"readingTime":10.3,"truncated":false,"authors":[{"name":"Jeff Radick","title":"Staff Software Engineer"}],"frontMatter":{"title":"Configuring Harvester to Boot from an iSCSI Root Disk in Special Circumstances","description":"How to modify GRUB configuration so Harvester will use system firmware to access an iSCSI boot/root disk","slug":"install_iscsi_firmware_install_boot","authors":[{"name":"Jeff Radick","title":"Staff Software Engineer"}],"tags":["harvester"],"hide_table_of_contents":false},"nextItem":{"title":"Mitigating filesystem trim Risk","permalink":"/kb/the_potential_risk_with_filesystem_trim"}},"content":"Through v1.3.0, no explicit support has been provided for using Harvester (installing, booting, and running) with any type of storage that is not locally attached. This is in keeping with the philosophy of Hyper-Converged Infrastructure (HCI), which by definition hosts computational capability, storage, and networking in a single device or a set of similar devices operating in a cluster.\\n\\nHowever, there are certain limited conditions that allow Harvester to be used on nodes without locally-attached bootable storage devices. Specifically, the use of converged network adapters (CNAs) as well as manual changes to the boot loader configuration of the installed system are required.\\n\\n## Concepts, Requirements, and Limitations\\n\\nThis section describes background concepts and outlines requirements and limitations that you must consider before performing the procedure. For more information about the described concepts, see the references listed at the end of this article.\\n\\n### iSCSI Concepts and Terminology\\n\\nSCSI (Small Computer System Interface) is a set of standards for transferring data between computers systems and I/O devices. It is primarily used with storage devices.\\n\\nThe SCSI standards specify the following:\\n- **SCSI protocol**: A set of message formats and rules of exchange\\n- **SCSI transports**: Methods for physically connecting storage devices to the computer system and transferring SCSI messages between them\\n\\nA number of SCSI transports are defined, including the following:\\n- **SAS (Serial Attached SCSI)** and **UAS (USB Attached SCSI)**: Used to access SCSI storage devices that are directly attached to the computers using that storage\\n- **FCP (Fibre Channel Protocol)** and **iSCSI (Internet SCSI)**: Permit computer systems to access storage via a Storage Area Network (SAN), where the storage devices are attached to a system other than the computers using that storage\\n\\nThe SCSI protocol is a client-server protocol, which means that all interaction occurs between clients that send requests and a server that services the requests. In the SCSI context, the client is called the **initiator** and the server is called the **target**. iSCSI initiators and targets identify themselves using a specially formatted identifier called an **iSCSI qualified name (IQN)**. The controller used to provide access to the storage devices is commonly called a **host bus adapter (HBA)**.\\n\\nWhen using iSCSI, access is provided by a traditional Internet protocol, with an extra layer to encapsulate SCSI commands within TCP/IP messages. This can be implemented entirely in software (transferring messages using a traditional NIC), or it can be \\"offloaded\\" to a \\"smart\\" NIC that contains the iSCSI protocol and provides access through special firmware. Such NICs, which provide both a traditional Ethernet interface for regular Internet traffic and a higher-level storage interface for iSCSI services, are often called **converged network adapters (CNAs)**.\\n\\nSystems with iSCSI CNAs can be configured to enable the system bootstrap firmware to boot the system via iSCSI. In addition, if the loaded operating system is aware of such an interface provided by the CNA, it can access the bootstrap device using that firmware interface *as if it were a locally attached device* without requiring initialization of the operating system\'s full software iSCSI protocol machinery.\\n\\n### Additional Concepts and Terminology\\n\\nHarvester must be installed on a bootable storage device, which is referred to as the *boot disk*.\\n\\nOther storage devices, which are referred to as *non-boot disks*, may also be used in the Harvester ecosystem.\\n\\n### Requirements\\n\\nYou must install Harvester on a node with a converged NIC that provides iSCSI offload capability with firmware support. This firmware must specifically support the iSCSI Boot Firmware Table (iBFT).\\n\\n:::note\\nThe procedure was tested with the following:\\n- Harvester v1.2.1 and v1.3.0\\n- Dell PowerEdge R650 (Other systems with comparable hardware and firmware iSCSI support may also be suitable.)\\n:::\\n\\n### Limitations\\n\\nThe procedure will not work in environments with the following conditions:\\n\\n- iSCSI is not implemented in a converged NIC.\\n- Nodes boot via PXE.\\n- Harvester is installed only on virtual machines.\\n\\n## Procedure\\n\\nThe following is a summary of the procedure. Individual steps, which are described in the following sections, must be performed interactively. A fully automated installation is **not** possible at this time.\\n\\n1. Provision storage for your Harvester node on your iSCSI server system.\\n1. Configure system firmware to boot via iSCSI using the available CNA.\\n1. Boot the Harvester install image and install to the iSCSI device.\\n1. On first Harvester boot after installation, edit the kernel boot parameters in the GRUB kernel command line.\\n1. Permanently edit the GRUB configuration file in the normally read-only partition.\\n\\n:::info important\\nThe boot configuration changes will persist across node reboots but **not** across system upgrades, which will overwrite the GRUB parameters. \\n:::\\n\\n### 1. Provision storage for your Harvester node on your iSCSI server system.\\n\\nBefore attempting to install Harvester onto a disk accessed by iSCSI,\\nthe storage must first be provisioned on the storage server.\\n\\nThe details depend on the storage server and will not be discussed here.\\n\\nHowever, several pieces of information must be obtained\\nin order for the system being installed to be able\\nto access the storage using iSCSI.\\n\\n* The IP address and port number of the iSCSI server.\\n* The iSCSI Qualified Name (IQN) of the iSCSI target on the server.\\n* The LUN of the volume on the server to be accessed from the client as the disk on which Harvester will be installed.\\n* Depending on on how the server is administered, authentication parameters may also be required.\\n\\nThese items of information will be determined by the server system.\\n\\nIn addition, an IQN must be chosen for the client system to be used as its initiator identifier.\\n\\nAn IQN is a string in a certain format.\\nIn general, any string in the defined format can be used as long as it is unique.\\nHowever, specific environments may place stricter requirements on the choice of names.\\n\\nThe format of an IQN is illustrated in the following example:\\n\\n```\\n iqn.2024-02.com.example:cluster1-node0-boot-disk\\n```\\n\\nThere are lots of variations of this format, and this is just an example.\\n\\nThe correct name to use should be chosen in consultation with the administrator of your storage server and storage area network.\\n\\n### 2. Configure system firmware to boot via iSCSI using the available CNA.\\n\\nWhen your system to be installed powers on or is reset, you must enter the firmware setup menu to change the boot settings and enable booting via iSCSI.\\n\\nPrecise details for this are difficult to provide because they vary from system to system.\\n\\nIt is typical to force the system to enter the firmware settings menu by typing a special key such as F2, F7, ESC, etc.\\nWhich one works for your system varies.\\nOften the system will display a list of which key(s) are available for specific firmware functions,\\nbut it is not uncommon for the firmware to erase this list and start to boot after only a very short delay,\\nso you have to pay close attention.\\n\\nIf in doubt, consult the system provider\'s documentation.\\nAn example document link is provided in the References section.\\nOther vendors should provide similar documentation.\\n\\nThe typical things you need to configure are:\\n* Enable UEFI boot\\n* Configure iSCSI initiator and target parameters\\n* Enable the iSCSI device in the boot menu\\n* Set the boot order so that your system will boot from the iSCSI device\\n\\n### Boot the Harvester install image and install to the iSCSI device\\n\\nThis can be done by whatever means you would normally use to load the Harvester install image.\\n\\nThe Harvester installer _should_ automatically \\"see\\" the iSCSI device in the dialog where you chose the installation destination.\\nChoose this device to install.\\n\\nInstallation should proceed and complete normally.\\n\\nWhen installation completes, your system should reboot.\\n\\n### 4. On first boot, edit kernel boot parameters in the GRUB kernel command line.\\n\\nAs your system starts to come up after the first reboot,\\nthe firmware will load the boot loader (GRUB) from the iSCSI device,\\nand GRUB will be able to use this device to load the kernel.\\n\\nHowever, the kernel will **not** be aware of the iSCSI boot disk **unless** you modify the kernel parameters in the GRUB command line.\\n\\nIf you don\'t modify the kernel parameters, then system startup procedures will fail to find the `COS_OEM` and other paritions on the boot disk,\\nand it will be unable to access the `cloud-init` configuration or any of the container images needed to \\n\\nThe first time the GRUB menu appears after installation, you should stop the GRUB boot loader from automatically loading the kernel,\\nand edit the kernel command line.\\n\\nTo stop GRUB from automatically loading the kernel, hit the ESC key as soon as the menu appears.\\nYou will only have a few seconds to do this before the system automatically boots.\\n\\nThen, type \\"e\\" to edit the GRUB configuration for the first boot option.\\n\\nIt will show you something similar to the following:\\n\\n```\\nsetparams \'Harvester v1.3.0\'\\n\\n # label is kept around for backward compatibility\\n set label=${active_label}\\n set img=/cOS/active.img\\n loopback $loopdev /$img\\n source $(loopdev)/etc/cos/bootargs.cfg\\n linux ($loopdev)$kernel $kernelcmd ${extra_cmdline} ${extra_active_cmdline}\\n initrd ($loopdev)$initramfs\\n```\\n\\nMove the cursor down to the line that begins with `linux`, and move the cursor to the end of that line.\\n\\nAppend the following string (two parameters): `rd.iscsi.firmware rd.iscsi.ibft`.\\n\\nThe line beginning with `linux` should now look like this:\\n\\n```\\n linux ($loopdev)$kernel $kernelcmd ${extra_cmdline} ${extra_active_cmdline} rd.iscsi.firmware rd.iscsi.ibft\\n```\\n\\nAt this point, type Ctrl-X to resume booting with the modified kernel command line.\\n\\nNow the node should come up normally, and finish with the normal Harvester console screen that shows the cluster and node IP addresses and status.\\n\\nThe the node should operate normally now **but** the kernel boot argument changes will not be preserved across a reboot unless you perform the next step.\\n\\n### 5. Permanently edit the GRUB configuration file.\\n\\nAt this point you need to preserve these boot argument changes.\\n\\nYou can do this from the console by pressing F12 and logging in, or you can use an SSH session over the network.\\n\\nThe changes must be made permanent by editing the GRUB configuration file `grub.cfg`.\\n\\nThe trick here is that the file to be changed is stored in a partition which is normally **read-only**,\\nso the first thing you must do is to re-mount the volume to be read-write.\\n\\nStart out by using the `blkid` command to find the device name of the correct partition:\\n\\n```\\n $ sudo -i\\n # blkid -L COS_STATE\\n /dev/sda4\\n #\\n```\\n\\nThe device name will be something like `/dev/sda4`. The following examples assume that\'s the name but you should modify the commands to match what you see on your system.\\n\\nNow, re-mount that volume to make it writable:\\n\\n```shell\\n # mount -o remount -rw /dev/sda4 /run/initramfs/cos-state\\n```\\n\\nNext, edit the `grub.cfg` file.\\n\\n```shell\\n # vim /run/initramfs/cos-state/grub2/grub.cfg\\n```\\n\\nLook for `menuentry` directives. There will be several of these; at least one as a fallback, and one for recovery. You should apply the same change to all of them.\\n\\nIn each of these, edit the line beginning with `linux` just as you did for the interactive GRUB menu, appending ` rd.iscsi.firmware rd.iscsi.ibft` to the arguments.\\n\\nThen save the changes.\\n\\nIt is not necessary, but probably advisable to remount that volume again to return it to its read-only state:\\n\\n```shell\\n # mount -o remount -ro /dev/sda4 /run/initramfs/cos-state\\n```\\n\\nFrom this point on, these changes will persist across node reboots.\\n\\nA few important notes:\\n\\n* You must perform this same procedure for every node of your cluster that you are booting with iSCSI.\\n* These changes will be overwritten by the upgrade procedure if you upgrade your cluster to a newer version of Harvester. Therefore, if you do an upgrade, be sure to re-do the procedure to edit the `grub.cfg` on every node of your cluster that is booting by iSCSI.\\n\\n\\n## References\\n\\n- [SCSI](https://en.wikipedia.org/wiki/SCSI) provides an overview of SCSI and contains references to additional material.\\n- [iSCSI](https://en.wikipedia.org/wiki/ISCSI) provides an overview of iSCSI and contains references to additional material.\\n- [Converged Network Adapter](https://en.wikipedia.org/wiki/Converged_network_adapter) provides a summary of CNAs and references to additional material.\\n- [Harvester Docuementation](https://docs.harvesterhci.io/v1.2/troubleshooting/os/#how-to-permanently-edit-kernel-parameters) provides a general description of how to permanently edit kernel parameters to be used when booting a Harvester node.\\n- [Dell PowerEdge R630 Owner\'s Manual](https://www.dell.com/support/manuals/en-us/poweredge-r630/r630_om_pub/uefi-iscsi-settings?guid=guid-adc7d625-5c7b-469d-ba9c-4a2c704fcc49&lang=en-us) This is an example of relevant vendor documentation. Other vendors such as HPE, IBM, Lenovo, etc should provide comparable documentation, though the details will vary."},{"id":"the_potential_risk_with_filesystem_trim","metadata":{"permalink":"/kb/the_potential_risk_with_filesystem_trim","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2024-01-30/the_potential_risk_with_fstrim.md","source":"@site/kb/2024-01-30/the_potential_risk_with_fstrim.md","title":"Mitigating filesystem trim Risk","description":"The potential risk with filesystem trim and how to avoid it","date":"2024-01-30T00:00:00.000Z","formattedDate":"January 30, 2024","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"rancher integration","permalink":"/kb/tags/rancher-integration"},{"label":"longhorn","permalink":"/kb/tags/longhorn"},{"label":"filesystem trim","permalink":"/kb/tags/filesystem-trim"}],"readingTime":2.9,"truncated":false,"authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"frontMatter":{"title":"Mitigating filesystem trim Risk","description":"The potential risk with filesystem trim and how to avoid it","slug":"the_potential_risk_with_filesystem_trim","authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"tags":["harvester","rancher integration","longhorn","filesystem trim"],"hide_table_of_contents":false},"prevItem":{"title":"Configuring Harvester to Boot from an iSCSI Root Disk in Special Circumstances","permalink":"/kb/install_iscsi_firmware_install_boot"},"nextItem":{"title":"Calculation of Resource Metrics in Harvester","permalink":"/kb/calculation_of_resource_metrics_in_harvester"}},"content":":::note\\nThis issue is already resolved by Longhorn v1.5.4, v1.6.1, v1.7.0 and later versions.\\n:::\\n\\n\\nFilesystem trim is a common way to release unused space in a filesystem. However, this operation is known to cause IO errors when used with Longhorn volumes that are rebuilding. For more information about the errors, see the following issues:\\n\\n- Harvester: [Issue 4793](https://github.com/harvester/harvester/issues/4739)\\n- Longhorn: [Issue 7103](https://github.com/longhorn/longhorn/issues/7103)\\n\\n## Risks Associated with Filesystem Trim\\n\\nA consequence of the IO errors caused by filesystem trim is that VMs using affected Longhorn volumes become stuck. Imagine the VM is running critical applications, then becomes unavailable. This is significant because Harvester typically uses Longhorn volumes as VM disks. The IO errors will cause VMs to flap between running and paused states until volume rebuilding is completed.\\n\\nAlthough the described system behavior does not affect data integrity, it might induce panic in some users. Consider the guest Kubernetes cluster scenario. In a stuck VM, the etcd service is unavailable. The effects of this failure cascade from the Kubernetes cluster becoming unavailable to services running on the cluster becoming unavailable.\\n\\n## How to Check If Filesystem Trim Is Enabled\\n\\n### Linux\\n\\nIn most Linux distributions, filesystem trim is enabled by default. You can check if the related service fstrim is enabled by running the following command:\\n\\n\\n```\\n$ systemctl status fstrim.timer\\n\u25cf fstrim.timer - Discard unused blocks once a week\\n Loaded: loaded (/lib/systemd/system/fstrim.timer; enabled; vendor preset: enabled)\\n Active: active (waiting) since Mon 2024-03-18 03:40:24 UTC; 1 week 1 day ago\\n Trigger: Mon 2024-04-01 01:00:06 UTC; 5 days left\\n Triggers: \u25cf fstrim.service\\n Docs: man:fstrim\\n\\nMar 18 03:40:24 harvester-cluster-01-pool1-49b619f6-tpc4v systemd[1]: Started Discard unused blocks once a week.\\n```\\n\\nWhen the fstrim.timer service is enabled, the system periodically runs fstrim.\\n\\n### Windows\\n\\nYou can check if filesystem trim is enabled by running the following command:\\n\\n```\\nC:\\\\> fsutil behavior query DisableDeleteNotify\\nNTFS DisableDeleteNotify = 0 (Allows TRIM operations to be sent to the storage device)\\nReFS DisableDeleteNotify = 0 (Allows TRIM operations to be sent to the storage device)\\n```\\n\\n`DisableDeleteNotify = 0` indicates that TRIM operations are enabled. For more information, see [fsutil behavior](https://docs.microsoft.com/en-us/windows-server/administration/windows-commands/fsutil-behavior) in the Microsoft documentation.\\n\\n## Risk Mitigation\\n\\n### Linux\\n\\nOne way to mitigate the described risks is to disable fstrim services in VMs. fstrim services is enabled by default in many modern Linux distributions.\\nYou can determine if fstrim is enabled in VMs that use affected Longhorn volumes by checking the following:\\n\\n - `/etc/fstab`: Some root filesystems mount with the *discard* option.\\n\\n Example:\\n ```\\n /dev/mapper/rootvg-rootlv / xfs defaults,discard 0 0\\n ```\\n \\n You can disable fstrim on the root filesystem by removing the *discard* option.\\n ```\\n /dev/mapper/rootvg-rootlv / xfs defaults 0 0 <-- remove the discard option\\n ```\\n \\n After removing the *discard* option, you can remount the root filesystem using the command `mount -o remount /` or by rebooting the VM.\\n\\n - `fstrim.timer`: When this service is enabled, fstrim executes weekly by default. You can either disable the service or edit the service file to prevent simultaneous fstrim execution on VMs.\\n\\n You can disable the service using the following command:\\n ```\\n systemctl disable fstrim.timer\\n ```\\n\\n To prevent simultaneous fstrim execution, use the following values in the service file (located at `/usr/lib/systemd/system/fstrim.timer`):\\n ```\\n [Timer]\\n OnCalendar=weekly\\n AccuracySec=1h\\n Persistent=true\\n RandomizedDelaySec=6000\\n ```\\n\\n### Windows\\n\\nTo mitigate the described risks, you can disable TRIM operations using the following commands:\\n\\n- ReFS v2\\n ```\\n C:\\\\> fsutil behavior set DisableDeleteNotify ReFS 1\\n ```\\n\\n- NTFS and ReFS v1\\n ```\\n C:\\\\> fsutil behavior set DisableDeleteNotify 1\\n ```"},{"id":"calculation_of_resource_metrics_in_harvester","metadata":{"permalink":"/kb/calculation_of_resource_metrics_in_harvester","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2024-01-23/harvester_resource_metrics_calculation.md","source":"@site/kb/2024-01-23/harvester_resource_metrics_calculation.md","title":"Calculation of Resource Metrics in Harvester","description":"Understand how resource metrics are calculated.","date":"2024-01-23T00:00:00.000Z","formattedDate":"January 23, 2024","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"resource metrics","permalink":"/kb/tags/resource-metrics"},{"label":"reserved resource","permalink":"/kb/tags/reserved-resource"},{"label":"calculation","permalink":"/kb/tags/calculation"}],"readingTime":2.835,"truncated":false,"authors":[{"name":"Jian Wang","title":"Staff Software Engineer","url":"https://github.com/w13915984028","image_url":"https://github.com/w13915984028.png","imageURL":"https://github.com/w13915984028.png"}],"frontMatter":{"title":"Calculation of Resource Metrics in Harvester","description":"Understand how resource metrics are calculated.","slug":"calculation_of_resource_metrics_in_harvester","authors":[{"name":"Jian Wang","title":"Staff Software Engineer","url":"https://github.com/w13915984028","image_url":"https://github.com/w13915984028.png","imageURL":"https://github.com/w13915984028.png"}],"tags":["harvester","resource metrics","reserved resource","calculation"],"hide_table_of_contents":false},"prevItem":{"title":"Mitigating filesystem trim Risk","permalink":"/kb/the_potential_risk_with_filesystem_trim"},"nextItem":{"title":"Best Practices for Optimizing Longhorn Disk Performance","permalink":"/kb/best_practices_for_optimizing_longhorn_disk_performance"}},"content":"Harvester calculates the resource metrics using data that is dynamically collected from the system. Host-level resource metrics are calculated and then aggregated to obtain the cluster-level metrics.\\n\\nYou can view resource-related metrics on the Harvester UI.\\n\\n- **Hosts** screen: Displays host-level metrics\\n\\n ![host level resources metrics](./imgs/host-resource-usage.png)\\n\\n- **Dashboard** screen: Displays cluster-level metrics\\n\\n ![cluster level resources metrics](./imgs/cluster-resource-usage.png)\\n\\n## CPU and Memory\\n\\nThe following sections describe the data sources and calculation methods for CPU and memory resources.\\n\\n- Resource capacity: Baseline data\\n- Resource usage: Data source for the **Used** field on the **Hosts** screen\\n- Resource reservation: Data source for the **Reserved** field on the **Hosts** screen\\n\\n### Resource Capacity \\n\\nIn Kubernetes, a `Node` object is created for each host.\\n\\nThe `.status.allocatable.cpu` and `.status.allocatable.memory` represent the available CPU and Memory resources of a host.\\n\\n```\\n# kubectl get nodes -A -oyaml\\napiVersion: v1\\nitems:\\n- apiVersion: v1\\n kind: Node\\n metadata:\\n..\\n management.cattle.io/pod-limits: \'{\\"cpu\\":\\"12715m\\",\\"devices.kubevirt.io/kvm\\":\\"1\\",\\"devices.kubevirt.io/tun\\":\\"1\\",\\"devices.kubevirt.io/vhost-net\\":\\"1\\",\\"memory\\":\\"17104951040\\"}\'\\n management.cattle.io/pod-requests: \'{\\"cpu\\":\\"5657m\\",\\"devices.kubevirt.io/kvm\\":\\"1\\",\\"devices.kubevirt.io/tun\\":\\"1\\",\\"devices.kubevirt.io/vhost-net\\":\\"1\\",\\"ephemeral-storage\\":\\"50M\\",\\"memory\\":\\"9155862208\\",\\"pods\\":\\"78\\"}\'\\n node.alpha.kubernetes.io/ttl: \\"0\\"\\n..\\n name: harv41\\n resourceVersion: \\"2170215\\"\\n uid: b6f5850a-2fbc-4aef-8fbe-121dfb671b67\\n spec:\\n podCIDR: 10.52.0.0/24\\n podCIDRs:\\n - 10.52.0.0/24\\n providerID: rke2://harv41\\n status:\\n addresses:\\n - address: 192.168.122.141\\n type: InternalIP\\n - address: harv41\\n type: Hostname\\n allocatable:\\n cpu: \\"10\\"\\n devices.kubevirt.io/kvm: 1k\\n devices.kubevirt.io/tun: 1k\\n devices.kubevirt.io/vhost-net: 1k\\n ephemeral-storage: \\"149527126718\\"\\n hugepages-1Gi: \\"0\\"\\n hugepages-2Mi: \\"0\\"\\n memory: 20464216Ki\\n pods: \\"200\\"\\n capacity:\\n cpu: \\"10\\"\\n devices.kubevirt.io/kvm: 1k\\n devices.kubevirt.io/tun: 1k\\n devices.kubevirt.io/vhost-net: 1k\\n ephemeral-storage: 153707984Ki\\n hugepages-1Gi: \\"0\\"\\n hugepages-2Mi: \\"0\\"\\n memory: 20464216Ki\\n pods: \\"200\\"\\n```\\n\\n### Resource Usage\\n\\nCPU and memory usage data is continuously collected and stored in the `NodeMetrics` object. Harvester reads the data from `usage.cpu` and `usage.memory`.\\n\\n```\\n# kubectl get NodeMetrics -A -oyaml\\napiVersion: v1\\nitems:\\n- apiVersion: metrics.k8s.io/v1beta1\\n kind: NodeMetrics\\n metadata:\\n...\\n name: harv41\\n timestamp: \\"2024-01-23T12:04:44Z\\"\\n usage:\\n cpu: 891736742n\\n memory: 9845008Ki\\n window: 10.149s\\n```\\n\\n### Resource Reservation\\n\\nHarvester dynamically calculates the resource limits and requests of all pods running on a host, and updates the information to the annotations of the `NodeMetrics` object.\\n\\n```\\n management.cattle.io/pod-limits: \'{\\"cpu\\":\\"12715m\\",...,\\"memory\\":\\"17104951040\\"}\'\\n management.cattle.io/pod-requests: \'{\\"cpu\\":\\"5657m\\",...,\\"memory\\":\\"9155862208\\"}\'\\n```\\n\\nFor more information, see [Requests and Limits](https://kubernetes.io/docs/concepts/configuration/manage-resources-containers/#requests-and-limits) in the Kubernetes documentation.\\n\\n## Storage\\n\\nLonghorn is the default Container Storage Interface (CSI) driver of Harvester, providing storage management features such as distributed block storage and tiering.\\n\\n### Reserved Storage in Longhorn\\n\\nLonghorn allows you to specify the percentage of disk space that is not allocated to the default disk on each new Longhorn node. The default value is \\"30\\". For more information, see [Storage Reserved Percentage For Default Disk](https://longhorn.io/docs/1.5.3/references/settings/#storage-reserved-percentage-for-default-disk) in the Longhorn documentation.\\n\\nDepending on the disk size, you can modify the default value using the [embedded Longhorn UI](https://docs.harvesterhci.io/v1.2/troubleshooting/harvester/#access-embedded-rancher-and-longhorn-dashboards).\\n\\n:::note\\n\\nBefore changing the settings, read the Longhorn documentation carefully.\\n\\n:::\\n\\n### Data Sources and Calculation\\n\\nHarvester uses the following data to calculate metrics for storage resources.\\n\\n- Sum of the `storageMaximum` values of all disks (`status.diskStatus.disk-name`): Total storage capacity\\n\\n- Total storage capacity - Sum of the `storageAvailable` values of all disks (`status.diskStatus.disk-name`): Data source for the **Used** field on the **Hosts** screen\\n\\n- Sum of the `storageReserved` values of all disks (`spec.disks`): Data source for the **Reserved** field on the **Hosts** screen\\n\\n```\\n# kubectl get nodes.longhorn.io -n longhorn-system -oyaml\\n\\napiVersion: v1\\nitems:\\n- apiVersion: longhorn.io/v1beta2\\n kind: Node\\n metadata:\\n..\\n name: harv41\\n namespace: longhorn-system\\n..\\n spec:\\n allowScheduling: true\\n disks:\\n default-disk-ef11a18c36b01132:\\n allowScheduling: true\\n diskType: filesystem\\n evictionRequested: false\\n path: /var/lib/harvester/defaultdisk\\n storageReserved: 24220101427\\n tags: []\\n..\\n status:\\n..\\n diskStatus:\\n default-disk-ef11a18c36b01132:\\n..\\n diskType: filesystem\\n diskUUID: d2788933-8817-44c6-b688-dee414cc1f73\\n scheduledReplica:\\n pvc-95561210-c39c-4c2e-ac9a-4a9bd72b3100-r-20affeca: 2147483648\\n pvc-9e83b2dc-6a4b-4499-ba70-70dc25b2d9aa-r-4ad05c86: 32212254720\\n pvc-bc25be1e-ca4e-4818-a16d-48353a0f2f96-r-c7b88c60: 3221225472\\n pvc-d9d3e54d-8d67-4740-861e-6373f670f1e4-r-f4c7c338: 2147483648\\n pvc-e954b5fe-bbd7-4d44-9866-6ff6684d5708-r-ba6b87b6: 5368709120\\n storageAvailable: 77699481600\\n storageMaximum: 80733671424\\n storageScheduled: 45097156608\\n region: \\"\\"\\n snapshotCheckStatus: {}\\n zone: \\"\\"\\n```"},{"id":"best_practices_for_optimizing_longhorn_disk_performance","metadata":{"permalink":"/kb/best_practices_for_optimizing_longhorn_disk_performance","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-12-27/best_practices_disk_performance.md","source":"@site/kb/2023-12-27/best_practices_disk_performance.md","title":"Best Practices for Optimizing Longhorn Disk Performance","description":"Follow the recommendations for achieving optimal disk performance.","date":"2023-12-27T00:00:00.000Z","formattedDate":"December 27, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"longhorn","permalink":"/kb/tags/longhorn"},{"label":"best practices","permalink":"/kb/tags/best-practices"},{"label":"disk performance","permalink":"/kb/tags/disk-performance"}],"readingTime":1.585,"truncated":false,"authors":[{"name":"David Ko","title":"Senior Software Engineering Manager","url":"https://github.com/innobead","image_url":"https://github.com/innobead.png","imageURL":"https://github.com/innobead.png"},{"name":"Jillian Maroket","title":"Technical Writer","url":"https://github.com/jillian-maroket/","image_url":"https://github.com/jillian-maroket.png","imageURL":"https://github.com/jillian-maroket.png"}],"frontMatter":{"title":"Best Practices for Optimizing Longhorn Disk Performance","description":"Follow the recommendations for achieving optimal disk performance.","slug":"best_practices_for_optimizing_longhorn_disk_performance","authors":[{"name":"David Ko","title":"Senior Software Engineering Manager","url":"https://github.com/innobead","image_url":"https://github.com/innobead.png","imageURL":"https://github.com/innobead.png"},{"name":"Jillian Maroket","title":"Technical Writer","url":"https://github.com/jillian-maroket/","image_url":"https://github.com/jillian-maroket.png","imageURL":"https://github.com/jillian-maroket.png"}],"tags":["harvester","longhorn","best practices","disk performance"],"hide_table_of_contents":false},"prevItem":{"title":"Calculation of Resource Metrics in Harvester","permalink":"/kb/calculation_of_resource_metrics_in_harvester"},"nextItem":{"title":"VM Live Migration Policy and Configuration","permalink":"/kb/vm_live_migration_policy_and_configuration"}},"content":"The Longhorn documentation provides [best practice recommendations](https://longhorn.io/docs/1.5.3/best-practices/) for deploying Longhorn in production environments. Before configuring workloads, ensure that you have set up the following basic requirements for optimal disk performance.\\n\\n- SATA/NVMe SSDs or disk drives with similar performance\\n- 10 Gbps network bandwidth between nodes\\n- Dedicated Priority Classes for system-managed and user-deployed Longhorn components\\n\\nThe following sections outline other recommendations for achieving optimal disk performance.\\n\\n## IO Performance\\n\\n- **Storage network**: Use a [dedicated storage network](https://docs.harvesterhci.io/v1.2/advanced/storagenetwork) to improve IO performance and stability. \\n\\n- **Longhorn disk**: Use a [dedicated disk](https://docs.harvesterhci.io/v1.2/host/#multi-disk-management) for Longhorn storage instead of using the root disk. \\n\\n- **Replica count**: Set the [default replica count](https://docs.harvesterhci.io/v1.2/advanced/storageclass#parameters-tab) to \\"2\\" to achieve data availability with better disk space usage or less impact to system performance. This practice is especially beneficial to data-intensive applications. \\n\\n- **Storage tag**: Use storage tags to define storage tiering for data-intensive applications. For example, only high-performance disks can be used for storing performance-sensitive data. You can either [add disks with tags](https://docs.harvesterhci.io/v1.2/host/#storage-tags) or [create StorageClasses with tags](https://docs.harvesterhci.io/v1.2/advanced/storageclass#disk-selector-optional). \\n\\n- **Data locality**: Use `best-effort` as the default [data locality](https://longhorn.io/docs/1.5.3/high-availability/data-locality/) of Longhorn Storage Classes. \\n\\n For applications that support data replication (for example, a distributed database), you can use the `strict-local` option to ensure that only one replica is created for each volume. This practice prevents the extra disk space usage and IO performance overhead associated with volume replication. \\n\\n For data-intensive applications, you can use pod scheduling functions such as node selector or taint toleration. These functions allow you to schedule the workload to a specific storage-tagged node together with one replica. \\n\\n## Space Efficiency \\n\\n- **Recurring snapshots**: Periodically clean up system-generated snapshots and retain only the number of snapshots that makes sense for your implementation. \\n\\n For applications with replication capability, periodically [delete all types of snapshots](https://longhorn.io/docs/1.5.3/concepts/#243-deleting-snapshots).\\n\\n## Disaster Recovery\\n\\n- **Recurring backups**: Create [recurring backup jobs](https://longhorn.io/docs/1.5.3/volumes-and-nodes/trim-filesystem/) for mission-critical application volumes.\\n\\n- **System backup**: Run periodic system backups."},{"id":"vm_live_migration_policy_and_configuration","metadata":{"permalink":"/kb/vm_live_migration_policy_and_configuration","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-09-01/vm_live_migration_policy_and_configuration.md","source":"@site/kb/2023-09-01/vm_live_migration_policy_and_configuration.md","title":"VM Live Migration Policy and Configuration","description":"Know how VM live migration works, the migration policies, how to tune the policies and check status","date":"2023-09-01T00:00:00.000Z","formattedDate":"September 1, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"virtual machine","permalink":"/kb/tags/virtual-machine"},{"label":"VM","permalink":"/kb/tags/vm"},{"label":"live migration","permalink":"/kb/tags/live-migration"},{"label":"policy","permalink":"/kb/tags/policy"},{"label":"strategy","permalink":"/kb/tags/strategy"},{"label":"configuration","permalink":"/kb/tags/configuration"}],"readingTime":10.58,"truncated":false,"authors":[{"name":"Jian Wang","title":"Staff Software Engineer","url":"https://github.com/w13915984028","image_url":"https://github.com/w13915984028.png","imageURL":"https://github.com/w13915984028.png"}],"frontMatter":{"title":"VM Live Migration Policy and Configuration","description":"Know how VM live migration works, the migration policies, how to tune the policies and check status","slug":"vm_live_migration_policy_and_configuration","authors":[{"name":"Jian Wang","title":"Staff Software Engineer","url":"https://github.com/w13915984028","image_url":"https://github.com/w13915984028.png","imageURL":"https://github.com/w13915984028.png"}],"tags":["harvester","virtual machine","VM","live migration","policy","strategy","configuration"],"hide_table_of_contents":false},"prevItem":{"title":"Best Practices for Optimizing Longhorn Disk Performance","permalink":"/kb/best_practices_for_optimizing_longhorn_disk_performance"},"nextItem":{"title":"Use Rook Ceph External Storage with Harvester","permalink":"/kb/use_rook_ceph_external_storage"}},"content":"In Harvester, the **VM Live Migration** is well supported by the UI. Please refer to [Harvester VM Live Migration](https://docs.harvesterhci.io/v1.1/vm/live-migration) for more details.\\n\\nThe VM Live Migration process is finished smoothly in most cases. However, sometimes the migration may get stuck and not end as expected.\\n\\nThis article dives into the VM Live Migration process in more detail. There are three main parts:\\n\\n- General Process of VM Live Migration\\n- VM Live Migration Strategies\\n- VM Live Migration Configurations\\n\\nRelated issues:\\n\\n- [Migration should show the proper status and progress in the UI](https://github.com/harvester/harvester/issues/4352)\\n- [VM Migration policy and status](https://github.com/harvester/harvester/issues/4376)\\n\\n:::note\\n\\nA big part of the following contents are copied from `kubevirt` document https://kubevirt.io/user-guide/operations/live_migration/, some contents/formats are adjusted to fit in this document.\\n\\n:::\\n\\n## General Process of VM Live Migration\\n\\n### Starting a Migration from Harvester UI\\n\\n1. Go to the **Virtual Machines** page.\\n1. Find the virtual machine that you want to migrate and select **\u22ee** > **Migrate**.\\n1. Choose the node to which you want to migrate the virtual machine and select **Apply**.\\n\\nAfter successfully selecting **Apply**, a CRD `VirtualMachineInstanceMigration` object is created, and the related `controller/operator` will start the process.\\n\\n### Migration CRD Object\\n\\nYou can also create the CRD `VirtualMachineInstanceMigration` object manually via `kubectl` or other tools.\\n\\nThe example below starts a migration process for a virtual machine instance (VMI) `new-vm`.\\n\\n```\\napiVersion: kubevirt.io/v1\\nkind: VirtualMachineInstanceMigration\\nmetadata:\\n name: migration-job\\nspec:\\n vmiName: new-vm\\n```\\n\\nUnder the hood, the open source projects `Kubevirt, Libvirt, QEMU, ... ` perform most of the `VM Live Migration`. [References.](#references)\\n\\n### Migration Status Reporting\\n\\nWhen starting a virtual machine instance (VMI), it has also been calculated whether the machine is live migratable. The result is being stored in the VMI `VMI.status.conditions`. The calculation can be based on multiple parameters of the VMI, however, at the moment, the calculation is largely based on the Access Mode of the VMI volumes. Live migration is only permitted when the volume access mode is set to ReadWriteMany. Requests to migrate a non-LiveMigratable VMI will be rejected.\\n\\nThe reported Migration Method is also being calculated during VMI start. `BlockMigration` indicates that some of the VMI disks require copying from the source to the destination. `LiveMigration` means that only the instance memory will be copied.\\n\\n```\\nStatus:\\n Conditions:\\n Status: True\\n Type: LiveMigratable\\n Migration Method: BlockMigration\\n```\\n\\n### Migration Status\\n\\nThe migration progress status is reported in `VMI.status`. Most importantly, it indicates whether the migration has been completed or failed.\\n\\nBelow is an example of a successful migration.\\n\\n```\\nMigration State:\\n Completed: true\\n End Timestamp: 2019-03-29T03:37:52Z\\n Migration Config:\\n Completion Timeout Per GiB: 800\\n Progress Timeout: 150\\n Migration UID: c64d4898-51d3-11e9-b370-525500d15501\\n Source Node: node02\\n Start Timestamp: 2019-03-29T04:02:47Z\\n Target Direct Migration Node Ports:\\n 35001: 0\\n 41068: 49152\\n 38284: 49153\\n Target Node: node01\\n Target Node Address: 10.128.0.46\\n Target Node Domain Detected: true\\n Target Pod: virt-launcher-testvmimcbjgw6zrzcmp8wpddvztvzm7x2k6cjbdgktwv8tkq\\n```\\n\\n## VM Live Migration Strategies\\n\\nVM Live Migration is a process during which a running Virtual Machine Instance moves to another compute node while the guest workload continues to run and remain accessible.\\n\\n### Understanding Different VM Live Migration Strategies\\n\\nVM Live Migration is a complex process. During a migration, the source VM needs to transfer its whole state (mainly RAM) to the target VM. If there are enough resources available, such as network bandwidth and CPU power, migrations should converge nicely. If this is not the scenario, however, the migration might get stuck without an ability to progress.\\n\\nThe main factor that affects migrations from the guest perspective is its dirty rate, which is the rate by which the VM dirties memory. Guests with high dirty rate lead to a race during migration. On the one hand, memory would be transferred continuously to the target, and on the other, the same memory would get dirty by the guest. On such scenarios, one could consider to use more advanced migration strategies. Refer to [Understanding different migration strategies](https://kubevirt.io/user-guide/operations/live_migration/#understanding-different-migration-strategies) for more details.\\n\\nThere are 3 `VM Live Migration` strategies/policies:\\n\\n#### VM Live Migration Strategy: Pre-copy\\n\\nPre-copy is the default strategy. It should be used for most cases.\\n\\nThe way it works is as following:\\n1. The target VM is created, but the guest keeps running on the source VM.\\n1. The source starts sending chunks of VM state (mostly memory) to the target. This continues until all of the state has been transferred to the target.\\n1. The guest starts executing on the target VM. 4. The source VM is being removed.\\n\\nPre-copy is the safest and fastest strategy for most cases. Furthermore, it can be easily cancelled, can utilize multithreading, and more. If there is no real reason to use another strategy, this is definitely the strategy to go with.\\n\\nHowever, on some cases migrations might not converge easily, that is, by the time the chunk of source VM state would be received by the target VM, it would already be mutated by the source VM (which is the VM the guest executes on). There are many reasons for migrations to fail converging, such as a high dirty-rate or low resources like network bandwidth and CPU. On such scenarios, see the following alternative strategies below.\\n\\n#### VM Live Migration Strategy: Post-copy\\n\\nThe way post-copy migrations work is as following:\\n1. The target VM is created.\\n1. The guest is being run on the target VM.\\n1. The source starts sending chunks of VM state (mostly memory) to the target.\\n1. When the guest, running on the target VM, would access memory: 1. If the memory exists on the target VM, the guest can access it. 2. Otherwise, the target VM asks for a chunk of memory from the source VM.\\n1. Once all of the memory state is updated at the target VM, the source VM is being removed.\\n\\nThe main idea here is that the guest starts to run immediately on the target VM. This approach has advantages and disadvantages:\\n\\n**Advantages:**\\n\\n- The same memory chink is never being transferred twice. This is possible due to the fact that with post-copy it doesn\'t matter that a page had been dirtied since the guest is already running on the target VM.\\n- This means that a high dirty-rate has much less effect.\\n- Consumes less network bandwidth.\\n\\n**Disadvantages:**\\n\\n- When using post-copy, the VM state has no one source of truth. When the guest (running on the target VM) writes to memory, this memory is one part of the guest\'s state, but some other parts of it may still be updated only at the source VM. This situation is generally dangerous, since, for example, if either the target or guest VMs crash the state cannot be recovered.\\n- Slow warmup: when the guest starts executing, no memory is present at the target VM. Therefore, the guest would have to wait for a lot of memory in a short period of time.\\n- Slower than pre-copy on most cases.\\n- Harder to cancel a migration.\\n\\n#### VM Live Migration Strategy: Auto-converge\\n\\nAuto-converge is a technique to help pre-copy migrations converge faster without changing the core algorithm of how the migration works.\\n\\nSince a high dirty-rate is usually the most significant factor for migrations to not converge, auto-converge simply throttles the guest\'s CPU. If the migration would converge fast enough, the guest\'s CPU would not be throttled or throttled negligibly. But, if the migration would not converge fast enough, the CPU would be throttled more and more as time goes.\\n\\nThis technique dramatically increases the probability of the migration converging eventually.\\n\\n### Observe the VM Live Migration Progress and Result\\n\\n#### Migration Timeouts\\n\\nDepending on the type, the live migration process will copy virtual machine memory pages and disk blocks to the destination. During this process non-locked pages and blocks are being copied and become free for the instance to use again. To achieve a successful migration, it is assumed that the instance will write to the free pages and blocks (pollute the pages) at a lower rate than these are being copied.\\n\\n#### Completion Time\\n\\nIn some cases the virtual machine can write to different memory pages / disk blocks at a higher rate than these can be copied, which will prevent the migration process from completing in a reasonable amount of time. In this case, live migration will be aborted if it is running for a long period of time. The timeout is calculated base on the size of the VMI, it\'s memory and the ephemeral disks that are needed to be copied. The configurable parameter completionTimeoutPerGiB, which defaults to 800s is the time for GiB of data to wait for the migration to be completed before aborting it. A VMI with 8Gib of memory will time out after 6400 seconds.\\n\\n#### Progress Timeout\\n\\nA VM Live Migration will also be aborted when it notices that copying memory doesn\'t make any progress. The time to wait for live migration to make progress in transferring data is configurable by the `progressTimeout` parameter, which defaults to 150 seconds.\\n\\n## VM Live Migration Configurations\\n\\n### Changing Cluster Wide Migration Limits\\n\\nKubeVirt puts some limits in place so that migrations don\'t overwhelm the cluster. By default, it is to only run 5 migrations in parallel with an additional limit of a maximum of 2 outbound migrations per node. Finally, every migration is limited to a bandwidth of 64MiB/s.\\n\\nYou can change these values in the `kubevirt` CR:\\n```\\n apiVersion: kubevirt.io/v1\\n kind: Kubevirt\\n metadata:\\n name: kubevirt\\n namespace: kubevirt\\n spec:\\n configuration:\\n migrations:\\n parallelMigrationsPerCluster: 5\\n parallelOutboundMigrationsPerNode: 2\\n bandwidthPerMigration: 64Mi\\n completionTimeoutPerGiB: 800\\n progressTimeout: 150\\n disableTLS: false\\n nodeDrainTaintKey: \\"kubevirt.io/drain\\"\\n allowAutoConverge: false ---------------------\x3e related to: Auto-converge\\n allowPostCopy: false -------------------------\x3e related to: Post-copy\\n unsafeMigrationOverride: false\\n```\\n\\nRemember that most of these configurations can be overridden and fine-tuned to a specified group of VMs. For more information, please refer to the Migration Policies section below.\\n\\n### Migration Policies\\n\\n[Migration policies](https://kubevirt.io/user-guide/operations/migration_policies/) provides a new way of applying migration configurations to Virtual Machines. The policies can refine Kubevirt CR\'s `MigrationConfiguration` that sets the cluster-wide migration configurations. This way, the cluster-wide settings default how the migration policy can be refined (i.e., changed, removed, or added).\\n\\nRemember that migration policies are in version `v1alpha1`. This means that this API is not fully stable yet and that APIs may change in the future.\\n\\n#### Migration Configurations\\n\\nCurrently, the `MigrationPolicy` spec only includes the following configurations from Kubevirt CR\'s `MigrationConfiguration`. (In the future, more configurations that aren\'t part of Kubevirt CR will be added):\\n\\n```\\napiVersion: migrations.kubevirt.io/v1alpha1\\nkind: MigrationPolicy\\n spec:\\n allowAutoConverge: true\\n bandwidthPerMigration: 217Ki\\n completionTimeoutPerGiB: 23\\n allowPostCopy: false\\n```\\n\\nAll the above fields are optional. When omitted, the configuration will be applied as defined in KubevirtCR\'s `MigrationConfiguration`. This way, KubevirtCR will serve as a configurable set of defaults for both VMs that are not bound to any `MigrationPolicy` and VMs that are bound to a `MigrationPolicy` that does not define all fields of the configurations.\\n\\n##### Matching Policies to VMs\\n\\nNext in the spec are the selectors defining the group of VMs to apply the policy. The options to do so are the following.\\n\\nThis policy applies to the VMs in namespaces that have all the required labels:\\n\\n```\\napiVersion: migrations.kubevirt.io/v1alpha1\\nkind: MigrationPolicy\\n spec:\\n selectors:\\n namespaceSelector:\\n hpc-workloads: true # Matches a key and a value\\n```\\n\\nThe policy below applies to the VMs that have all the required labels:\\n\\n```\\napiVersion: migrations.kubevirt.io/v1alpha1\\nkind: MigrationPolicy\\n spec:\\n selectors:\\n virtualMachineInstanceSelector:\\n workload-type: db # Matches a key and a value\\n```\\n\\n## References\\n\\n### Documents\\n\\n### Libvirt Guest Migration\\n\\n`Libvirt` has a chapter to describe the pricipal of `VM/Guest Live Migration`.\\n\\nhttps://libvirt.org/migration.html\\n\\n### Kubevirt Live Migration\\n\\nhttps://kubevirt.io/user-guide/operations/live_migration/\\n\\n### Source Code\\n\\nThe `VM Live Migration` related configuration options are passed to each layer correspondingly.\\n\\n#### Kubevirt\\n\\nhttps://github.com/kubevirt/kubevirt/blob/d425593ae392111dab80403ef0cde82625e37653/pkg/virt-launcher/virtwrap/live-migration-source.go#L103\\n\\n```\\n...\\nimport \\"libvirt.org/go/libvirt\\"\\n\\n...\\n\\nfunc generateMigrationFlags(isBlockMigration, migratePaused bool, options *cmdclient.MigrationOptions) libvirt.DomainMigrateFlags {\\n...\\n\\tif options.AllowAutoConverge {\\n\\t\\tmigrateFlags |= libvirt.MIGRATE_AUTO_CONVERGE\\n\\t}\\n\\tif options.AllowPostCopy {\\n\\t\\tmigrateFlags |= libvirt.MIGRATE_POSTCOPY\\n\\t}\\n...\\n}\\n```\\n\\n#### Go Package Libvirt\\n\\nhttps://pkg.go.dev/libvirt.org/go/libvirt\\n\\n```\\nconst (\\n...\\n\\tMIGRATE_AUTO_CONVERGE = DomainMigrateFlags(C.VIR_MIGRATE_AUTO_CONVERGE)\\n\\tMIGRATE_RDMA_PIN_ALL = DomainMigrateFlags(C.VIR_MIGRATE_RDMA_PIN_ALL)\\n\\tMIGRATE_POSTCOPY = DomainMigrateFlags(C.VIR_MIGRATE_POSTCOPY)\\n...\\n)\\n```\\n\\n#### Libvirt\\n\\nhttps://github.com/libvirt/libvirt/blob/bfe53e9145cd5996a791c5caff0686572b850f82/include/libvirt/libvirt-domain.h#L1030\\n\\n```\\n /* Enable algorithms that ensure a live migration will eventually converge.\\n * This usually means the domain will be slowed down to make sure it does\\n * not change its memory faster than a hypervisor can transfer the changed\\n * memory to the destination host. VIR_MIGRATE_PARAM_AUTO_CONVERGE_*\\n * parameters can be used to tune the algorithm.\\n *\\n * Since: 1.2.3\\n */\\n VIR_MIGRATE_AUTO_CONVERGE = (1 << 13),\\n...\\n /* Setting the VIR_MIGRATE_POSTCOPY flag tells libvirt to enable post-copy\\n * migration. However, the migration will start normally and\\n * virDomainMigrateStartPostCopy needs to be called to switch it into the\\n * post-copy mode. See virDomainMigrateStartPostCopy for more details.\\n *\\n * Since: 1.3.3\\n */\\n VIR_MIGRATE_POSTCOPY = (1 << 15),\\n```"},{"id":"use_rook_ceph_external_storage","metadata":{"permalink":"/kb/use_rook_ceph_external_storage","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-08-23/using_rook_ceph_storage.md","source":"@site/kb/2023-08-23/using_rook_ceph_storage.md","title":"Use Rook Ceph External Storage with Harvester","description":"Use Rook Ceph External Storage with Harvester","date":"2023-08-23T00:00:00.000Z","formattedDate":"August 23, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"rook","permalink":"/kb/tags/rook"},{"label":"ceph","permalink":"/kb/tags/ceph"},{"label":"csi","permalink":"/kb/tags/csi"}],"readingTime":3.86,"truncated":false,"authors":[{"name":"Hang Yu","title":"Staff Software Engineer","url":"https://github.com/futuretea","image_url":"https://github.com/futuretea.png","imageURL":"https://github.com/futuretea.png"}],"frontMatter":{"title":"Use Rook Ceph External Storage with Harvester","description":"Use Rook Ceph External Storage with Harvester","slug":"use_rook_ceph_external_storage","authors":[{"name":"Hang Yu","title":"Staff Software Engineer","url":"https://github.com/futuretea","image_url":"https://github.com/futuretea.png","imageURL":"https://github.com/futuretea.png"}],"tags":["harvester","rook","ceph","csi"],"hide_table_of_contents":false},"prevItem":{"title":"VM Live Migration Policy and Configuration","permalink":"/kb/vm_live_migration_policy_and_configuration"},"nextItem":{"title":"Upgrade Guest Kubernetes Clusters to be Compatible with Harvester IP Pools","permalink":"/kb/upgrading_guest_clusters_with_harvester_ip_pool_compatibility"}},"content":"Starting with Harvester v1.2.0, it offers the capability to install a Container Storage Interface (CSI) in your Harvester cluster. This allows you to leverage external storage for the Virtual Machine\'s non-system data disk, giving you the flexibility to use different drivers tailored for specific needs, whether it\'s for performance optimization or seamless integration with your existing in-house storage solutions.\\n\\nIt\'s important to note that, despite this enhancement, the provisioner for the Virtual Machine (VM) image in Harvester still relies on Longhorn. Prior to version 1.2.0, Harvester exclusively supported Longhorn for storing VM data and did not offer support for external storage as a destination for VM data.\\n\\nOne of the options for integrating external storage with Harvester is Rook, an open-source cloud-native storage orchestrator. Rook provides a robust platform, framework, and support for Ceph storage, enabling seamless integration with cloud-native environments.\\n\\n[Ceph](https://ceph.io) is a software-defined distributed storage system that offers versatile storage capabilities, including file, block, and object storage. It is designed for large-scale production clusters and can be deployed effectively in such environments.\\n\\n[Rook](https://rook.io) simplifies the deployment and management of Ceph, offering self-managing, self-scaling, and self-healing storage services. It leverages Kubernetes resources to automate the deployment, configuration, provisioning, scaling, upgrading, and monitoring of Ceph.\\n\\nIn this article, we will walk you through the process of installing, configuring, and utilizing [Rook](https://rook.io/docs/rook/v1.12/Getting-Started/intro/) to use storage from an [existing external Ceph cluster](https://www.rook.io/docs/rook/v1.12/CRDs/Cluster/external-cluster/) as a data disk for a VM within the Harvester environment.\\n\\n## Install Harvester Cluster\\n\\nHarvester\'s operating system follows an immutable design, meaning that most OS files revert to their pre-configured state after a reboot. To accommodate Rook Ceph\'s requirements, you need to add specific persistent paths to the `os.persistentStatePaths` section in the [Harvester configuration](https://docs.harvesterhci.io/dev/install/harvester-configuration#ospersistent_state_paths). These paths include:\\n\\n```yaml\\nos:\\n persistent_state_paths:\\n - /var/lib/rook\\n - /var/lib/ceph\\n modules:\\n - rbd\\n - nbd\\n```\\n\\nAfter the cluster is installed, refer to [How can I access the kubeconfig file of the Harvester cluster?](https://docs.harvesterhci.io/v1.1/faq#how-can-i-access-the-kubeconfig-file-of-the-harvester-cluster) to get the kubeconfig of the Harvester cluster.\\n\\n## Install Rook to Harvester\\n\\nInstall Rook to the Harvester cluster by referring to [Rook Quickstart](https://rook.io/docs/rook/v1.12/Getting-Started/quickstart/).\\n\\n```bash\\ncurl -fsSLo rook.tar.gz https://github.com/rook/rook/archive/refs/tags/v1.12.2.tar.gz \\\\\\n && tar -zxf rook.tar.gz && cd rook-1.12.2/deploy/examples\\n# apply configurations ref: https://rook.github.io/docs/rook/v1.12/Getting-Started/example-configurations/\\nkubectl apply -f crds.yaml -f common.yaml -f operator.yaml\\nkubectl -n rook-ceph wait --for=condition=Available deploy rook-ceph-operator --timeout=10m\\n```\\n\\n## Using an existing external Ceph cluster\\n\\n1. Run the python script `create-external-cluster-resources.py` in the [existing external Ceph cluster](https://www.rook.io/docs/rook/v1.12/CRDs/Cluster/external-cluster/) for creating all users and keys.\\n```bash\\n# script help ref: https://www.rook.io/docs/rook/v1.12/CRDs/Cluster/external-cluster/#1-create-all-users-and-keys\\ncurl -s https://raw.githubusercontent.com/rook/rook/v1.12.2/deploy/examples/create-external-cluster-resources.py > create-external-cluster-resources.py\\npython3 create-external-cluster-resources.py --rbd-data-pool-name --namespace rook-ceph-external --format bash\\n```\\n\\n2. Copy the Bash output.\\n\\nExample output:\\n```\\nexport NAMESPACE=rook-ceph-external\\nexport ROOK_EXTERNAL_FSID=b3b47828-4c60-11ee-be38-51902f85c805\\nexport ROOK_EXTERNAL_USERNAME=client.healthchecker\\nexport ROOK_EXTERNAL_CEPH_MON_DATA=ceph-1=192.168.5.99:6789\\nexport ROOK_EXTERNAL_USER_SECRET=AQDd6/dkFyu/IhAATv/uCMbHtWk4AYK2KXzBhQ==\\nexport ROOK_EXTERNAL_DASHBOARD_LINK=https://192.168.5.99:8443/\\nexport CSI_RBD_NODE_SECRET=AQDd6/dk2HsjIxAA06Yw9UcOg0dfwV/9IFBRhA==\\nexport CSI_RBD_NODE_SECRET_NAME=csi-rbd-node\\nexport CSI_RBD_PROVISIONER_SECRET=AQDd6/dkEY1kIxAAAzrXZnVRf4x+wDUz1zyaQg==\\nexport CSI_RBD_PROVISIONER_SECRET_NAME=csi-rbd-provisioner\\nexport MONITORING_ENDPOINT=192.168.5.99\\nexport MONITORING_ENDPOINT_PORT=9283\\nexport RBD_POOL_NAME=test\\nexport RGW_POOL_PREFIX=default\\n```\\n\\n3. Consume the external Ceph cluster resources on the Harvester cluster.\\n\\n```bash\\n# Paste the above output from create-external-cluster-resources.py into import-env.sh\\nvim import-env.sh\\nsource import-env.sh\\n# this script will create a StorageClass ceph-rbd\\nsource import-external-cluster.sh\\n```\\n\\n```bash\\nkubectl apply -f common-external.yaml\\nkubectl apply -f cluster-external.yaml\\n# wait for all pods to become Ready\\nwatch \'kubectl --namespace rook-ceph get pods\'\\n```\\n\\n4. Create the VolumeSnapshotClass `csi-rbdplugin-snapclass-external`.\\n\\n```bash\\ncat >./csi/rbd/snapshotclass-external.yaml < **Settings**.\\n1. Find and select **csi-driver-config**, and then click on the **\u22ee** > **Edit Setting** to access the configuration options.\\n1. In the settings, set the **Provisioner** to `rook-ceph.rbd.csi.ceph.com`.\\n2. Next, specify the **Volume Snapshot Class Name** as `csi-rbdplugin-snapclass-external`. This setting points to the name of the `VolumeSnapshotClass` used for creating volume snapshots or VM snapshots.\\n3. Similarly, set the **Backup Volume Snapshot Class Name** to `csi-rbdplugin-snapclass-external`. This corresponds to the name of the `VolumeSnapshotClass` responsible for creating VM backups.\\n\\n![csi-driver-config-external](./imgs/csi-driver-config-external.png)\\n\\n## Use Rook Ceph in Harvester\\n\\nAfter successfully configuring these settings, you can proceed to utilize the Rook Ceph StorageClass, which is named `rook-ceph-block` for the internal Ceph cluster or named `ceph-rbd` for the external Ceph cluster. You can apply this StorageClass when creating an empty volume or adding a new block volume to a VM, enhancing your Harvester cluster\'s storage capabilities.\\n\\nWith these configurations in place, your Harvester cluster is ready to make the most of the Rook Ceph storage integration.\\n\\n![rook-ceph-volume-external](./imgs/rook-ceph-volume-external.png)\\n\\n![rook-ceph-vm-external](./imgs/rook-ceph-vm-external.png)"},{"id":"upgrading_guest_clusters_with_harvester_ip_pool_compatibility","metadata":{"permalink":"/kb/upgrading_guest_clusters_with_harvester_ip_pool_compatibility","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-08-21/compatible_with_ip_pool_new_feature.md","source":"@site/kb/2023-08-21/compatible_with_ip_pool_new_feature.md","title":"Upgrade Guest Kubernetes Clusters to be Compatible with Harvester IP Pools","description":"Explain how to keep load balancer IP during upgrading guest cluster","date":"2023-08-21T00:00:00.000Z","formattedDate":"August 21, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"load balancer","permalink":"/kb/tags/load-balancer"},{"label":"cloud provider","permalink":"/kb/tags/cloud-provider"},{"label":"ip pool","permalink":"/kb/tags/ip-pool"},{"label":"upgrade","permalink":"/kb/tags/upgrade"}],"readingTime":2.675,"truncated":false,"authors":[{"name":"Canwu Yao","title":"Software Engineer","url":"https://github.com/yaocw2020","image_url":"https://avatars.githubusercontent.com/u/7421463?s=400&v=4","imageURL":"https://avatars.githubusercontent.com/u/7421463?s=400&v=4"}],"frontMatter":{"title":"Upgrade Guest Kubernetes Clusters to be Compatible with Harvester IP Pools","description":"Explain how to keep load balancer IP during upgrading guest cluster","slug":"upgrading_guest_clusters_with_harvester_ip_pool_compatibility","authors":[{"name":"Canwu Yao","title":"Software Engineer","url":"https://github.com/yaocw2020","image_url":"https://avatars.githubusercontent.com/u/7421463?s=400&v=4","imageURL":"https://avatars.githubusercontent.com/u/7421463?s=400&v=4"}],"tags":["harvester","load balancer","cloud provider","ip pool","upgrade"],"hide_table_of_contents":false},"prevItem":{"title":"Use Rook Ceph External Storage with Harvester","permalink":"/kb/use_rook_ceph_external_storage"},"nextItem":{"title":"Using NetApp Storage on Harvester","permalink":"/kb/install_netapp_trident_csi"}},"content":"As **Harvester v1.2.0** is released, a new Harvester cloud provider version **0.2.2** is integrated into RKE2 **v1.24.15+rke2r1**, **v1.25.11+rke2r1**, **v1.26.6+rke2r1**, **v1.27.3+rke2r1**, and newer versions.\\n\\nWith Harvester v1.2.0, the new Harvester cloud provider offers enhanced load balancing capabilities for guest Kubernetes services. Specifically, it introduces the Harvester IP Pool feature, a built-in IP address management (IPAM) solution for the Harvester load balancer. It allows you to define an IP pool specific to a particular guest cluster by specifying the guest cluster name. For example, you can create an IP pool exclusively for the guest cluster named cluster2:\\n\\n![image](ippoolforcluster2.png)\\n\\nHowever, after upgrading, the feature is not automatically compatible with existing guest Kubernetes clusters, as they do not pass the correct cluster name to the Harvester cloud provider. Refer to [issue 4232](https://github.com/harvester/harvester/issues/4232) for more details. Users can manually upgrade the Harvester cloud provider using Helm as a workaround and provide the correct cluster name after upgrading. However, this would result in a change in the load balancer IPs. \\n\\nThis article outlines a workaround that allows you to leverage the new IP pool feature while keeping the load balancer IPs unchanged.\\n\\n## Prerequisites\\n\\n- Download the Harvester kubeconfig file from the Harvester UI. If you have imported Harvester into Rancher, do not use the kubeconfig file from the Rancher UI. Refer to [Access Harvester Cluster](https://docs.harvesterhci.io/v1.1/faq#how-can-i-access-the-kubeconfig-file-of-the-harvester-cluster) to get the desired one.\\n\\n- Download the kubeconfig file for the guest Kubernetes cluster you plan to upgrade. Refer to [Accessing Clusters with kubectl from Your Workstation](https://ranchermanager.docs.rancher.com/how-to-guides/new-user-guides/manage-clusters/access-clusters/use-kubectl-and-kubeconfig#accessing-clusters-with-kubectl-from-your-workstation) for instructions on how to download the kubeconfig file.\\n\\n## Steps to Keep Load Balancer IP\\n\\n1. Execute the following script before upgrading.\\n ```\\n curl -sfL https://raw.githubusercontent.com/harvester/harvesterhci.io/main/kb/2023-08-21/keepip.sh | sh -s before_upgrade \\n ```\\n\\n - ``: Path to the Harvester kubeconfig file.\\n - ``: Path to the kubeconfig file of your guest Kubernetes cluster.\\n - ``: Name of your guest cluster.\\n - ``: Namespace where the VMs of the guest cluster are located.\\n\\n The script will help users copy the DHCP information to the service annotation and modify the IP pool allocated history to make sure the IP is unchanged.\\n\\n ![image](before-upgrade.png)\\n\\n After executing the script, the load balancer service with DHCP mode will be annotated with the DHCP information. For example:\\n\\n ``` yaml\\n apiVersion: v1\\n kind: Service\\n metadata:\\n annotations:\\n kube-vip.io/hwaddr: 00:00:6c:4f:18:68\\n kube-vip.io/requestedIP: 172.19.105.215\\n name: lb0\\n namespace: default\\n ```\\n\\n As for the load balancer service with pool mode, the IP pool allocated history will be modified as the new load balancer name. For example:\\n\\n ``` yaml\\n apiVersion: loadbalancer.harvesterhci.io/v1beta1\\n kind: IPPool\\n metadata:\\n name: default\\n spec:\\n ...\\n status:\\n allocatedHistory:\\n 192.168.100.2: default/cluster-name-default-lb1-ddc13071 # replace the new load balancer name\\n ```\\n\\n2. Add network selector for the pool.\\n\\n For example, the following cluster is under the VM network `default/mgmt-untagged`. The network selector should be `default/mgmt-untagged`.\\n\\n ![image](network.png)\\n\\n ![image](network-selector.png)\\n\\n3. Upgrade the RKE2 cluster in the Rancher UI and select the new version.\\n \\n ![image](upgrade.png)\\n\\n1. Execute the script after upgrading.\\n ```\\n curl -sfL https://raw.githubusercontent.com/harvester/harvesterhci.io/main/kb/2023-08-21/keepip.sh | sh -s after_upgrade \\n ```\\n ![image](before-upgrade.png)\\n \\n In this step, the script wraps the operations to upgrade the Harvester cloud provider to set the cluster name. After the Harvester cloud provider is running, the new Harvester load balancers will be created with the unchanged IPs."},{"id":"install_netapp_trident_csi","metadata":{"permalink":"/kb/install_netapp_trident_csi","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-08-11/using_netapp_third_party_storage.md","source":"@site/kb/2023-08-11/using_netapp_third_party_storage.md","title":"Using NetApp Storage on Harvester","description":"Installation procedure for NetApp Astra Trident CSI Driver","date":"2023-08-11T00:00:00.000Z","formattedDate":"August 11, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"}],"readingTime":6.08,"truncated":false,"authors":[{"name":"Jeff Radick","title":"Staff Software Engineer"}],"frontMatter":{"title":"Using NetApp Storage on Harvester","description":"Installation procedure for NetApp Astra Trident CSI Driver","slug":"install_netapp_trident_csi","authors":[{"name":"Jeff Radick","title":"Staff Software Engineer"}],"tags":["harvester"],"hide_table_of_contents":false},"prevItem":{"title":"Upgrade Guest Kubernetes Clusters to be Compatible with Harvester IP Pools","permalink":"/kb/upgrading_guest_clusters_with_harvester_ip_pool_compatibility"},"nextItem":{"title":"Configure PriorityClass on Longhorn System Components","permalink":"/kb/configure_priority_class_longhorn"}},"content":"This article covers instructions for installing the Netapp Astra Trident CSI driver into a Harvester cluster, which enables NetApp storage systems to store storage volumes usable by virtual machines running in Harvester.\\n\\nThe NetApp storage will be an option in addition to the normal Longhorn storage; it will not replace Longhorn. Virtual machine images will still be stored using Longhorn.\\n\\nThis has been tested with Harvester 1.2.0 and Trident v23.07.0.\\n\\nThis procedure only works to access storage via iSCSI, not NFS.\\n\\n:::note\\n3rd party storage classes (including those based on Trident) can only be used for non-boot volumes of Harvester VMs.\\n:::\\n\\n# Detailed Instructions\\n\\nWe assume that before beginning this procedure, a Harvester cluster and a NetApp ONTAP storage system are both installed and configured for use.\\n\\nMost of these steps can be performed on any system with the `helm` and `kubectl` commands installed and network connectivity to the management port of the Harvester cluster. Let\'s call this your workstation. Certain steps must be performed on one or more cluster nodes themselves. The steps described below should be done on your workstation unless otherwise indicated.\\n\\nThe last step (enabling multipathd) should be done on all nodes after the Trident CSI has been installed.\\n\\nCertain parameters of your installation will require modification of details in the examples in the procedure given below. Those which you may wish to modify include:\\n\\n* The namespace. `trident` is used as the namespace in the examples, but you may prefer to use another.\\n* The name of the deployment. `mytrident` is used but you can change this to something else.\\n* The management IP address of the ONTAP storage system\\n* Login credentials (username and password) of the ONTAP storage system\\n\\nThe procedure is as follows.\\n\\n1. Read the NetApp Astra Trident documentation:\\n\\n * https://docs.netapp.com/us-en/trident/\\n * https://docs.netapp.com/us-en/trident/trident-get-started/kubernetes-deploy-operator.html\\n * https://docs.netapp.com/us-en/trident/trident-get-started/kubernetes-deploy-helm.html#deploy-the-trident-operator-and-install-astra-trident-using-helm\\n\\n The simplest method is to install using Helm; that process is described here.\\n\\n1. Download the KubeConfig from the Harvester cluster.\\n\\n * Open the web UI for your Harvester cluster\\n * In the lower left corner, click the \\"Support\\" link. This will take you to a \\"Harvester Support\\" page.\\n * Click the button labeled \\"Download KubeConfig\\". This will download a your cluster config in a file called \\"local.yaml\\" by default.\\n * Move this file to a convenient location and set your `KUBECONFIG` environment variable to the path of this file.\\n\\n1. Prepare the cluster for installation of the Helm chart.\\n\\n Before starting installation of the helm chart, special authorization must be provided to enable certain modifications to be made during the installation.\\n This addresses the issue described here: https://github.com/NetApp/trident/issues/839\\n\\n * Put the following text into a file. For this example we\'ll call it `authorize_trident.yaml`.\\n\\n ```yaml\\n ---\\n apiVersion: rbac.authorization.k8s.io/v1\\n kind: ClusterRole\\n metadata:\\n name: trident-operator-psa\\n rules:\\n - apiGroups:\\n - management.cattle.io\\n resources:\\n - projects\\n verbs:\\n - updatepsa\\n ---\\n apiVersion: rbac.authorization.k8s.io/v1\\n kind: ClusterRoleBinding\\n metadata:\\n name: trident-operator-psa\\n roleRef:\\n apiGroup: rbac.authorization.k8s.io\\n kind: ClusterRole\\n name: trident-operator-psa\\n subjects:\\n - kind: ServiceAccount\\n name: trident-operator\\n namespace: trident\\n ```\\n\\n * Apply this manifest via the command `kubectl apply -f authorize_trident.yaml`.\\n\\n1. Install the helm chart.\\n\\n * First you will need to add the Astra Trident Helm repository:\\n\\n ```shell\\n helm repo add netapp-trident https://netapp.github.io/trident-helm-chart\\n ```\\n\\n * Next, install the Helm chart. This example uses `mytrident` as the deployment name, `trident` as the namespace, and 23.07.0 as the version number to install:\\n\\n ```shell\\n helm install mytrident netapp-trident/trident-operator --version 23.07.0 --create-namespace --namespace trident\\n ```\\n\\n * The NetApp documentation describes variations on how you can do this.\\n\\n1. Download and extract the tridentctl command, which will be needed for the next few steps.\\n\\n This and the next few steps need to be performed logged into a master node of the Harvester cluster, using root access.\\n\\n ```shell\\n cd /tmp\\n curl -L -o trident-installer-23.07.0.tar.gz https://github.com/NetApp/trident/releases/download/v23.07.0/trident-installer-23.07.0.tar.gz\\n tar -xf trident-installer-23.07.0.tar.gz\\n cd trident-installer\\n ```\\n\\n1. Install a backend.\\n\\n This part is specific to Harvester.\\n\\n 1. Put the following into a text file, for example /tmp/backend.yaml\\n\\n ```yaml\\n version: 1\\n backendName: default_backend_san\\n storageDriverName: ontap-san-economy\\n managementLIF: 172.19.97.114\\n svm: default_backend\\n username: admin\\n password: password1234\\n labels:\\n name: default_backend_san\\n ```\\n\\n The LIF IP address, username, and password of this file\\n should be replaced with the management LIF and credentials\\n for the ONTAP system.\\n\\n 1. Create the backend\\n\\n ```shell\\n ./tridentctl create backend -f /tmp/backend.yaml -n trident\\n ```\\n\\n 1. Check that it is created\\n\\n ```shell\\n ./tridentctl get backend -n trident\\n ```\\n\\n1. Define a StorageClass and SnapshotClass.\\n\\n 1. Put the following into a file, for example `/tmp/storage.yaml`\\n\\n ```yaml\\n ---\\n apiVersion: storage.k8s.io/v1\\n kind: StorageClass\\n metadata:\\n name: ontap-san-economy\\n provisioner: csi.trident.netapp.io\\n parameters:\\n selector: \\"name=default_backend_san\\"\\n ---\\n apiVersion: snapshot.storage.k8s.io/v1\\n kind: VolumeSnapshotClass\\n metadata:\\n name: csi-snapclass\\n driver: csi.trident.netapp.io\\n deletionPolicy: Delete\\n ```\\n\\n 1. Apply the definitions:\\n\\n ```shell\\n kubectl apply -f /tmp/storage.yaml\\n ```\\n\\n1. Enable multipathd\\n\\n The following is required to enable multipathd.\\n This must be done on every node of the Harvester cluster, using root access.\\n The preceding steps should only be done once on a single node.\\n\\n 1. Create this file in `/oem/99_multipathd.yaml`:\\n\\n ```yaml\\n stages:\\n default:\\n - name: \\"Setup multipathd\\"\\n systemctl:\\n enable:\\n - multipathd\\n start:\\n - multipathd\\n ```\\n\\n 1. Configure `multipathd` to exclude pathnames used by Longhorn.\\n\\n This part is a little tricky. `multipathd` will automatically discover\\n device names matching a certain pattern, and attempt to set up multipathing on them.\\n Unfortunately, Longhorn\'s device names follow the same pattern, and\\n will not work correctly if `multipathd` tries to use those devices.\\n\\n Therefore the file `/etc/multipath.conf` must be set up on each node\\n so as to prevent `multipathd` from touching any of the devices\\n that Longhorn will use. Unfortunately, it is not possible to know\\n in advance which device names will be used until the volumes are attached\\n to a VM when the VM is started, or when the volumes are hot-added to a running VM.\\n The recommended method is to \\"whitelist\\" the Trident devices using device\\n properties rather than device naming. The properties to allow are the\\n device vendor and product. Here is an example of what you\'ll want in `/etc/multipath.conf`:\\n\\n ```text\\n blacklist {\\n device {\\n vendor \\"!NETAPP\\"\\n product \\"!LUN\\"\\n }\\n }\\n blacklist_exceptions {\\n device {\\n vendor \\"NETAPP\\"\\n product \\"LUN\\"\\n }\\n }\\n ```\\n\\n This example only works if NetApp is the only storage provider in the system for which `multipathd` must be used. More complex environments will require more complex configuration.\\n\\n Explicitly putting that content into `/etc/multipath.conf` will work when you start `multipathd` as described below, but the change in `/etc` will not persist across node reboots. To solve that problem, you should add another file to `/oem` that will re-generate `/etc/multipath.conf` when the node reboots. The following example will create the `/etc/multipath.conf` given in the example above, but may need to be modified for your environment if you have a more complex iSCSI configuration:\\n\\n ```text\\n stages:\\n initramfs:\\n - name: \\"Configure multipath blacklist and whitelist\\"\\n files:\\n - path: /etc/multipath.conf\\n permissions: 0644\\n owner: 0\\n group: 0\\n content: |\\n blacklist {\\n device {\\n vendor \\"!NETAPP\\"\\n product \\"!LUN\\"\\n }\\n }\\n blacklist_exceptions {\\n device {\\n vendor \\"NETAPP\\"\\n product \\"LUN\\"\\n }\\n }\\n ```\\n\\n Remember, this has to be done on every node.\\n\\n 1. Enable multipathd.\\n\\n Adding the above files to `/oem` will take effect on the next reboot of the node; `multipathd` can be enabled immediately without rebooting the node using the following commands:\\n\\n ```shell\\n systemctl enable multipathd\\n systemctl start multipathd\\n ```\\n\\n After the above steps, the `ontap-san-economy` storage class should be available when creating a volume for a Harvester VM."},{"id":"configure_priority_class_longhorn","metadata":{"permalink":"/kb/configure_priority_class_longhorn","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-07-25/configure_priority_class_longhorn.md","source":"@site/kb/2023-07-25/configure_priority_class_longhorn.md","title":"Configure PriorityClass on Longhorn System Components","description":"Configure priority classes on Longhorn system components","date":"2023-07-25T00:00:00.000Z","formattedDate":"July 25, 2023","tags":[{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"longhorn","permalink":"/kb/tags/longhorn"},{"label":"priority class","permalink":"/kb/tags/priority-class"}],"readingTime":6.405,"truncated":false,"authors":[{"name":"Kiefer Chang","title":"Engineer Manager","url":"https://github.com/bk201","image_url":"https://github.com/bk201.png","imageURL":"https://github.com/bk201.png"}],"frontMatter":{"title":"Configure PriorityClass on Longhorn System Components","description":"Configure priority classes on Longhorn system components","slug":"configure_priority_class_longhorn","authors":[{"name":"Kiefer Chang","title":"Engineer Manager","url":"https://github.com/bk201","image_url":"https://github.com/bk201.png","imageURL":"https://github.com/bk201.png"}],"tags":["harvester","longhorn","priority class"],"hide_table_of_contents":false},"prevItem":{"title":"Using NetApp Storage on Harvester","permalink":"/kb/install_netapp_trident_csi"},"nextItem":{"title":"Package your own Toolbox Image","permalink":"/kb/package_your_own_toolbox_image"}},"content":"**Harvester v1.2.0** introduces a new enhancement where Longhorn system-managed components in newly-deployed clusters are automatically assigned a `system-cluster-critical` priority class by default. However, when upgrading your Harvester clusters from previous versions, you may notice that Longhorn system-managed components do not have any priority class set.\\n\\nThis behavior is intentional and aimed at supporting zero-downtime upgrades. Longhorn does not allow changing the `priority-class` setting when attached volumes exist. For more details, please refer to [Setting Priority Class During Longhorn Installation](https://longhorn.io/docs/1.4.3/advanced-resources/deploy/priority-class/#setting-priority-class-during-longhorn-installation)).\\n\\nThis article explains how to manually configure priority classes for Longhorn system-managed components after upgrading your Harvester cluster, ensuring that your Longhorn components have the appropriate priority class assigned and maintaining the stability and performance of your system.\\n\\n## Stop all virtual machines\\n\\nStop all virtual machines (VMs) to detach all volumes. Please back up any work before doing this.\\n1. [Login to a Harvester controller node and become root](https://docs.harvesterhci.io/v1.1/troubleshooting/os#how-to-log-into-a-harvester-node).\\n2. Get all running VMs and write down their namespaces and names:\\n\\n ```bash\\n kubectl get vmi -A\\n ```\\n\\n Alternatively, you can get this information by backing up the Virtual Machine Instance (VMI) manifests with the following command:\\n ```bash\\n kubectl get vmi -A -o json > vmi-backup.json\\n ```\\n\\n3. Shut down all VMs. Log in to all running VMs and shut them down gracefully (recommended). Or use the following command to send shutdown signals to all VMs:\\n ```bash\\n kubectl get vmi -A -o json | jq -r \'.items[] | [.metadata.name, .metadata.namespace] | @tsv\' | while IFS=$\'\\\\t\' read -r name namespace; do\\n if [ -z \\"$name\\" ]; then\\n break\\n fi\\n echo \\"Stop ${namespace}/${name}\\"\\n virtctl stop $name -n $namespace\\n done\\n ```\\n\\n :::note\\n You can also stop all VMs from the Harvester UI:\\n 1. Go to the **Virtual Machines** page.\\n 2. For each VM, select **\u22ee** > **Stop**.\\n :::\\n\\n4. Ensure there are no running VMs:\\n\\n Run the command:\\n\\n ```bash\\n kubectl get vmi -A\\n ```\\n\\n The above command must return:\\n\\n ```bash\\n No resources found\\n\\n## Scale down monitoring pods\\n\\n1. Scale down the Prometheus deployment. Run the following command and wait for all Prometheus pods to terminate:\\n\\n ```bash\\n kubectl patch -n cattle-monitoring-system prometheus/rancher-monitoring-prometheus --patch \'{\\"spec\\": {\\"replicas\\": 0}}\' --type merge && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system statefulset/prometheus-rancher-monitoring-prometheus\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n prometheus.monitoring.coreos.com/rancher-monitoring-prometheus patched\\n statefulset rolling update complete 0 pods at revision prometheus-rancher-monitoring-prometheus-cbf6bd5f7...\\n ```\\n\\n2. Scale down the AlertManager deployment. Run the following command and wait for all AlertManager pods to terminate:\\n\\n ```bash\\n kubectl patch -n cattle-monitoring-system alertmanager/rancher-monitoring-alertmanager --patch \'{\\"spec\\": {\\"replicas\\": 0}}\' --type merge && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system statefulset/alertmanager-rancher-monitoring-alertmanager\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n alertmanager.monitoring.coreos.com/rancher-monitoring-alertmanager patched\\n statefulset rolling update complete 0 pods at revision alertmanager-rancher-monitoring-alertmanager-c8c459dff...\\n ```\\n\\n3. Scale down the Grafana deployment. Run the following command and wait for all Grafana pods to terminate:\\n\\n ```bash\\n kubectl scale --replicas=0 deployment/rancher-monitoring-grafana -n cattle-monitoring-system && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system deployment/rancher-monitoring-grafana\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n deployment.apps/rancher-monitoring-grafana scaled\\n deployment \\"rancher-monitoring-grafana\\" successfully rolled out\\n ```\\n\\n## Scale down vm-import-controller pods\\n\\n1. Check if the [`vm-import-controller`](https://docs.harvesterhci.io/v1.1/advanced/vmimport) addon is enabled and configured with a persistent volume with the following command:\\n\\n ```bash\\n kubectl get pvc -n harvester-system harvester-vm-import-controller\\n ```\\n\\n If the above command returns an output like this, you must scale down the `vm-import-controller` pod. Otherwise, you can skip the following step.\\n ```\\n NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE\\n harvester-vm-import-controller Bound pvc-eb23e838-4c64-4650-bd8f-ba7075ab0559 200Gi RWO harvester-longhorn 2m53s\\n ```\\n\\n2. Scale down the `vm-import-controller` pods with the following command:\\n\\n ```bash\\n kubectl scale --replicas=0 deployment/harvester-vm-import-controller -n harvester-system && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n harvester-system deployment/harvester-vm-import-controller\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n deployment.apps/harvester-vm-import-controller scaled\\n deployment \\"harvester-vm-import-controller\\" successfully rolled out\\n ```\\n\\n## Set the `priority-class` setting\\n\\n1. Before applying the `priority-class` setting, you need to verify all volumes are detached. Run the following command to verify the `STATE` of each volume is `detached`:\\n\\n ```bash\\n kubectl get volumes.longhorn.io -A\\n ```\\n\\n Verify the output looks like this:\\n ```\\n NAMESPACE NAME STATE ROBUSTNESS SCHEDULED SIZE NODE AGE\\n longhorn-system pvc-5743fd02-17a3-4403-b0d3-0e9b401cceed detached unknown 5368709120 15d\\n longhorn-system pvc-7e389fe8-984c-4049-9ba8-5b797cb17278 detached unknown 53687091200 15d\\n longhorn-system pvc-8df64e54-ecdb-4d4e-8bab-28d81e316b8b detached unknown 2147483648 15d\\n longhorn-system pvc-eb23e838-4c64-4650-bd8f-ba7075ab0559 detached unknown 214748364800 11m\\n ```\\n\\n1. Set the `priority-class` setting with the following command:\\n\\n ```bash\\n kubectl patch -n longhorn-system settings.longhorn.io priority-class --patch \'{\\"value\\": \\"system-cluster-critical\\"}\' --type merge\\n ```\\n\\n Longhorn system-managed pods will restart and then you need to check if all the system-managed components have a priority class set:\\n\\n Get the value of the priority class `system-cluster-critical`:\\n ```bash\\n kubectl get priorityclass system-cluster-critical\\n ```\\n\\n Verify the output looks like this:\\n ```\\n NAME VALUE GLOBAL-DEFAULT AGE\\n system-cluster-critical 2000000000 false 15d\\n ```\\n\\n3. Use the following command to get pods\' priority in the `longhorn-system` namespace:\\n\\n ```bash\\n kubectl get pods -n longhorn-system -o custom-columns=\\"Name\\":metadata.name,\\"Priority\\":.spec.priority\\n ```\\n\\n4. Verify all system-managed components\' pods have the correct priority. System-managed components include:\\n\\n - `csi-attacher`\\n - `csi-provisioner`\\n - `csi-resizer`\\n - `csi-snapshotter`\\n - `engine-image-ei`\\n - `instance-manager-e`\\n - `instance-manager-r`\\n - `longhorn-csi-plugin`\\n\\n## Scale up vm-import-controller pods\\n\\nIf you scale down the `vm-import-controller` pods, you must scale it up again. \\n\\n1. Scale up the `vm-import-controller` pod. Run the command: \\n\\n ```bash\\n kubectl scale --replicas=1 deployment/harvester-vm-import-controller -n harvester-system && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n harvester-system deployment/harvester-vm-import-controller\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n deployment.apps/harvester-vm-import-controller scaled\\n Waiting for deployment \\"harvester-vm-import-controller\\" rollout to finish: 0 of 1 updated replicas are available...\\n deployment \\"harvester-vm-import-controller\\" successfully rolled out\\n ```\\n\\n2. Verify `vm-import-controller` is running using the following command:\\n ```bash\\n kubectl get pods --selector app.kubernetes.io/instance=vm-import-controller -A\\n ```\\n\\n A sample output looks like this, the pod\'s `STATUS` must be `Running`:\\n ```\\n NAMESPACE NAME READY STATUS RESTARTS AGE\\n harvester-system harvester-vm-import-controller-6bd8f44f55-m9k86 1/1 Running 0 4m53s\\n ```\\n\\n## Scale up monitoring pods\\n\\n1. Scale up the Prometheus deployment. Run the following command and wait for all Prometheus pods to roll out:\\n\\n ```bash\\n kubectl patch -n cattle-monitoring-system prometheus/rancher-monitoring-prometheus --patch \'{\\"spec\\": {\\"replicas\\": 1}}\' --type merge && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system statefulset/prometheus-rancher-monitoring-prometheus\\n ```\\n\\n A sample output looks like:\\n ```\\n prometheus.monitoring.coreos.com/rancher-monitoring-prometheus patched\\n Waiting for 1 pods to be ready...\\n statefulset rolling update complete 1 pods at revision prometheus-rancher-monitoring-prometheus-cbf6bd5f7...\\n ```\\n\\n2. Scale down the AlertManager deployment. Run the following command and wait for all AlertManager pods to roll out:\\n\\n ```bash\\n kubectl patch -n cattle-monitoring-system alertmanager/rancher-monitoring-alertmanager --patch \'{\\"spec\\": {\\"replicas\\": 1}}\' --type merge && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system statefulset/alertmanager-rancher-monitoring-alertmanager\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n alertmanager.monitoring.coreos.com/rancher-monitoring-alertmanager patched\\n Waiting for 1 pods to be ready...\\n statefulset rolling update complete 1 pods at revision alertmanager-rancher-monitoring-alertmanager-c8bd4466c...\\n ```\\n\\n3. Scale down the Grafana deployment. Run the following command and wait for all Grafana pods to roll out:\\n\\n ```bash\\n kubectl scale --replicas=1 deployment/rancher-monitoring-grafana -n cattle-monitoring-system && \\\\\\n sleep 5 && \\\\\\n kubectl rollout status --watch=true -n cattle-monitoring-system deployment/rancher-monitoring-grafana\\n ```\\n\\n A sample output looks like this:\\n\\n ```\\n deployment.apps/rancher-monitoring-grafana scaled\\n Waiting for deployment \\"rancher-monitoring-grafana\\" rollout to finish: 0 of 1 updated replicas are available...\\n deployment \\"rancher-monitoring-grafana\\" successfully rolled out\\n ```\\n\\n## Start virtual machines\\n\\n1. Start a VM with the command:\\n\\n ```bash\\n virtctl start $name -n $namespace\\n ```\\n\\n Replace `$name` with the VM\'s name and `$namespace` with the VM\'s namespace. You can list all virtual machines with the command:\\n\\n ```bash\\n kubectl get vms -A\\n ```\\n\\n :::note\\n You can also stop all VMs from the Harvester UI:\\n 1. Go to the **Virtual Machines** page.\\n 2. For each VM, select **\u22ee** > **Start**.\\n :::\\n\\n Alternatively, you can start all running VMs with the following command:\\n\\n ```bash\\n cat vmi-backup.json | jq -r \'.items[] | [.metadata.name, .metadata.namespace] | @tsv\' | while IFS=$\'\\\\t\' read -r name namespace; do\\n if [ -z \\"$name\\" ]; then\\n break\\n fi\\n echo \\"Start ${namespace}/${name}\\"\\n virtctl start $name -n $namespace || true\\n done\\n ```"},{"id":"package_your_own_toolbox_image","metadata":{"permalink":"/kb/package_your_own_toolbox_image","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-07-06/package_your_own_toolbox_image.md","source":"@site/kb/2023-07-06/package_your_own_toolbox_image.md","title":"Package your own Toolbox Image","description":"How to package your own toolbox image","date":"2023-07-06T00:00:00.000Z","formattedDate":"July 6, 2023","tags":[{"label":"debug","permalink":"/kb/tags/debug"},{"label":"harvester","permalink":"/kb/tags/harvester"},{"label":"container","permalink":"/kb/tags/container"}],"readingTime":1.655,"truncated":false,"authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"frontMatter":{"title":"Package your own Toolbox Image","description":"How to package your own toolbox image","slug":"package_your_own_toolbox_image","authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"tags":["debug","harvester","container"],"hide_table_of_contents":false},"prevItem":{"title":"Configure PriorityClass on Longhorn System Components","permalink":"/kb/configure_priority_class_longhorn"},"nextItem":{"title":"Scan and Repair Root Filesystem of VirtualMachine","permalink":"/kb/scan-and-repair-vm-root-filesystem"}},"content":"Harvester OS is designed as an immutable operating system, which means you cannot directly install additional packages on it. While there is a way to [install packages](https://docs.harvesterhci.io/dev/troubleshooting/os#how-can-i-install-packages-why-are-some-paths-read-only), it is strongly advised against doing so, as it may lead to system instability.\\n\\nIf you only want to debug with the system, the preferred way is to package the toolbox image with all the needed packages. \\n\\nThis article shares how to package your toolbox image and how to install any packages on the toolbox image that help you debug the system.\\n\\nFor example, if you want to analyze a storage performance issue, you can install `blktrace` on the toolbox image.\\n\\n\\n## Create a Dockerfile\\n\\n```bash\\nFROM opensuse/leap:15.4\\n\\n# Install blktrace\\nRUN zypper in -y \\\\\\n blktrace\\n\\nRUN zypper clean --all\\n```\\n\\n## Build the image and push\\n```bash\\n# assume you are in the directory of Dockerfile\\n$ docker build -t harvester/toolbox:dev .\\n.\\n.\\n.\\nnaming to docker.io/harvester/toolbox:dev ...\\n$ docker push harvester/toolbox:dev\\n.\\n.\\nd4b76d0683d4: Pushed \\na605baa225e2: Pushed \\n9e9058bdf63c: Layer already exists \\n```\\n\\nAfter you build and push the image, you can run the toolbox using this image to trace storage performance.\\n\\n## Run the toolbox\\n```bash\\n# use `privileged` flag only when you needed. blktrace need debugfs, so I add extra mountpoint.\\ndocker run -it --privileged -v /sys/kernel/debug/:/sys/kernel/debug/ --rm harvester/toolbox:dev bash\\n\\n# test blktrace\\n6ffa8eda3aaf:/ $ blktrace -d /dev/nvme0n1 -o - | blkparse -i -\\n259,0 10 3414 0.020814875 34084 Q WS 2414127984 + 8 [fio]\\n259,0 10 3415 0.020815190 34084 G WS 2414127984 + 8 [fio]\\n259,0 10 3416 0.020815989 34084 C WS 3206896544 + 8 [0]\\n259,0 10 3417 0.020816652 34084 C WS 2140319184 + 8 [0]\\n259,0 10 3418 0.020817992 34084 P N [fio]\\n259,0 10 3419 0.020818227 34084 U N [fio] 1\\n259,0 10 3420 0.020818437 34084 D WS 2414127984 + 8 [fio]\\n259,0 10 3421 0.020821826 34084 Q WS 1743934904 + 8 [fio]\\n259,0 10 3422 0.020822150 34084 G WS 1743934904 + 8 [fio]\\n\\n```"},{"id":"scan-and-repair-vm-root-filesystem","metadata":{"permalink":"/kb/scan-and-repair-vm-root-filesystem","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-02-01/scan_and_repair_filesystem.md","source":"@site/kb/2023-02-01/scan_and_repair_filesystem.md","title":"Scan and Repair Root Filesystem of VirtualMachine","description":"Scan and repair root filesystem of VM","date":"2023-02-01T00:00:00.000Z","formattedDate":"February 1, 2023","tags":[{"label":"storage","permalink":"/kb/tags/storage"},{"label":"longhorn","permalink":"/kb/tags/longhorn"},{"label":"root","permalink":"/kb/tags/root"},{"label":"filesystem","permalink":"/kb/tags/filesystem"}],"readingTime":3.37,"truncated":false,"authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"frontMatter":{"title":"Scan and Repair Root Filesystem of VirtualMachine","description":"Scan and repair root filesystem of VM","slug":"scan-and-repair-vm-root-filesystem","authors":[{"name":"Vicente Cheng","title":"Senior Software Engineer","url":"https://github.com/Vicente-Cheng","image_url":"https://github.com/Vicente-Cheng.png","imageURL":"https://github.com/Vicente-Cheng.png"}],"tags":["storage","longhorn","root","filesystem"],"hide_table_of_contents":false},"prevItem":{"title":"Package your own Toolbox Image","permalink":"/kb/package_your_own_toolbox_image"},"nextItem":{"title":"Evicting Replicas From a Disk (the CLI way)","permalink":"/kb/evicting-replicas-from-a-disk-the-cli-way"}},"content":"In earlier versions of Harvester (v1.0.3 and prior), Longhorn volumes may get corrupted during the replica rebuilding process (reference: [Analysis: Potential Data/Filesystem Corruption](https://longhorn.io/kb/troubleshooting-volume-filesystem-corruption/#solution)). In Harvester v1.1.0 and later versions, the Longhorn team has fixed this issue. This article covers manual steps you can take to scan the VM\'s filesystem and repair it if needed.\\n\\n\\n## Stop The VM And Backup Volume\\n\\nBefore you scan the filesystem, it is recommend you back up the volume first. For an example, refer to the following steps to stop the VM and backup the volume.\\n\\n- Find the target VM.\\n\\n![finding the target VM](./imgs/finding_the_target_vm.png)\\n\\n- Stop the target VM.\\n\\n![Stop the target VM](./imgs/stop_the_target_vm.png)\\n\\nThe target VM is stopped and the related volumes are detached. Now go to the Longhorn UI to backup this volume.\\n\\n- Enable `Developer Tools & Features` (Preferences -> Enable Developer Tools & Features).\\n\\n![Preferences then enable developer mode](./imgs/preferences_enable_developer_mode.png)\\n![Enable the developer mode](./imgs/enable_the_developer_mode.png)\\n\\n- Click the `\u22ee` button and select **Edit Config** to edit the config page of the VM.\\n\\n![goto edit config page of VM](./imgs/goto_vm_edit_config_page.png)\\n\\n- Go to the `Volumes` tab and select `Check volume details.`\\n\\n![link to longhorn volume page](./imgs/link_to_longhorn_volume.png)\\n\\n- Click the dropdown menu on the right side and select \'Attach\' to attach the volume again. \\n\\n![attach this volume again](./imgs/attach_this_volume_again.png)\\n\\n- Select the attached node. \\n\\n![choose the attached node](./imgs/choose_the_attached_node.png)\\n\\n- Check the volume attached under `Volume Details` and select `Take Snapshot` on this volume page.\\n\\n![take snapshot on volume page](./imgs/take_snapshot_on_volume_page.png)\\n\\n- Confirm that the snapshot is ready.\\n\\n![check the snapshot is ready](./imgs/check_the_snapshot_is_ready.png)\\n\\nNow that you completed the volume backup, you need to scan and repair the root filesystem.\\n\\n## Scanning the root filesystem and repairing\\n\\nThis section will introduce how to scan the filesystem (e.g., XFS, EXT4) using related tools.\\n\\nBefore scanning, you need to know the filesystem\'s device/partition.\\n\\n- Identify the filesystem\'s device by checking the major and minor numbers of that device.\\n\\n1. Obtain the major and minor numbers from the listed volume information.\\n \\n In the following example, the volume name is `pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58`.\\n ```\\n harvester-node-0:~ # ls /dev/longhorn/pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58 -al\\n brw-rw---- 1 root root 8, 0 Oct 23 14:43 /dev/longhorn/pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58\\n ```\\n The output indicates that the major and minor numbers are `8:0`.\\n \\n2. Obtain the device name from the output of the `lsblk` command.\\n ```\\n harvester-node-0:~ # lsblk\\n NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS\\n loop0 7:0 0 3G 1 loop /\\n sda 8:0 0 40G 0 disk\\n \u251c\u2500sda1 8:1 0 2M 0 part\\n \u251c\u2500sda2 8:2 0 20M 0 part\\n \u2514\u2500sda3 8:3 0 40G 0 part\\n ```\\n The output indicates that `8:0` are the major and minor numbers of the device named `sda`. Therefore, `/dev/sda` is related to the volume named `pvc-ea7536c0-301f-479e-b2a2-e40ddc864b58`.\\n\\n- You should now know the filesystem\'s partition. In the example below, sda3 is the filesystem\'s partition.\\n- Use the Filesystem toolbox image to scan and repair.\\n\\n```\\n# docker run -it --rm --privileged registry.opensuse.org/isv/rancher/harvester/toolbox/main/fs-toolbox:latest -- bash\\n```\\n\\nThen we try to scan with this target device.\\n\\n### XFS\\n\\nWhen scanning an XFS filesystem, use the `xfs_repair` command and specify the problematic partition of the device.\\n\\nIn the following example, `/dev/sda3` is the problematic partition.\\n```\\n# xfs_repair -n /dev/sda3\\n```\\n\\nTo repair the corrupted partition, run the following command.\\n\\n```\\n# xfs_repair /dev/sda3\\n```\\n\\n### EXT4\\n\\nWhen scanning a EXT4 filesystem, use the `e2fsck` command as follows, where the `/dev/sde1` is the problematic partition of the device.\\n\\n```\\n# e2fsck -f /dev/sde1\\n```\\n\\nTo repair the corrupted partition, run the following command.\\n\\n```\\n# e2fsck -fp /dev/sde1\\n```\\n\\n\\nAfter using the \'e2fsck\' command, you should also see logs related to scanning and repairing the partition. Scanning and repairing the corrupted partition is successful if there are no errors in these logs. \\n\\n\\n## Detach and Start VM again.\\n\\nAfter the corrupted partition is scanned and repaired, detach the volume and try to start the related VM again.\\n\\n- Detach the volume from the Longhorn UI.\\n\\n![detach volume on longhorn UI](./imgs/detach_volume.png)\\n\\n- Start the related VM again from the Harvester UI.\\n\\n![Start VM again](./imgs/start_vm_again.png)\\n\\nYour VM should now work normally."},{"id":"evicting-replicas-from-a-disk-the-cli-way","metadata":{"permalink":"/kb/evicting-replicas-from-a-disk-the-cli-way","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2023-01-12/evict_replicas_from_a_disk.md","source":"@site/kb/2023-01-12/evict_replicas_from_a_disk.md","title":"Evicting Replicas From a Disk (the CLI way)","description":"Evicting replicas from a disk (the CLI way)","date":"2023-01-12T00:00:00.000Z","formattedDate":"January 12, 2023","tags":[{"label":"storage","permalink":"/kb/tags/storage"},{"label":"longhorn","permalink":"/kb/tags/longhorn"},{"label":"disk","permalink":"/kb/tags/disk"}],"readingTime":1.935,"truncated":false,"authors":[{"name":"Kiefer Chang","title":"Engineer Manager","url":"https://github.com/bk201","image_url":"https://github.com/bk201.png","imageURL":"https://github.com/bk201.png"}],"frontMatter":{"title":"Evicting Replicas From a Disk (the CLI way)","description":"Evicting replicas from a disk (the CLI way)","slug":"evicting-replicas-from-a-disk-the-cli-way","authors":[{"name":"Kiefer Chang","title":"Engineer Manager","url":"https://github.com/bk201","image_url":"https://github.com/bk201.png","imageURL":"https://github.com/bk201.png"}],"tags":["storage","longhorn","disk"],"hide_table_of_contents":false},"prevItem":{"title":"Scan and Repair Root Filesystem of VirtualMachine","permalink":"/kb/scan-and-repair-vm-root-filesystem"},"nextItem":{"title":"NIC Naming Scheme","permalink":"/kb/nic-naming-scheme"}},"content":"Harvester replicates volumes data across disks in a cluster. Before removing a disk, the user needs to evict replicas on the disk to other disks to preserve the volumes\' configured availability. For more information about eviction in Longhorn, please check [Evicting Replicas on Disabled Disks or Nodes](https://longhorn.io/docs/1.3.2/volumes-and-nodes/disks-or-nodes-eviction/).\\n\\n## Preparation\\n\\nThis document describes how to evict Longhorn disks using the `kubectl` command. Before that, users must ensure the environment is set up correctly.\\nThere are two recommended ways to do this:\\n\\n1. Log in to any management node and switch to root (`sudo -i`).\\n1. Download Kubeconfig file and use it locally\\n - Install `kubectl` and `yq` program manually.\\n - Open Harvester GUI, click `support` at the bottom left of the page and click `Download KubeConfig` to download the Kubeconfig file.\\n - Set the Kubeconfig file\'s path to `KUBECONFIG` environment variable. For example, `export KUBECONFIG=/path/to/kubeconfig`.\\n\\n\\n## Evicting replicas from a disk\\n\\n1. List Longhorn nodes (names are identical to Kubernetes nodes):\\n\\n ```\\n kubectl get -n longhorn-system nodes.longhorn.io\\n ```\\n\\n Sample output:\\n\\n ```\\n NAME READY ALLOWSCHEDULING SCHEDULABLE AGE\\n node1 True true True 24d\\n node2 True true True 24d\\n node3 True true True 24d\\n ```\\n\\n1. List disks on a node. Assume we want to evict replicas of a disk on `node1`:\\n\\n ```\\n kubectl get -n longhorn-system nodes.longhorn.io node1 -o yaml | yq e \'.spec.disks\'\\n ```\\n\\n Sample output:\\n\\n ```\\n default-disk-ed7af10f5b8356be:\\n allowScheduling: true\\n evictionRequested: false\\n path: /var/lib/harvester/defaultdisk\\n storageReserved: 36900254515\\n tags: []\\n ```\\n\\n1. Assume disk `default-disk-ed7af10f5b8356be` is the target we want to evict replicas out of.\\n\\n Edit the node:\\n ```\\n kubectl edit -n longhorn-system nodes.longhorn.io node1 \\n ```\\n\\n Update these two fields and save:\\n - `spec.disks..allowScheduling` to `false`\\n - `spec.disks..evictionRequested` to `true`\\n\\n Sample editing:\\n\\n ```\\n default-disk-ed7af10f5b8356be:\\n allowScheduling: false\\n evictionRequested: true\\n path: /var/lib/harvester/defaultdisk\\n storageReserved: 36900254515\\n tags: []\\n ```\\n\\n1. Wait for all replicas on the disk to be evicted.\\n\\n Get current scheduled replicas on the disk:\\n ```\\n kubectl get -n longhorn-system nodes.longhorn.io node1 -o yaml | yq e \'.status.diskStatus.default-disk-ed7af10f5b8356be.scheduledReplica\'\\n ```\\n\\n Sample output:\\n ```\\n pvc-86d3d212-d674-4c64-b69b-4a2eb1df2272-r-7b422db7: 5368709120\\n pvc-b06f0b09-f30c-4936-8a2a-425b993dd6cb-r-bb0fa6b3: 2147483648\\n pvc-b844bcc6-3b06-4367-a136-3909251cb560-r-08d1ab3c: 53687091200\\n pvc-ea6e0dff-f446-4a38-916a-b3bea522f51c-r-193ca5c6: 10737418240\\n ```\\n\\n Run the command repeatedly, and the output should eventually become an empty map:\\n ```\\n {}\\n ```\\n\\n This means Longhorn evicts replicas on the disk to other disks.\\n\\n :::note\\n \\n If a replica always stays in a disk, please open the [Longhorn GUI](https://docs.harvesterhci.io/v1.1/troubleshooting/harvester#access-embedded-rancher-and-longhorn-dashboards) and check if there is free space on other disks.\\n :::"},{"id":"nic-naming-scheme","metadata":{"permalink":"/kb/nic-naming-scheme","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2022-04-06/nic_naming_scheme.md","source":"@site/kb/2022-04-06/nic_naming_scheme.md","title":"NIC Naming Scheme","description":"NIC Naming Scheme changed after upgrading to v1.0.1","date":"2022-04-06T00:00:00.000Z","formattedDate":"April 6, 2022","tags":[{"label":"network","permalink":"/kb/tags/network"}],"readingTime":1.825,"truncated":false,"authors":[{"name":"Date Huang","title":"Software Engineer","url":"https://github.com/tjjh89017","image_url":"https://github.com/tjjh89017.png","imageURL":"https://github.com/tjjh89017.png"}],"frontMatter":{"title":"NIC Naming Scheme","descripion":"NIC Naming Scheme Change","slug":"nic-naming-scheme","authors":[{"name":"Date Huang","title":"Software Engineer","url":"https://github.com/tjjh89017","image_url":"https://github.com/tjjh89017.png","imageURL":"https://github.com/tjjh89017.png"}],"tags":["network"],"hide_table_of_contents":false},"prevItem":{"title":"Evicting Replicas From a Disk (the CLI way)","permalink":"/kb/evicting-replicas-from-a-disk-the-cli-way"},"nextItem":{"title":"Multiple NICs VM Connectivity","permalink":"/kb/multiple-nics-vm-connectivity"}},"content":"## NIC Naming Scheme changed after upgrading to v1.0.1\\n\\n`systemd` in OpenSUSE Leap 15.3 which is the base OS of Harvester is upgraded to `246.16-150300.7.39.1`. In this version, `systemd` will enable additional naming scheme `sle15-sp3` which is `v238` with `bridge_no_slot`. When there is a PCI bridge associated with NIC, `systemd` will never generate `ID_NET_NAME_SLOT` and naming policy in `/usr/lib/systemd/network/99-default.link` will fallback to `ID_NET_NAME_PATH`. According to this change, NIC names might be changed in your Harvester nodes during the upgrade process from `v1.0.0` to `v1.0.1-rc1` or above, and it will cause network issues that are associated with NIC names.\\n\\n## Effect Settings and Workaround\\n\\n### Startup Network Configuration\\n\\nNIC name changes will need to update the name in `/oem/99_custom.yaml`. You could use [migration script](https://github.com/harvester/upgrade-helpers/blob/main/hack/udev_v238_sle15-sp3.py) to change the NIC names which are associated with a PCI bridge.\\n\\n:::tip\\nYou could find an identical machine to test naming changes before applying the configuration to production machines\\n:::\\n\\nYou could simply execute the script with root account in `v1.0.0` via\\n```bash\\n# python3 udev_v238_sle15-sp3.py\\n```\\n\\nIt will output the patched configuration to the screen and you could compare it to the original one to ensure there is no exception. (e.g. We could use `vimdiff` to check the configuration)\\n```bash\\n# python3 udev_v238_sle15-spe3.py > /oem/test\\n# vimdiff /oem/test /oem/99_custom.yaml\\n```\\n\\nAfter checking the result, we could execute the script with `--really-want-to-do` to override the configuration. It will also back up the original configuration file with a timestamp before patching it.\\n```bash\\n# python3 udev_v238_sle15-sp3.py --really-want-to-do\\n```\\n\\n### Harvester VLAN Network Configuration\\n\\nIf your VLAN network is associated with NIC name directly without `bonding`, you will need to migrate `ClusterNetwork` and `NodeNetwork` with the previous section together.\\n\\n:::note\\nIf your VLAN network is associated with the `bonding` name in `/oem/99_custom.yaml`, you could skip this section.\\n:::\\n\\n#### Modify ClusterNetworks\\n\\nYou need to modify `ClusterNetworks` via \\n```bash\\n$ kubectl edit clusternetworks vlan\\n```\\nsearch this pattern\\n```yaml\\nconfig:\\n defaultPhysicalNIC: \\n```\\nand change to new NIC name\\n\\n#### Modify NodeNetworks\\n\\nYou need to modify `NodeNetworks` via\\n```bash\\n$ kubectl edit nodenetworks -vlan\\n```\\nsearch this pattern\\n```yaml\\nspec:\\n nic: \\n```\\nand change to new NIC name"},{"id":"multiple-nics-vm-connectivity","metadata":{"permalink":"/kb/multiple-nics-vm-connectivity","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2022-03-10/multiple_nics_vm_connectivity.md","source":"@site/kb/2022-03-10/multiple_nics_vm_connectivity.md","title":"Multiple NICs VM Connectivity","description":"What is the default behavior of a VM with multiple NICs","date":"2022-03-10T00:00:00.000Z","formattedDate":"March 10, 2022","tags":[{"label":"vm","permalink":"/kb/tags/vm"},{"label":"network","permalink":"/kb/tags/network"}],"readingTime":3.955,"truncated":false,"authors":[{"name":"Date Huang","title":"Software Engineer","url":"https://github.com/tjjh89017","image_url":"https://github.com/tjjh89017.png","imageURL":"https://github.com/tjjh89017.png"}],"frontMatter":{"title":"Multiple NICs VM Connectivity","descripion":"How to deal VMs with multiple NICs in Harvester","slug":"multiple-nics-vm-connectivity","authors":[{"name":"Date Huang","title":"Software Engineer","url":"https://github.com/tjjh89017","image_url":"https://github.com/tjjh89017.png","imageURL":"https://github.com/tjjh89017.png"}],"tags":["vm","network"],"hide_table_of_contents":false},"prevItem":{"title":"NIC Naming Scheme","permalink":"/kb/nic-naming-scheme"},"nextItem":{"title":"VM Scheduling","permalink":"/kb/vm-scheduling"}},"content":"## What is the default behavior of a VM with multiple NICs\\n\\nIn [some scenarios](https://github.com/harvester/harvester/issues/1059), you\'ll setup two or more NICs in your VM to serve different networking purposes. If all networks are setup by default with DHCP, you might get random connectivity issues. And while it might get fixed after rebooting the VM, it still will lose connection randomly after some period.\\n\\n## How-to identify connectivity issues\\n\\nIn a Linux VM, you can use commands from the `iproute2` package to identify the default route.\\n\\nIn your VM, execute the following command:\\n```bash\\nip route show default\\n```\\n:::tip\\nIf you get the `access denied` error, please run the command using `sudo`\\n:::\\n \\nThe output of this command will only show the default route with the gateway and VM IP of the primary network interface (`eth0` in the example below).\\n```\\ndefault via dev eth0 proto dhcp src metric 100\\n```\\n\\nHere is the full example:\\n```\\n$ ip route show default\\ndefault via 192.168.0.254 dev eth0 proto dhcp src 192.168.0.100 metric 100\\n```\\n\\nHowever, if the issue covered in this KB occurs, you\'ll only be able to connect to the VM via the VNC or serial console.\\n\\nOnce connected, you can run again the same command as before:\\n```bash\\n$ ip route show default\\n```\\n\\nHowever, this time you\'ll get a default route with an incorrect gateway IP.\\nFor example:\\n```\\ndefault via dev eth0 proto dhcp src metric 100\\n```\\n\\n## Why do connectivity issues occur randomly\\n\\nIn a standard setup, cloud-based VMs typically use DHCP for their NICs configuration. It will set an IP and a gateway for each NIC. Lastly, a default route to the gateway IP will also be added, so you can use its IP to connect to the VM.\\n\\nHowever, Linux distributions start multiple DHCP clients at the same time and do not have a **priority** system. This means that if you have two or more NICs configured with DHCP, the client will enter a **race condition** to configure the default route. And depending on the currently running Linux distribution DHCP script, there is no guarantee which default route will be configured.\\n\\nAs the default route might change in every DHCP renewing process or after every OS reboot, this will create network connectivity issues.\\n\\n## How to avoid the random connectivity issues\\n\\nYou can easily avoid these connectivity issues by having only one NIC attached to the VM and having only one IP and one gateway configured.\\n\\nHowever, for VMs in more complex infrastructures, it is often not possible to use just one NIC. For example, if your infrastructure has a storage network and a service network. For security reasons, the storage network will be isolated from the service network and have a separate subnet. In this case, you must have two NICs to connect to both the service and storage networks.\\n\\nYou can choose a solution below that meets your requirements and security policy.\\n\\n### Disable DHCP on secondary NIC\\n\\nAs mentioned above, the problem is caused by a `race condition` between two DHCP clients. One solution to avoid this problem is to disable DHCP for all NICs and configure them with static IPs only. Likewise, you can configure the secondary NIC with a static IP and keep the primary NIC enabled with DHCP.\\n\\n1. To configure the primary NIC with a static IP (`eth0` in this example), you can edit the file `/etc/sysconfig/network/ifcfg-eth0` with the following values:\\n\\n```\\nBOOTPROTO=\'static\'\\nIPADDR=\'192.168.0.100\'\\nNETMASK=\'255.255.255.0\'\\n```\\n\\nAlternatively, if you want to reserve the primary NIC using DHCP (`eth0` in this example), use the following values instead:\\n\\n```\\nBOOTPROTO=\'dhcp\'\\nDHCLIENT_SET_DEFAULT_ROUTE=\'yes\'\\n```\\n\\n\\n2. You need to configure the default route by editing the file `/etc/sysconfig/network/ifroute-eth0` (if you configured the primary NIC using DHCP, skip this step):\\n\\n\\n```\\n# Destination Dummy/Gateway Netmask Interface\\ndefault 192.168.0.254 - eth0\\n```\\n\\n:::warning\\nDo not put other default route for your secondary NIC\\n:::\\n \\n3. Finally, configure a static IP for the secondary NIC by editing the file `/etc/sysconfig/network/ifcfg-eth1`:\\n\\n```\\nBOOTPROTO=\'static\'\\nIPADDR=\'10.0.0.100\'\\nNETMASK=\'255.255.255.0\'\\n```\\n\\n#### Cloud-Init config\\n\\n```yaml\\nnetwork:\\n version: 1\\n config:\\n - type: physical\\n name: eth0\\n subnets:\\n - type: dhcp\\n - type: physical\\n name: eth1\\n subnets:\\n - type: static\\n address: 10.0.0.100/24\\n```\\n \\n### Disable secondary NIC default route from DHCP\\n\\nIf your secondary NIC requires to get its IP from DHCP, you\'ll need to disable the secondary NIC default route configuration.\\n\\n1. Confirm that the primary NIC configures its default route in the file `/etc/sysconfig/network/ifcfg-eth0`:\\n\\n```\\nBOOTPROTO=\'dhcp\'\\nDHCLIENT_SET_DEFAULT_ROUTE=\'yes\'\\n```\\n\\n2. Disable the secondary NIC default route configuration by editing the file `/etc/sysconfig/network/ifcfg-eth1`:\\n\\n```\\nBOOTPROTO=\'dhcp\'\\nDHCLIENT_SET_DEFAULT_ROUTE=\'no\'\\n```\\n\\n#### Cloud-Init config\\n\\nThis solution is not available in Cloud-Init. Cloud-Init didn\'t allow any option for DHCP."},{"id":"vm-scheduling","metadata":{"permalink":"/kb/vm-scheduling","editUrl":"https://github.com/harvester/harvesterhci.io/edit/main/kb/kb/2022-03-07/vm-scheduling.md","source":"@site/kb/2022-03-07/vm-scheduling.md","title":"VM Scheduling","description":"How does Harvester schedule VMs?","date":"2022-03-07T00:00:00.000Z","formattedDate":"March 7, 2022","tags":[{"label":"vm","permalink":"/kb/tags/vm"},{"label":"scheduling","permalink":"/kb/tags/scheduling"}],"readingTime":15.44,"truncated":false,"authors":[{"name":"PoAn Yang","title":"Software Engineer","url":"https://github.com/FrankYang0529","image_url":"https://github.com/FrankYang0529.png","imageURL":"https://github.com/FrankYang0529.png"}],"frontMatter":{"title":"VM Scheduling","description":"How does Harvester schedule VMs?","slug":"vm-scheduling","authors":[{"name":"PoAn Yang","title":"Software Engineer","url":"https://github.com/FrankYang0529","image_url":"https://github.com/FrankYang0529.png","imageURL":"https://github.com/FrankYang0529.png"}],"tags":["vm","scheduling"],"hide_table_of_contents":false},"prevItem":{"title":"Multiple NICs VM Connectivity","permalink":"/kb/multiple-nics-vm-connectivity"}},"content":"## How does Harvester schedule a VM?\\n\\nHarvester doesn\'t directly schedule a VM in Kubernetes, it relies on [KubeVirt](http://kubevirt.io/) to create the custom resource `VirtualMachine`. When the request to create a new VM is sent, a `VirtualMachineInstance` object is created and it creates the corresponding `Pod`.\\n\\nThe whole VM creation processt leverages `kube-scheduler`, which allows Harvester to use `nodeSelector`, `affinity`, and resources request/limitation to influence where a VM will be deployed.\\n\\n## How does kube-scheduler decide where to deploy a VM?\\n\\nFirst, `kube-scheduler` finds Nodes available to run a pod. After that, `kube-scheduler` scores each available Node by a list of [plugins](https://github.com/kubernetes/kubernetes/tree/v1.22.7/pkg/scheduler/framework/plugins) like [ImageLocality](https://github.com/kubernetes/kubernetes/blob/v1.22.7/pkg/scheduler/framework/plugins/imagelocality/image_locality.go), [InterPodAffinity](https://github.com/kubernetes/kubernetes/tree/v1.22.7/pkg/scheduler/framework/plugins/interpodaffinity), [NodeAffinity](https://github.com/kubernetes/kubernetes/tree/v1.22.7/pkg/scheduler/framework/plugins/nodeaffinity), etc. \\n\\nFinally, `kube-scheduler` calculates the scores from the plugins results for each Node, and select the Node with the highest score to deploy the Pod.\\n\\nFor example, let\'s say we have a three nodes Harvester cluster with 6 cores CPU and 16G RAM each, and we want to deploy a VM with 1 CPU and 1G RAM (without resources overcommit). \\n\\n`kube-scheduler` will summarize the scores, as displayed in _Table 1_ below, and will select the node with the highest score, `harvester-node-2` in this case, to deploy the VM.\\n\\n
\\n kube-scheduler logs\\n\\n```\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 0,\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 45,\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 46,\\n\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 4,\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 34,\\nvirt-launcher-vm-without-overcommit-75q9b -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 37,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=4\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=34\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=37\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=45\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=46\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" node=\\"harvester-node-0\\" score=1000358\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" node=\\"harvester-node-1\\" score=1000433\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" node=\\"harvester-node-2\\" score=1000437\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm-without-overcommit-75q9b\\", node \\"harvester-node-2\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm-without-overcommit-75q9b\\", node \\"harvester-node-2\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm-without-overcommit-75q9b\\" node=\\"harvester-node-2\\"\\n```\\n
\\n\\n**Table 1 - kube-scheduler scores example**\\n\\n| | harvester-node-0 | harvester-node-1 | harvester-node-2 |\\n|:-------------------------------:|:----------------:|:----------------:|:----------------:|\\n| ImageLocality | 54 | 54 | 54 |\\n| InterPodAffinity | 0 | 0 | 0 |\\n| NodeResourcesLeastAllocated | 4 | 34 | 37 |\\n| NodeAffinity | 0 | 0 | 0 |\\n| NodePreferAvoidPods | 1000000 | 1000000 | 1000000 |\\n| PodTopologySpread | 200 | 200 | 200 |\\n| TaintToleration | 100 | 100 | 100 |\\n| NodeResourcesBalancedAllocation | 0 | 45 | 46 |\\n| Total | 1000358 | 1000433 | 1000437 |\\n\\n## Why VMs are distributed unevenly with overcommit?\\n\\nWith resources overcommit, Harvester modifies the resources request. By default, the `overcommit` configuration is `{\\"cpu\\": 1600, \\"memory\\": 150, \\"storage\\": 200}`. This means that if we request a VM with 1 CPU and 1G RAM, its `resources.requests.cpu` will become `62m`. \\n\\n!!! note\\n The unit suffix `m` stands for \\"thousandth of a core.\\"\\n\\nTo explain it, let\'s take the case of CPU overcommit. The default value of 1 CPU is equal to 1000m CPU, and with the default overcommit configuration of `\\"cpu\\": 1600`, the CPU resource will be 16x smaller. Here is the calculation: `1000m * 100 / 1600 = 62m`.\\n\\nNow, we can see how overcommitting influences `kube-scheduler` scores.\\n\\nIn this example, we use a three nodes Harvester cluster with 6 cores and 16G RAM each. We will deploy two VMs with 1 CPU and 1G RAM, and we will compare the scores for both cases of \\"with-overcommit\\" and \\"without-overcommit\\" resources. \\n\\nThe results of both tables _Table 2_ and _Table 3_ can be explained as follow:\\n\\nIn the \\"with-overcommit\\" case, both VMs are deployed on `harvester-node-2`, however in the \\"without-overcommit\\" case, the VM1 is deployed on `harvester-node-2`, and VM2 is deployed on `harvester-node-1`. \\n\\nIf we look at the detailed scores, we\'ll see a variation of `Total Score` for `harvester-node-2` from `1000459` to `1000461` in the \\"with-overcommit\\" case, and `1000437` to `1000382` in the \\"without-overcommit case\\". It\'s because resources overcommit influences `request-cpu` and `request-memory`. \\n\\nIn the \\"with-overcommit\\" case, the `request-cpu` changes from `4412m` to `4474m`. The difference between the two numbers is `62m`, which is what we calculated above. However, in the \\"without-overcommit\\" case, we send **real** requests to `kube-scheduler`, so the `request-cpu` changes from `5350m` to `6350m`.\\n\\nFinally, since most plugins give the same scores for each node except `NodeResourcesBalancedAllocation` and `NodeResourcesLeastAllocated`, we\'ll see a difference of these two scores for each node.\\n\\nFrom the results, we can see the overcommit feature influences the final score of each Node, so VMs are distributed unevenly. Although the `harvester-node-2` score for VM 2 is higher than VM 1, it\'s not always increasing. In _Table 4_, we keep deploying VM with 1 CPU and 1G RAM, and we can see the score of `harvester-node-2` starts decreasing from 11th VM. The behavior of `kube-scheduler` depends on your cluster resources and the workload you deployed.\\n\\n
\\n kube-scheduler logs for vm1-with-overcommit\\n\\n```\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 0,\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 58,\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4412 memory:5581918208] ,score 59,\\n\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 5,\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 43,\\nvirt-launcher-vm1-with-overcommit-ljlmq -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4412 memory:5581918208] ,score 46,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=5\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=43\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=46\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=58\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=59\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" node=\\"harvester-node-0\\" score=1000359\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" node=\\"harvester-node-1\\" score=1000455\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" node=\\"harvester-node-2\\" score=1000459\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm1-with-overcommit-ljlmq\\", node \\"harvester-node-2\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm1-with-overcommit-ljlmq\\", node \\"harvester-node-2\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm1-with-overcommit-ljlmq\\" node=\\"harvester-node-2\\"\\n```\\n
\\n\\n
\\n kube-scheduler logs for vm2-with-overcommit\\n\\n```\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 0,\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 58,\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4474 memory:6476701696] ,score 64,\\n\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9022 memory:14807289856] ,score 5,\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4622 memory:5992960000] ,score 43,\\nvirt-launcher-vm2-with-overcommit-pwrx4 -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:4474 memory:6476701696] ,score 43,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=58\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=64\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=5\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=43\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=43\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" node=\\"harvester-node-0\\" score=1000359\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" node=\\"harvester-node-1\\" score=1000455\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" node=\\"harvester-node-2\\" score=1000461\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm2-with-overcommit-pwrx4\\", node \\"harvester-node-2\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm2-with-overcommit-pwrx4\\", node \\"harvester-node-2\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm2-with-overcommit-pwrx4\\" node=\\"harvester-node-2\\"\\n```\\n
\\n\\n
\\n kube-scheduler logs for vm1-without-overcommit\\n\\n```\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 0,\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 45,\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 46,\\n\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 4,\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 34,\\nvirt-launcher-vm1-with-overcommit-6xqmq -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5350 memory:5941231616] ,score 37,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=4\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=34\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=37\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=45\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=46\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" node=\\"harvester-node-0\\" score=1000358\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" node=\\"harvester-node-1\\" score=1000433\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" node=\\"harvester-node-2\\" score=1000437\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm1-with-overcommit-6xqmq\\", node \\"harvester-node-2\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm1-with-overcommit-6xqmq\\", node \\"harvester-node-2\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm1-with-overcommit-6xqmq\\" node=\\"harvester-node-2\\"\\n```\\n
\\n\\n
\\n kube-scheduler logs for vm2-without-overcommit\\n\\n```\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-0: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 0,\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-1: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 45,\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-2: NodeResourcesBalancedAllocation, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:6350 memory:7195328512] ,score 0,\\n\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-0: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:9960 memory:15166603264] ,score 4,\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-1: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:5560 memory:6352273408] ,score 34,\\nvirt-launcher-vm2-without-overcommit-mf5vk -> harvester-node-2: NodeResourcesLeastAllocated, map of allocatable resources map[cpu:6000 memory:16776437760], map of requested resources map[cpu:6350 memory:7195328512] ,score 28,\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-0\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-1\\" score=200\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"PodTopologySpread\\" node=\\"harvester-node-2\\" score=200\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-0\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-1\\" score=100\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"TaintToleration\\" node=\\"harvester-node-2\\" score=100\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-1\\" score=45\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesBalancedAllocation\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-0\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-1\\" score=54\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"ImageLocality\\" node=\\"harvester-node-2\\" score=54\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"InterPodAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-0\\" score=4\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-1\\" score=34\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeResourcesLeastAllocated\\" node=\\"harvester-node-2\\" score=28\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-0\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-1\\" score=0\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodeAffinity\\" node=\\"harvester-node-2\\" score=0\\n\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-0\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-1\\" score=1000000\\n\\"Plugin scored node for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" plugin=\\"NodePreferAvoidPods\\" node=\\"harvester-node-2\\" score=1000000\\n\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" node=\\"harvester-node-0\\" score=1000358\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" node=\\"harvester-node-1\\" score=1000433\\n\\"Calculated node\'s final score for pod\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" node=\\"harvester-node-2\\" score=1000382\\n\\nAssumePodVolumes for pod \\"default/virt-launcher-vm2-without-overcommit-mf5vk\\", node \\"harvester-node-1\\"\\nAssumePodVolumes for pod \\"default/virt-launcher-vm2-without-overcommit-mf5vk\\", node \\"harvester-node-1\\": all PVCs bound and nothing to do\\n\\"Attempting to bind pod to node\\" pod=\\"default/virt-launcher-vm2-without-overcommit-mf5vk\\" node=\\"harvester-node-1\\"\\n```\\n
\\n\\n**Table 2 - With Overcommit**\\n\\n| VM 1 / VM 2 | harvester-node-0 | harvester-node-1 | harvester-node-2 |\\n|:-------------------------------------:|--------------------------:|------------------------:|------------------------:|\\n| request-cpu (m) | 9022 / 9022 | 4622 / 4622 | **4412** / **4474** |\\n| request-memory | 14807289856 / 14807289856 | 5992960000 / 5992960000 | **5581918208** / **6476701696** |\\n| NodeResourcesBalancedAllocation Score | 0 / 0 | 58 / 58 | **59** / **64** |\\n| NodeResourcesLeastAllocated Score | 5 / 5 | 43 / 43 | **46** / **43** |\\n| Other Scores | 1000354 / 1000354 | 1000354 / 1000354 | 1000354 / 1000354 |\\n| Total Score | 1000359 / 1000359 | 1000455 / 1000455 | **1000459** / **1000461** |\\n\\n**Table 3 - Without Overcommit**\\n\\n| VM 1 / VM 2 | harvester-node-0 | harvester-node-1 | harvester-node-2 |\\n|:-------------------------------------:|--------------------------:|------------------------:|------------------------:|\\n| request-cpu (m) | 9960 / 9960 | 5560 / **5560** | **5350** / 6350 |\\n| request-memory | 15166603264 / 15166603264 | 6352273408 / **6352273408** | **5941231616** / 7195328512 |\\n| NodeResourcesBalancedAllocation Score | 0 / 0 | 45 / **45** | **46** / 0 |\\n| NodeResourcesLeastAllocated Score | 4 / 4 | 34 / **34** | **37** / 28 |\\n| Other Scores | 1000354 / 1000354 | 1000354 / **1000354** | **1000354** / 1000354 |\\n| Total Score | 1000358 / 1000358 | 1000358 / **1000433** | **1000437** / 1000382 |\\n\\n**Table 4**\\n\\n| Score | harvester-node-0 | harvester-node-1 | harvester-node-2 |\\n|:-----:|-----------------:|-----------------:|-----------------:|\\n| VM 1 | 1000359 | 1000455 | 1000459 |\\n| VM 2 | 1000359 | 1000455 | 1000461 |\\n| VM 3 | 1000359 | 1000455 | 1000462 |\\n| VM 4 | 1000359 | 1000455 | 1000462 |\\n| VM 5 | 1000359 | 1000455 | 1000463 |\\n| VM 6 | 1000359 | 1000455 | 1000465 |\\n| VM 7 | 1000359 | 1000455 | 1000466 |\\n| VM 8 | 1000359 | 1000455 | 1000467 |\\n| VM 9 | 1000359 | 1000455 | 1000469 |\\n| VM 10 | 1000359 | 1000455 | 1000469 |\\n| VM 11 | 1000359 | 1000455 | **1000465** |\\n| VM 12 | 1000359 | 1000455 | **1000457** |\\n\\n\\n## How to avoid uneven distribution of VMs?\\n\\nThere are many plugins in `kube-scheduler` which we can use to influence the scores. For example, we can add the `podAntiAffinity` plugin to avoid VMs with the same labels being deployed on the same node.\\n\\n```\\n affinity:\\n podAntiAffinity:\\n preferredDuringSchedulingIgnoredDuringExecution:\\n - podAffinityTerm:\\n labelSelector:\\n matchExpressions:\\n - key: harvesterhci.io/creator\\n operator: Exists\\n topologyKey: kubernetes.io/hostname\\n weight: 100\\n```\\n\\n## How to see scores in kube-scheduler?\\n\\n`kube-scheduler` is deployed as a static pod in Harvester. The file is under `/var/lib/rancher/rke2/agent/pod-manifests/kube-scheduler.yaml` in each Management Node. We can add `- --v=10` to the `kube-scheduler` container to show score logs.\\n\\n```\\nkind: Pod\\nmetadata:\\n labels:\\n component: kube-scheduler\\n tier: control-plane\\n name: kube-scheduler\\n namespace: kube-system\\nspec:\\n containers:\\n - command:\\n - kube-scheduler\\n # ...\\n - --v=10\\n```"}]}')}}]); \ No newline at end of file diff --git a/assets/js/7fd1b631.8b1ea9aa.js b/assets/js/7fd1b631.355e0309.js similarity index 80% rename from assets/js/7fd1b631.8b1ea9aa.js rename to assets/js/7fd1b631.355e0309.js index c9caf0fa..f8d03161 100644 --- a/assets/js/7fd1b631.8b1ea9aa.js +++ b/assets/js/7fd1b631.355e0309.js @@ -1 +1 @@ -"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[4507],{3562:function(e){e.exports=JSON.parse('{"permalink":"/kb/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":15,"previousPage":"/kb","nextPage":null,"blogDescription":"Blog","blogTitle":"Harvester HCI knowledge base"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[4507],{3562:function(e){e.exports=JSON.parse('{"permalink":"/kb/page/2","page":2,"postsPerPage":10,"totalPages":2,"totalCount":16,"previousPage":"/kb","nextPage":null,"blogDescription":"Blog","blogTitle":"Harvester HCI knowledge base"}')}}]); \ No newline at end of file diff --git a/assets/js/91cce478.0743eddd.js b/assets/js/91cce478.b6a34e80.js similarity index 80% rename from assets/js/91cce478.0743eddd.js rename to assets/js/91cce478.b6a34e80.js index 43245846..5eff5264 100644 --- a/assets/js/91cce478.0743eddd.js +++ b/assets/js/91cce478.b6a34e80.js @@ -1 +1 @@ -"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[1227],{8859:function(e){e.exports=JSON.parse('{"permalink":"/kb","page":1,"postsPerPage":10,"totalPages":2,"totalCount":15,"previousPage":null,"nextPage":"/kb/page/2","blogDescription":"Blog","blogTitle":"Harvester HCI knowledge base"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[1227],{8859:function(e){e.exports=JSON.parse('{"permalink":"/kb","page":1,"postsPerPage":10,"totalPages":2,"totalCount":16,"previousPage":null,"nextPage":"/kb/page/2","blogDescription":"Blog","blogTitle":"Harvester HCI knowledge base"}')}}]); \ No newline at end of file diff --git a/assets/js/96b7d83e.0f706d3b.js b/assets/js/96b7d83e.59ff2d58.js similarity index 52% rename from assets/js/96b7d83e.0f706d3b.js rename to assets/js/96b7d83e.59ff2d58.js index dde6abd0..a7010163 100644 --- a/assets/js/96b7d83e.0f706d3b.js +++ b/assets/js/96b7d83e.59ff2d58.js @@ -1 +1 @@ -"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[5396],{5389:function(e){e.exports=JSON.parse('{"permalink":"/kb/tags/harvester","page":1,"postsPerPage":10,"totalPages":1,"totalCount":10,"previousPage":null,"nextPage":null,"blogDescription":"Blog","blogTitle":"Harvester HCI knowledge base"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[5396],{5389:function(e){e.exports=JSON.parse('{"permalink":"/kb/tags/harvester","page":1,"postsPerPage":10,"totalPages":2,"totalCount":11,"previousPage":null,"nextPage":"/kb/tags/harvester/page/2","blogDescription":"Blog","blogTitle":"Harvester HCI knowledge base"}')}}]); \ No newline at end of file diff --git a/assets/js/bbd95991.9f8bccbc.js b/assets/js/bbd95991.9f5b50f0.js similarity index 75% rename from assets/js/bbd95991.9f8bccbc.js rename to assets/js/bbd95991.9f5b50f0.js index 1d843be6..f07816bd 100644 --- a/assets/js/bbd95991.9f8bccbc.js +++ b/assets/js/bbd95991.9f5b50f0.js @@ -1 +1 @@ -"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[8964],{7059:function(e){e.exports=JSON.parse('{"allTagsPath":"/kb/tags","slug":"/kb/tags/harvester","name":"harvester","count":10,"permalink":"/kb/tags/harvester"}')}}]); \ No newline at end of file +"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[8964],{7059:function(e){e.exports=JSON.parse('{"allTagsPath":"/kb/tags","slug":"/kb/tags/harvester","name":"harvester","count":11,"permalink":"/kb/tags/harvester"}')}}]); \ No newline at end of file diff --git a/assets/js/c4fb252f.477b0c9a.js b/assets/js/c4fb252f.477b0c9a.js new file mode 100644 index 00000000..ddffb44d --- /dev/null +++ b/assets/js/c4fb252f.477b0c9a.js @@ -0,0 +1 @@ +"use strict";(self.webpackChunkharvesterhci_io=self.webpackChunkharvesterhci_io||[]).push([[9443],{3905:function(e,t,n){n.d(t,{Zo:function(){return u},kt:function(){return d}});var r=n(7294);function a(e,t,n){return t in e?Object.defineProperty(e,t,{value:n,enumerable:!0,configurable:!0,writable:!0}):e[t]=n,e}function i(e,t){var n=Object.keys(e);if(Object.getOwnPropertySymbols){var r=Object.getOwnPropertySymbols(e);t&&(r=r.filter((function(t){return Object.getOwnPropertyDescriptor(e,t).enumerable}))),n.push.apply(n,r)}return n}function o(e){for(var t=1;t=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),h=s(n),d=a,m=h["".concat(l,".").concat(d)]||h[d]||p[d]||i;return n?r.createElement(m,o(o({ref:t},u),{},{components:n})):r.createElement(m,o({ref:t},u))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=h;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,o[1]=c;for(var s=2;s ${patch_file} <=0||(a[n]=e[n]);return a}(e,t);if(Object.getOwnPropertySymbols){var i=Object.getOwnPropertySymbols(e);for(r=0;r=0||Object.prototype.propertyIsEnumerable.call(e,n)&&(a[n]=e[n])}return a}var l=r.createContext({}),s=function(e){var t=r.useContext(l),n=t;return e&&(n="function"==typeof e?e(t):o(o({},t),e)),n},u=function(e){var t=s(e.components);return r.createElement(l.Provider,{value:t},e.children)},p={inlineCode:"code",wrapper:function(e){var t=e.children;return r.createElement(r.Fragment,{},t)}},h=r.forwardRef((function(e,t){var n=e.components,a=e.mdxType,i=e.originalType,l=e.parentName,u=c(e,["components","mdxType","originalType","parentName"]),h=s(n),d=a,m=h["".concat(l,".").concat(d)]||h[d]||p[d]||i;return n?r.createElement(m,o(o({ref:t},u),{},{components:n})):r.createElement(m,o({ref:t},u))}));function d(e,t){var n=arguments,a=t&&t.mdxType;if("string"==typeof e||a){var i=n.length,o=new Array(i);o[0]=h;var c={};for(var l in t)hasOwnProperty.call(t,l)&&(c[l]=t[l]);c.originalType=e,c.mdxType="string"==typeof e?e:a,o[1]=c;for(var s=2;s ${patch_file} <\n

Your Docusaurus site did not load properly.

\n

A very common reason is a wrong site baseUrl configuration.

\n

Current configured baseUrl = '+e+" "+("/"===e?" (default value)":"")+'

\n

We suggest trying baseUrl =

\n\n'}(e)).replace(/0)&&(F.current.unobserve(t),F.current.disconnect(),n())}))})),F.current.observe(t))},to:I||""},g&&{isActive:y,activeClassName:v}))}var g=o.forwardRef(m)},1875:function(e,t){"use strict";t.Z=function(){return null}},5999:function(e,t,n){"use strict";n.d(t,{Z:function(){return c},I:function(){return u}});var r=n(7294),a=/{\w+}/g,o="{}";function i(e,t){var n=[],i=e.replace(a,(function(e){var a=e.substring(1,e.length-1),i=null==t?void 0:t[a];if(void 0!==i){var l=r.isValidElement(i)?i:String(i);return n.push(l),o}return e}));return 0===n.length?e:n.every((function(e){return"string"==typeof e}))?i.split(o).reduce((function(e,t,r){var a;return e.concat(t).concat(null!=(a=n[r])?a:"")}),""):i.split(o).reduce((function(e,t,a){return[].concat(e,[r.createElement(r.Fragment,{key:a},t,n[a])])}),[])}var l=n(7529);function s(e){var t,n,r=e.id,a=e.message;if(void 0===r&&void 0===a)throw new Error("Docusaurus translation declarations must have at least a translation id or a default translation message");return null!=(t=null!=(n=l[null!=r?r:a])?n:a)?t:r}function u(e,t){return i(s({message:e.message,id:e.id}),t)}function c(e){var t=e.children,n=e.id,r=e.values;if(t&&"string"!=typeof t)throw console.warn("Illegal children",t),new Error("The Docusaurus component only accept simple string values");return i(s({message:t,id:n}),r)}},9913:function(e,t,n){"use strict";n.d(t,{_:function(){return a},t:function(){return o}});var r=n(7294),a=r.createContext(!1);function o(e){var t=e.children,n=(0,r.useState)(!1),o=n[0],i=n[1];return(0,r.useEffect)((function(){i(!0)}),[]),r.createElement(a.Provider,{value:o},t)}},9935:function(e,t,n){"use strict";n.d(t,{m:function(){return r}});var r="default"},7041:function(e,t,n){"use strict";n.d(t,{_:function(){return c},M:function(){return d}});var r=n(7294),a=n(9782),o=JSON.parse('{"docusaurus-plugin-content-docs":{"default":{"path":"/","versions":[{"name":"current","label":"Next","isLast":true,"path":"/","mainDocId":"intro","docs":[{"id":"authentication","path":"/authentication","sidebar":"tutorialSidebar"},{"id":"development/dev-mode","path":"/development/dev-mode","sidebar":"tutorialSidebar"},{"id":"harvester-network","path":"/harvester-network","sidebar":"tutorialSidebar"},{"id":"import-image","path":"/import-image","sidebar":"tutorialSidebar"},{"id":"installation/harvester-configuration","path":"/installation/harvester-configuration","sidebar":"tutorialSidebar"},{"id":"installation/iso-install","path":"/installation/iso-install","sidebar":"tutorialSidebar"},{"id":"installation/pxe-boot-install","path":"/installation/pxe-boot-install","sidebar":"tutorialSidebar"},{"id":"intro","path":"/intro","sidebar":"tutorialSidebar"},{"id":"rancher-intergration/node-driver","path":"/rancher-intergration/node-driver","sidebar":"tutorialSidebar"},{"id":"rancher-intergration/rancher-integration","path":"/rancher-intergration/rancher-integration","sidebar":"tutorialSidebar"},{"id":"upgrade","path":"/upgrade","sidebar":"tutorialSidebar"},{"id":"vm-management/access-to-the-vm","path":"/vm-management/access-to-the-vm","sidebar":"tutorialSidebar"},{"id":"vm-management/backup-restore","path":"/vm-management/backup-restore","sidebar":"tutorialSidebar"},{"id":"vm-management/create-vm","path":"/vm-management/create-vm","sidebar":"tutorialSidebar"},{"id":"vm-management/live-migration","path":"/vm-management/live-migration","sidebar":"tutorialSidebar"}],"sidebars":{"tutorialSidebar":{"link":{"path":"/intro","label":"intro"}}}}],"breadcrumbs":true}}}'),i=JSON.parse('{"defaultLocale":"en","locales":["en"],"currentLocale":"en","localeConfigs":{"en":{"label":"English","direction":"ltr","htmlLang":"en"}}}'),l=n(7529),s=JSON.parse('{"docusaurusVersion":"2.0.0-beta.17","siteVersion":"1.22.0","pluginVersions":{"docusaurus-plugin-content-docs":{"type":"package","name":"@docusaurus/plugin-content-docs","version":"2.0.0-beta.17"},"docusaurus-plugin-content-blog":{"type":"package","name":"@docusaurus/plugin-content-blog","version":"2.0.0-beta.17"},"docusaurus-plugin-content-pages":{"type":"package","name":"@docusaurus/plugin-content-pages","version":"2.0.0-beta.17"},"docusaurus-plugin-google-analytics":{"type":"package","name":"@docusaurus/plugin-google-analytics","version":"2.0.0-beta.17"},"docusaurus-plugin-sitemap":{"type":"package","name":"@docusaurus/plugin-sitemap","version":"2.0.0-beta.17"},"docusaurus-theme-classic":{"type":"package","name":"@docusaurus/theme-classic","version":"2.0.0-beta.17"}}}'),u={siteConfig:a.default,siteMetadata:s,globalData:o,i18n:i,codeTranslations:l},c=r.createContext(u);function d(e){var t=e.children;return r.createElement(c.Provider,{value:u},t)}},3919:function(e,t,n){"use strict";function r(e){return!0===/^(?:\w*:|\/\/)/.test(e)}function a(e){return void 0!==e&&!r(e)}n.d(t,{Z:function(){return a},b:function(){return r}})},8143:function(e,t,n){"use strict";n.r(t),n.d(t,{Redirect:function(){return r.l_},matchPath:function(){return r.LX},useHistory:function(){return r.k6},useLocation:function(){return r.TH}});var r=n(6775)},4996:function(e,t,n){"use strict";n.d(t,{C:function(){return o},Z:function(){return i}});var r=n(2263),a=n(3919);function o(){var e=(0,r.Z)().siteConfig,t=e.baseUrl,n=e.url;return{withBaseUrl:function(e,r){return function(e,t,n,r){var o=void 0===r?{}:r,i=o.forcePrependBaseUrl,l=void 0!==i&&i,s=o.absolute,u=void 0!==s&&s;if(!n)return n;if(n.startsWith("#"))return n;if((0,a.b)(n))return n;if(l)return t+n.replace(/^\//,"");var c=n.startsWith(t)?n:t+n.replace(/^\//,"");return u?e+c:c}(n,t,e,r)}}}function i(e,t){return void 0===t&&(t={}),(0,o().withBaseUrl)(e,t)}},2263:function(e,t,n){"use strict";n.d(t,{Z:function(){return o}});var r=n(7294),a=n(7041);function o(){return(0,r.useContext)(a._)}},8084:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return o},useAllPluginInstancesData:function(){return i},usePluginData:function(){return l}});var r=n(2263),a=n(9935);function o(){var e=(0,r.Z)().globalData;if(!e)throw new Error("Docusaurus global data not found.");return e}function i(e){var t=o()[e];if(!t)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin.');return t}function l(e,t){void 0===t&&(t=a.m);var n=i(e)[t];if(!n)throw new Error('Docusaurus plugin global data not found for "'+e+'" plugin with id "'+t+'".');return n}},2389:function(e,t,n){"use strict";n.d(t,{Z:function(){return o}});var r=n(7294),a=n(9913);function o(){return(0,r.useContext)(a._)}},9670:function(e,t,n){"use strict";n.d(t,{Z:function(){return r}});function r(e){var t={};return function e(n,r){Object.keys(n).forEach((function(a){var o,i=n[a],l=r?r+"."+a:a;"object"==typeof(o=i)&&o&&Object.keys(o).length>0?e(i,l):t[l]=i}))}(e),t}},4953:function(e,t,n){"use strict";n.d(t,{Z:function(){return l}});var r=n(7294),a=n(2773),o=n(780);function i(e){var t=e.error,n=e.tryAgain;return r.createElement("div",{style:{display:"flex",flexDirection:"column",justifyContent:"center",alignItems:"center",height:"50vh",width:"100%",fontSize:"20px"}},r.createElement("h1",null,"This page crashed."),r.createElement("p",null,t.message),r.createElement("button",{type:"button",onClick:n},"Try again"))}function l(e){var t=e.error,n=e.tryAgain;return r.createElement(o.Z,{fallback:function(){return r.createElement(i,{error:t,tryAgain:n})}},r.createElement(a.Z,{title:"Page Error"},r.createElement(i,{error:t,tryAgain:n})))}},8408:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getDocVersionSuggestions=t.getActiveDocContext=t.getActiveVersion=t.getLatestVersion=t.getActivePlugin=void 0;var r=n(8143);t.getActivePlugin=function(e,t,n){void 0===n&&(n={});var a=Object.entries(e).sort((function(e,t){return t[1].path.localeCompare(e[1].path)})).find((function(e){var n=e[1];return!!(0,r.matchPath)(t,{path:n.path,exact:!1,strict:!1})})),o=a?{pluginId:a[0],pluginData:a[1]}:void 0;if(!o&&n.failfast)throw new Error("Can't find active docs plugin for \""+t+'" pathname, while it was expected to be found. Maybe you tried to use a docs feature that can only be used on a docs-related page? Existing docs plugin paths are: '+Object.values(e).map((function(e){return e.path})).join(", "));return o};t.getLatestVersion=function(e){return e.versions.find((function(e){return e.isLast}))};t.getActiveVersion=function(e,n){var a=(0,t.getLatestVersion)(e);return[].concat(e.versions.filter((function(e){return e!==a})),[a]).find((function(e){return!!(0,r.matchPath)(n,{path:e.path,exact:!1,strict:!1})}))};t.getActiveDocContext=function(e,n){var a,o,i=(0,t.getActiveVersion)(e,n),l=null==i?void 0:i.docs.find((function(e){return!!(0,r.matchPath)(n,{path:e.path,exact:!0,strict:!1})}));return{activeVersion:i,activeDoc:l,alternateDocVersions:l?(a=l.id,o={},e.versions.forEach((function(e){e.docs.forEach((function(t){t.id===a&&(o[e.name]=t)}))})),o):{}}};t.getDocVersionSuggestions=function(e,n){var r=(0,t.getLatestVersion)(e),a=(0,t.getActiveDocContext)(e,n);return{latestDocSuggestion:null==a?void 0:a.alternateDocVersions[r.name],latestVersionSuggestion:r}}},5551:function(e,t,n){"use strict";t.Jo=t.Iw=t.zu=t.yW=t.gB=t.gA=t.zh=t._r=void 0;var r=n(655),a=n(8143),o=r.__importStar(n(8084)),i=n(8408),l={};t._r=function(){var e;return null!=(e=(0,o.default)()["docusaurus-plugin-content-docs"])?e:l};t.zh=function(e){return(0,o.usePluginData)("docusaurus-plugin-content-docs",e)};t.gA=function(e){void 0===e&&(e={});var n=(0,t._r)(),r=(0,a.useLocation)().pathname;return(0,i.getActivePlugin)(n,r,e)};t.gB=function(e){return(0,t.zh)(e).versions};t.yW=function(e){var n=(0,t.zh)(e);return(0,i.getLatestVersion)(n)};t.zu=function(e){var n=(0,t.zh)(e),r=(0,a.useLocation)().pathname;return(0,i.getActiveVersion)(n,r)};t.Iw=function(e){var n=(0,t.zh)(e),r=(0,a.useLocation)().pathname;return(0,i.getActiveDocContext)(n,r)};t.Jo=function(e){var n=(0,t.zh)(e),r=(0,a.useLocation)().pathname;return(0,i.getDocVersionSuggestions)(n,r)}},4367:function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var r=n(655).__importDefault(n(412));t.default=r.default.canUseDOM?{onRouteUpdate:function(e){var t=e.location;window.ga("set","page",t.pathname),window.ga("send","pageview")}}:null},541:function(e,t,n){"use strict";n.d(t,{Z:function(){return o}});var r=n(7294),a="iconExternalLink_I5OW";function o(e){var t=e.width,n=void 0===t?13.5:t,o=e.height,i=void 0===o?13.5:o;return r.createElement("svg",{width:n,height:i,"aria-hidden":"true",viewBox:"0 0 24 24",className:a},r.createElement("path",{fill:"currentColor",d:"M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"}))}},2773:function(e,t,n){"use strict";n.d(t,{Z:function(){return le}});var r=n(7294),a=n(6010),o=n(780),i=n(6775),l=n(5999),s=n(3725),u="skipToContent_ZgBM";function c(e){e.setAttribute("tabindex","-1"),e.focus(),e.removeAttribute("tabindex")}function d(){var e=(0,r.useRef)(null),t=(0,i.k6)().action;return(0,s.SL)((function(n){var r=n.location;e.current&&!r.hash&&"PUSH"===t&&c(e.current)})),r.createElement("div",{ref:e,role:"region"},r.createElement("a",{href:"#",className:u,onClick:function(e){e.preventDefault();var t=document.querySelector("main:first-of-type")||document.querySelector(".main-wrapper");t&&c(t)}},r.createElement(l.Z,{id:"theme.common.skipToMainContent",description:"The skip to content label used for accessibility, allowing to rapidly navigate to main content with keyboard tab/enter navigation"},"Skip to main content")))}var f=n(7462),p=n(3366),m=["width","height","color","strokeWidth","className"];function g(e){var t=e.width,n=void 0===t?21:t,a=e.height,o=void 0===a?21:a,i=e.color,l=void 0===i?"currentColor":i,s=e.strokeWidth,u=void 0===s?1.2:s,c=(e.className,(0,p.Z)(e,m));return r.createElement("svg",(0,f.Z)({viewBox:"0 0 15 15",width:n,height:o},c),r.createElement("g",{stroke:l,strokeWidth:u},r.createElement("path",{d:"M.75.75l13.5 13.5M14.25.75L.75 14.25"})))}var h="announcementBar_IbjG",b="announcementBarPlaceholder_NC_W",v="announcementBarClose_FG1z",y="announcementBarContent_KsVm";function k(){var e=(0,s.nT)(),t=e.isActive,n=e.close,o=(0,s.LU)().announcementBar;if(!t)return null;var i=o.content,u=o.backgroundColor,c=o.textColor,d=o.isCloseable;return r.createElement("div",{className:h,style:{backgroundColor:u,color:c},role:"banner"},d&&r.createElement("div",{className:b}),r.createElement("div",{className:y,dangerouslySetInnerHTML:{__html:i}}),d?r.createElement("button",{type:"button",className:(0,a.Z)("clean-btn close",v),onClick:n,"aria-label":(0,l.I)({id:"theme.AnnouncementBar.closeButtonAriaLabel",message:"Close",description:"The ARIA label for close button of announcement bar"})},r.createElement(g,{width:14,height:14,strokeWidth:3.1})):null)}var w=n(1875),E=n(2389);function S(e){return r.createElement("svg",(0,f.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"}))}function _(e){return r.createElement("svg",(0,f.Z)({viewBox:"0 0 24 24",width:24,height:24},e),r.createElement("path",{fill:"currentColor",d:"M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"}))}var x={toggle:"toggle_S7eR",toggleScreenReader:"toggleScreenReader_g2nN",toggleDisabled:"toggleDisabled_f9M3",toggleButton:"toggleButton_rCf9",darkToggleIcon:"darkToggleIcon_nQuB",lightToggleIcon:"lightToggleIcon_v35p"};function C(e){var t,n=e.className,o=e.checked,i=e.onChange,s=(0,E.Z)(),u=(0,r.useState)(o),c=u[0],d=u[1],f=(0,r.useState)(!1),p=f[0],m=f[1],g=(0,r.useRef)(null);return(0,r.useEffect)((function(){d(o)}),[o]),r.createElement("div",{className:(0,a.Z)(x.toggle,n,(t={},t[x.toggleChecked]=c,t[x.toggleFocused]=p,t[x.toggleDisabled]=!s,t))},r.createElement("div",{className:x.toggleButton,role:"button",tabIndex:-1,onClick:function(){var e;return null==(e=g.current)?void 0:e.click()}},r.createElement(S,{className:(0,a.Z)(x.toggleIcon,x.lightToggleIcon)}),r.createElement(_,{className:(0,a.Z)(x.toggleIcon,x.darkToggleIcon)})),r.createElement("input",{ref:g,checked:c,type:"checkbox",className:x.toggleScreenReader,"aria-label":(0,l.I)({message:"Switch between dark and light mode (currently {mode})",id:"theme.colorToggle.ariaLabel",description:"The ARIA label for the navbar color mode toggle"},{mode:c?(0,l.I)({message:"dark mode",id:"theme.colorToggle.ariaLabel.mode.dark",description:"The name for the dark color mode"}):(0,l.I)({message:"light mode",id:"theme.colorToggle.ariaLabel.mode.light",description:"The name for the light color mode"})}),onChange:i,onClick:function(){return d(!c)},onFocus:function(){return m(!0)},onBlur:function(){return m(!1)},onKeyDown:function(e){var t;"Enter"===e.key&&(null==(t=g.current)||t.click())}}))}var T=r.memo(C),A=n(5551),P=n(2207),L=n(5537),O=["width","height","className"];function R(e){var t=e.width,n=void 0===t?30:t,a=e.height,o=void 0===a?30:a,i=e.className,l=(0,p.Z)(e,O);return r.createElement("svg",(0,f.Z)({className:i,width:n,height:o,viewBox:"0 0 30 30","aria-hidden":"true"},l),r.createElement("path",{stroke:"currentColor",strokeLinecap:"round",strokeMiterlimit:"10",strokeWidth:"2",d:"M4 7h22M4 15h22M4 23h22"}))}var N={toggle:"toggle_TdHA",navbarHideable:"navbarHideable_aKYr",navbarHidden:"navbarHidden_KUhG",navbarSidebarToggle:"navbarSidebarToggle_nL8I"},I="right";function D(){return(0,s.LU)().navbar.items}function M(){var e=(0,s.LU)().colorMode.disableSwitch,t=(0,s.If)(),n=t.isDarkTheme,a=t.setLightTheme,o=t.setDarkTheme;return{isDarkTheme:n,toggle:(0,r.useCallback)((function(e){return e.target.checked?o():a()}),[a,o]),disabled:e}}function j(e){var t=e.sidebarShown,n=e.toggleSidebar;(0,s.Ni)(t);var o=D(),i=M(),u=function(e){var t,n=e.sidebarShown,a=e.toggleSidebar,o=null==(t=(0,s.g8)())?void 0:t({toggleSidebar:a}),i=(0,s.D9)(o),l=(0,r.useState)((function(){return!1})),u=l[0],c=l[1];(0,r.useEffect)((function(){o&&!i&&c(!0)}),[o,i]);var d=!!o;return(0,r.useEffect)((function(){d?n||c(!0):c(!1)}),[n,d]),{shown:u,hide:(0,r.useCallback)((function(){c(!1)}),[]),content:o}}({sidebarShown:t,toggleSidebar:n});return r.createElement("div",{className:"navbar-sidebar"},r.createElement("div",{className:"navbar-sidebar__brand"},r.createElement(L.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title"}),!i.disabled&&r.createElement(T,{className:N.navbarSidebarToggle,checked:i.isDarkTheme,onChange:i.toggle}),r.createElement("button",{type:"button",className:"clean-btn navbar-sidebar__close",onClick:n},r.createElement(g,{color:"var(--ifm-color-emphasis-600)",className:N.navbarSidebarCloseSvg}))),r.createElement("div",{className:(0,a.Z)("navbar-sidebar__items",{"navbar-sidebar__items--show-secondary":u.shown})},r.createElement("div",{className:"navbar-sidebar__item menu"},r.createElement("ul",{className:"menu__list"},o.map((function(e,t){return r.createElement(P.Z,(0,f.Z)({mobile:!0},e,{onClick:n,key:t}))})))),r.createElement("div",{className:"navbar-sidebar__item menu"},o.length>0&&r.createElement("button",{type:"button",className:"clean-btn navbar-sidebar__back",onClick:u.hide},r.createElement(l.Z,{id:"theme.navbar.mobileSidebarSecondaryMenu.backButtonLabel",description:"The label of the back button to return to main menu, inside the mobile navbar sidebar secondary menu (notably used to display the docs sidebar)"},"\u2190 Back to main menu")),u.content)))}function F(){var e,t=(0,s.LU)().navbar,n=t.hideOnScroll,o=t.style,i=function(){var e=(0,s.iP)(),t="mobile"===e,n=(0,r.useState)(!1),a=n[0],o=n[1];(0,s.Rb)((function(){if(a)return o(!1),!1}));var i=(0,r.useCallback)((function(){o((function(e){return!e}))}),[]);return(0,r.useEffect)((function(){"desktop"===e&&o(!1)}),[e]),{shouldRender:t,toggle:i,shown:a}}(),l=M(),u=(0,A.gA)(),c=(0,s.cK)(n),d=c.navbarRef,p=c.isNavbarVisible,m=D(),g=m.some((function(e){return"search"===e.type})),h=function(e){return{leftItems:e.filter((function(e){var t;return"left"===(null!=(t=e.position)?t:I)})),rightItems:e.filter((function(e){var t;return"right"===(null!=(t=e.position)?t:I)}))}}(m),b=h.leftItems,v=h.rightItems;return r.createElement("nav",{ref:d,className:(0,a.Z)("navbar","navbar--fixed-top",(e={"navbar--dark":"dark"===o,"navbar--primary":"primary"===o,"navbar-sidebar--show":i.shown},e[N.navbarHideable]=n,e[N.navbarHidden]=n&&!p,e))},r.createElement("div",{className:"navbar__inner"},r.createElement("div",{className:"navbar__items"},((null==m?void 0:m.length)>0||u)&&r.createElement("button",{"aria-label":"Navigation bar toggle",className:"navbar__toggle clean-btn",type:"button",tabIndex:0,onClick:i.toggle,onKeyDown:i.toggle},r.createElement(R,null)),r.createElement(L.Z,{className:"navbar__brand",imageClassName:"navbar__logo",titleClassName:"navbar__title"}),b.map((function(e,t){return r.createElement(P.Z,(0,f.Z)({},e,{key:t}))}))),r.createElement("div",{className:"navbar__items navbar__items--right"},v.map((function(e,t){return r.createElement(P.Z,(0,f.Z)({},e,{key:t}))})),!l.disabled&&r.createElement(T,{className:N.toggle,checked:l.isDarkTheme,onChange:l.toggle}),!g&&r.createElement(w.Z,null))),r.createElement("div",{role:"presentation",className:"navbar-sidebar__backdrop",onClick:i.toggle}),i.shouldRender&&r.createElement(j,{sidebarShown:i.shown,toggleSidebar:i.toggle}))}var B=n(9960),z=n(4996),U=n(3919),Z="footerLogoLink_RC3H",$=n(9750),H=n(541),q=["to","href","label","prependBaseUrlToHref"];function G(e){var t=e.to,n=e.href,a=e.label,o=e.prependBaseUrlToHref,i=(0,p.Z)(e,q),l=(0,z.Z)(t),s=(0,z.Z)(n,{forcePrependBaseUrl:!0});return r.createElement(B.Z,(0,f.Z)({className:"footer__link-item"},n?{href:o?s:n}:{to:l},i),n&&!(0,U.Z)(n)?r.createElement("span",null,a,r.createElement(H.Z,null)):a)}function V(e){var t=e.sources,n=e.alt,a=e.width,o=e.height;return r.createElement($.Z,{className:"footer__logo",alt:n,sources:t,width:a,height:o})}function W(e){var t=e.links;return r.createElement(r.Fragment,null,t.map((function(e,t){return r.createElement("div",{key:t,className:"col footer__col"},r.createElement("div",{className:"footer__title"},e.title),r.createElement("ul",{className:"footer__items"},e.items.map((function(e,t){return e.html?r.createElement("li",{key:t,className:"footer__item",dangerouslySetInnerHTML:{__html:e.html}}):r.createElement("li",{key:e.href||e.to,className:"footer__item"},r.createElement(G,e))}))))})))}function K(e){var t=e.links;return r.createElement("div",{className:"footer__links"},t.map((function(e,n){return r.createElement(r.Fragment,{key:n},e.html?r.createElement("span",{className:"footer__link-item",dangerouslySetInnerHTML:{__html:e.html}}):r.createElement(G,e),t.length!==n+1&&r.createElement("span",{className:"footer__link-separator"},"\xb7"))})))}function Y(){var e=(0,s.LU)().footer,t=e||{},n=t.copyright,o=t.links,i=void 0===o?[]:o,l=t.logo,u=void 0===l?{}:l,c={light:(0,z.Z)(u.src),dark:(0,z.Z)(u.srcDark||u.src)};return e?r.createElement("footer",{className:(0,a.Z)("footer",{"footer--dark":"dark"===e.style})},r.createElement("div",{className:"container container-fluid"},i&&i.length>0&&(function(e){return"title"in e[0]}(i)?r.createElement("div",{className:"row footer__links"},r.createElement(W,{links:i})):r.createElement("div",{className:"footer__links text--center"},r.createElement(K,{links:i}))),(u||n)&&r.createElement("div",{className:"footer__bottom text--center"},u&&(u.src||u.srcDark)&&r.createElement("div",{className:"margin-bottom--sm"},u.href?r.createElement(B.Z,{href:u.href,className:Z},r.createElement(V,{alt:u.alt,sources:c,width:u.width,height:u.height})):r.createElement(V,{alt:u.alt,sources:c,width:u.width,height:u.height})),n?r.createElement("div",{className:"footer__copyright",dangerouslySetInnerHTML:{__html:n}}):null))):null}var Q=r.memo(Y);function X(e){var t=e.children;return r.createElement(s.SG,null,r.createElement(s.pl,null,r.createElement(s.z5,null,r.createElement(s.OC,null,r.createElement(s.L5,null,r.createElement(s.Cn,null,t))))))}var J=n(5742),ee=n(2263);function te(e){var t=e.locale,n=e.version,a=e.tag,o=t;return r.createElement(J.Z,null,t&&r.createElement("meta",{name:"docusaurus_locale",content:t}),n&&r.createElement("meta",{name:"docusaurus_version",content:n}),a&&r.createElement("meta",{name:"docusaurus_tag",content:a}),o&&r.createElement("meta",{name:"docsearch:language",content:o}),n&&r.createElement("meta",{name:"docsearch:version",content:n}),a&&r.createElement("meta",{name:"docsearch:docusaurus_tag",content:a}))}var ne=n(1217);function re(){var e=(0,ee.Z)().i18n,t=e.defaultLocale,n=e.localeConfigs,a=(0,s.l5)();return r.createElement(J.Z,null,Object.entries(n).map((function(e){var t=e[0],n=e[1].htmlLang;return r.createElement("link",{key:t,rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:n})})),r.createElement("link",{rel:"alternate",href:a.createUrl({locale:t,fullyQualified:!0}),hrefLang:"x-default"}))}function ae(e){var t=e.permalink,n=(0,ee.Z)().siteConfig.url,a=function(){var e=(0,ee.Z)().siteConfig.url,t=(0,i.TH)().pathname;return e+(0,z.Z)(t)}(),o=t?""+n+t:a;return r.createElement(J.Z,null,r.createElement("meta",{property:"og:url",content:o}),r.createElement("link",{rel:"canonical",href:o}))}function oe(e){var t=(0,ee.Z)(),n=t.siteConfig.favicon,a=t.i18n,o=a.currentLocale,i=a.localeConfigs,l=(0,s.LU)(),u=l.metadata,c=l.image,d=e.title,p=e.description,m=e.image,g=e.keywords,h=e.searchMetadata,b=(0,z.Z)(n),v=(0,s.pe)(d),y=i[o],k=y.htmlLang,w=y.direction;return r.createElement(r.Fragment,null,r.createElement(J.Z,null,r.createElement("html",{lang:k,dir:w}),n&&r.createElement("link",{rel:"icon",href:b}),r.createElement("title",null,v),r.createElement("meta",{property:"og:title",content:v}),r.createElement("meta",{name:"twitter:card",content:"summary_large_image"}),r.createElement("body",{className:s.hC})),c&&r.createElement(ne.Z,{image:c}),m&&r.createElement(ne.Z,{image:m}),r.createElement(ne.Z,{description:p,keywords:g}),r.createElement(ae,null),r.createElement(re,null),r.createElement(te,(0,f.Z)({tag:s.HX,locale:o},h)),r.createElement(J.Z,null,u.map((function(e,t){return r.createElement("meta",(0,f.Z)({key:"metadata_"+t},e))}))))}function ie(e){var t=e.error,n=e.tryAgain;return r.createElement("main",{className:"container margin-vert--xl"},r.createElement("div",{className:"row"},r.createElement("div",{className:"col col--6 col--offset-3"},r.createElement("h1",{className:"hero__title"},r.createElement(l.Z,{id:"theme.ErrorPageContent.title",description:"The title of the fallback page when the page crashed"},"This page crashed.")),r.createElement("p",null,t.message),r.createElement("div",null,r.createElement("button",{type:"button",onClick:n},r.createElement(l.Z,{id:"theme.ErrorPageContent.tryAgain",description:"The label of the button to try again when the page crashed"},"Try again"))))))}function le(e){var t=e.children,n=e.noFooter,i=e.wrapperClassName,l=e.pageClassName;return(0,s.t$)(),r.createElement(X,null,r.createElement(oe,e),r.createElement(d,null),r.createElement(k,null),r.createElement(F,null),r.createElement("div",{className:(0,a.Z)(s.kM.wrapper.main,i,l)},r.createElement(o.Z,{fallback:ie},t)),!n&&r.createElement(Q,null))}},5537:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(7462),a=n(3366),o=n(7294),i=n(9960),l=n(9750),s=n(4996),u=n(2263),c=n(3725),d=["imageClassName","titleClassName"];function f(e){var t=(0,u.Z)().siteConfig.title,n=(0,c.LU)().navbar,f=n.title,p=n.logo,m=void 0===p?{src:""}:p,g=e.imageClassName,h=e.titleClassName,b=(0,a.Z)(e,d),v=(0,s.Z)(m.href||"/"),y={light:(0,s.Z)(m.src),dark:(0,s.Z)(m.srcDark||m.src)},k=o.createElement(l.Z,{sources:y,height:m.height,width:m.width,alt:m.alt||f||t});return o.createElement(i.Z,(0,r.Z)({to:v},b,m.target&&{target:m.target}),m.src&&(g?o.createElement("div",{className:g},k):k),null!=f&&o.createElement("b",{className:h},f))}},5525:function(e,t,n){"use strict";n.d(t,{Z:function(){return m}});var r=n(7462),a=n(3366),o=n(7294),i=n(6010),l=n(3072),s=n(1068),u=["className","isDropdownItem"],c=["className","isDropdownItem"],d=["mobile","position"];function f(e){var t=e.className,n=e.isDropdownItem,s=void 0!==n&&n,c=(0,a.Z)(e,u),d=o.createElement(l.Z,(0,r.Z)({className:(0,i.Z)(s?"dropdown__link":"navbar__item navbar__link",t)},c));return s?o.createElement("li",null,d):d}function p(e){var t=e.className,n=(e.isDropdownItem,(0,a.Z)(e,c));return o.createElement("li",{className:"menu__list-item"},o.createElement(l.Z,(0,r.Z)({className:(0,i.Z)("menu__link",t)},n)))}function m(e){var t,n=e.mobile,i=void 0!==n&&n,l=(e.position,(0,a.Z)(e,d)),u=i?p:f;return o.createElement(u,(0,r.Z)({},l,{activeClassName:null!=(t=l.activeClassName)?t:(0,s.E)(i)}))}},6400:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(7462),a=n(3366),o=n(7294),i=n(5525),l=n(5551),s=n(6010),u=n(1068),c=n(3725),d=["docId","label","docsPluginId"];function f(e){var t,n=e.docId,f=e.label,p=e.docsPluginId,m=(0,a.Z)(e,d),g=(0,l.Iw)(p),h=g.activeVersion,b=g.activeDoc,v=(0,c.J)(p).preferredVersion,y=(0,l.yW)(p),k=function(e,t){var n=e.flatMap((function(e){return e.docs})),r=n.find((function(e){return e.id===t}));if(!r){var a=n.map((function(e){return e.id})).join("\n- ");throw new Error("DocNavbarItem: couldn't find any doc with id \""+t+'" in version'+(e.length?"s":"")+" "+e.map((function(e){return e.name})).join(", ")+'".\nAvailable doc ids are:\n- '+a)}return r}((0,c.jj)([h,v,y].filter(Boolean)),n),w=(0,u.E)(m.mobile);return o.createElement(i.Z,(0,r.Z)({exact:!0},m,{className:(0,s.Z)(m.className,(t={},t[w]=(null==b?void 0:b.sidebar)&&b.sidebar===k.sidebar,t)),activeClassName:w,label:null!=f?f:k.id,to:k.path}))}},4792:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(7462),a=n(3366),o=n(7294),i=n(5525),l=n(5551),s=n(6010),u=n(1068),c=n(3725),d=["sidebarId","label","docsPluginId"];function f(e){var t,n=e.sidebarId,f=e.label,p=e.docsPluginId,m=(0,a.Z)(e,d),g=(0,l.Iw)(p),h=g.activeVersion,b=g.activeDoc,v=(0,c.J)(p).preferredVersion,y=(0,l.yW)(p),k=function(e,t){var n=e.flatMap((function(e){if(e.sidebars)return Object.entries(e.sidebars)})).filter((function(e){return!!e})),r=n.find((function(e){return e[0]===t}));if(!r)throw new Error("DocSidebarNavbarItem: couldn't find any sidebar with id \""+t+'" in version'+(e.length?"s":"")+" "+e.map((function(e){return e.name})).join(", ")+'".\nAvailable sidebar ids are:\n- '+Object.keys(n).join("\n- "));if(!r[1].link)throw new Error("DocSidebarNavbarItem: couldn't find any document for sidebar with id \""+t+'"');return r[1].link}((0,c.jj)([h,v,y].filter(Boolean)),n),w=(0,u.E)(m.mobile);return o.createElement(i.Z,(0,r.Z)({exact:!0},m,{className:(0,s.Z)(m.className,(t={},t[w]=(null==b?void 0:b.sidebar)===n,t)),activeClassName:w,label:null!=f?f:k.label,to:k.path}))}},9308:function(e,t,n){"use strict";n.d(t,{Z:function(){return p}});var r=n(7462),a=n(3366),o=n(7294),i=n(5525),l=n(3154),s=n(5551),u=n(3725),c=n(5999),d=["mobile","docsPluginId","dropdownActiveClassDisabled","dropdownItemsBefore","dropdownItemsAfter"],f=function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))};function p(e){var t,n,p=e.mobile,m=e.docsPluginId,g=e.dropdownActiveClassDisabled,h=e.dropdownItemsBefore,b=e.dropdownItemsAfter,v=(0,a.Z)(e,d),y=(0,s.Iw)(m),k=(0,s.gB)(m),w=(0,s.yW)(m),E=(0,u.J)(m),S=E.preferredVersion,_=E.savePreferredVersionName;var x,C=(x=k.map((function(e){var t=(null==y?void 0:y.alternateDocVersions[e.name])||f(e);return{isNavLink:!0,label:e.label,to:t.path,isActive:function(){return e===(null==y?void 0:y.activeVersion)},onClick:function(){_(e.name)}}})),[].concat(h,x,b)),T=null!=(t=null!=(n=y.activeVersion)?n:S)?t:w,A=p&&C.length>1?(0,c.I)({id:"theme.navbar.mobileVersionsDropdown.label",message:"Versions",description:"The label for the navbar versions dropdown on mobile view"}):T.label,P=p&&C.length>1?void 0:f(T).path;return C.length<=1?o.createElement(i.Z,(0,r.Z)({},v,{mobile:p,label:A,to:P,isActive:g?function(){return!1}:void 0})):o.createElement(l.Z,(0,r.Z)({},v,{mobile:p,label:A,to:P,items:C,isActive:g?function(){return!1}:void 0}))}},7250:function(e,t,n){"use strict";n.d(t,{Z:function(){return c}});var r=n(7462),a=n(3366),o=n(7294),i=n(5525),l=n(5551),s=n(3725),u=["label","to","docsPluginId"];function c(e){var t,n=e.label,c=e.to,d=e.docsPluginId,f=(0,a.Z)(e,u),p=(0,l.zu)(d),m=(0,s.J)(d).preferredVersion,g=(0,l.yW)(d),h=null!=(t=null!=p?p:m)?t:g,b=null!=n?n:h.label,v=null!=c?c:function(e){return e.docs.find((function(t){return t.id===e.mainDocId}))}(h).path;return o.createElement(i.Z,(0,r.Z)({},f,{label:b,to:v}))}},3154:function(e,t,n){"use strict";n.d(t,{Z:function(){return h}});var r=n(7462),a=n(3366),o=n(7294),i=n(6010),l=n(3725),s=n(3072),u=n(2207),c=["items","position","className"],d=["items","className","position"],f=["mobile"];function p(e,t){return e.some((function(e){return function(e,t){return!!(0,l.Mg)(e.to,t)||!!(0,l.Fx)(e.activeBaseRegex,t)||!(!e.activeBasePath||!t.startsWith(e.activeBasePath))}(e,t)}))}function m(e){var t,n=e.items,l=e.position,d=e.className,f=(0,a.Z)(e,c),p=(0,o.useRef)(null),m=(0,o.useState)(!1),g=m[0],h=m[1];return(0,o.useEffect)((function(){var e=function(e){p.current&&!p.current.contains(e.target)&&h(!1)};return document.addEventListener("mousedown",e),document.addEventListener("touchstart",e),function(){document.removeEventListener("mousedown",e),document.removeEventListener("touchstart",e)}}),[p]),o.createElement("div",{ref:p,className:(0,i.Z)("navbar__item","dropdown","dropdown--hoverable",{"dropdown--right":"right"===l,"dropdown--show":g})},o.createElement(s.Z,(0,r.Z)({href:f.to?void 0:"#",className:(0,i.Z)("navbar__link",d)},f,{onClick:f.to?void 0:function(e){return e.preventDefault()},onKeyDown:function(e){"Enter"===e.key&&(e.preventDefault(),h(!g))}}),null!=(t=f.children)?t:f.label),o.createElement("ul",{className:"dropdown__menu"},n.map((function(e,t){return o.createElement(u.Z,(0,r.Z)({isDropdownItem:!0,onKeyDown:function(e){if(t===n.length-1&&"Tab"===e.key){e.preventDefault(),h(!1);var r=p.current.nextElementSibling;r&&r.focus()}},activeClassName:"dropdown__link--active"},e,{key:t}))}))))}function g(e){var t,n=e.items,c=e.className,f=(e.position,(0,a.Z)(e,d)),m=(0,l.be)(),g=p(n,m),h=(0,l.uR)({initialState:function(){return!g}}),b=h.collapsed,v=h.toggleCollapsed,y=h.setCollapsed;return(0,o.useEffect)((function(){g&&y(!g)}),[m,g,y]),o.createElement("li",{className:(0,i.Z)("menu__list-item",{"menu__list-item--collapsed":b})},o.createElement(s.Z,(0,r.Z)({role:"button",className:(0,i.Z)("menu__link menu__link--sublist",c)},f,{onClick:function(e){e.preventDefault(),v()}}),null!=(t=f.children)?t:f.label),o.createElement(l.zF,{lazy:!0,as:"ul",className:"menu__list",collapsed:b},n.map((function(e,t){return o.createElement(u.Z,(0,r.Z)({mobile:!0,isDropdownItem:!0,onClick:f.onClick,activeClassName:"menu__link--active"},e,{key:t}))}))))}function h(e){var t=e.mobile,n=void 0!==t&&t,r=(0,a.Z)(e,f),i=n?g:m;return o.createElement(i,r)}},3072:function(e,t,n){"use strict";n.d(t,{Z:function(){return f}});var r=n(7462),a=n(3366),o=n(7294),i=n(9960),l=n(4996),s=n(541),u=n(3919),c=n(3725),d=["activeBasePath","activeBaseRegex","to","href","label","activeClassName","prependBaseUrlToHref"];function f(e){var t,n=e.activeBasePath,f=e.activeBaseRegex,p=e.to,m=e.href,g=e.label,h=e.activeClassName,b=void 0===h?"":h,v=e.prependBaseUrlToHref,y=(0,a.Z)(e,d),k=(0,l.Z)(p),w=(0,l.Z)(n),E=(0,l.Z)(m,{forcePrependBaseUrl:!0}),S=g&&m&&!(0,u.Z)(m),_="dropdown__link--active"===b;return o.createElement(i.Z,(0,r.Z)({},m?{href:v?E:m}:Object.assign({isNavLink:!0,activeClassName:null!=(t=y.className)&&t.includes(b)?"":b,to:k},n||f?{isActive:function(e,t){return f?(0,c.Fx)(f,t.pathname):t.pathname.startsWith(w)}}:null),y),S?o.createElement("span",null,g,o.createElement(s.Z,_&&{width:12,height:12})):g)}},2207:function(e,t,n){"use strict";n.d(t,{Z:function(){return k}});var r=n(3366),a=n(7294),o=n(5525),i=n(3154),l=n(7462),s=["width","height"];function u(e){var t=e.width,n=void 0===t?20:t,o=e.height,i=void 0===o?20:o,u=(0,r.Z)(e,s);return a.createElement("svg",(0,l.Z)({viewBox:"0 0 24 24",width:n,height:i,"aria-hidden":!0},u),a.createElement("path",{fill:"currentColor",d:"M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"}))}var c=n(2263),d=n(3725),f=n(5999),p="iconLanguage_dNtB",m=["mobile","dropdownItemsBefore","dropdownItemsAfter"];function g(e){var t=e.mobile,n=e.dropdownItemsBefore,o=e.dropdownItemsAfter,s=(0,r.Z)(e,m),g=(0,c.Z)().i18n,h=g.currentLocale,b=g.locales,v=g.localeConfigs,y=(0,d.l5)();function k(e){return v[e].label}var w=b.map((function(e){var t="pathname://"+y.createUrl({locale:e,fullyQualified:!1});return{isNavLink:!0,label:k(e),to:t,target:"_self",autoAddBaseUrl:!1,className:e===h?"dropdown__link--active":""}})),E=[].concat(n,w,o),S=t?(0,f.I)({message:"Languages",id:"theme.navbar.mobileLanguageDropdown.label",description:"The label for the mobile language switcher dropdown"}):k(h);return a.createElement(i.Z,(0,l.Z)({},s,{mobile:t,label:a.createElement("span",null,a.createElement(u,{className:p}),a.createElement("span",null,S)),items:E}))}var h=n(1875);function b(e){return e.mobile?null:a.createElement(h.Z,null)}var v=["type"],y={default:function(){return o.Z},localeDropdown:function(){return g},search:function(){return b},dropdown:function(){return i.Z},docsVersion:function(){return n(7250).Z},docsVersionDropdown:function(){return n(9308).Z},doc:function(){return n(6400).Z},docSidebar:function(){return n(4792).Z}};function k(e){var t=e.type,n=(0,r.Z)(e,v),o=function(e,t){return e&&"default"!==e?e:t?"dropdown":"default"}(t,void 0!==n.items),i=function(e){var t=y[e];if(!t)throw new Error('No NavbarItem component found for type "'+e+'".');return t()}(o);return a.createElement(i,n)}},1068:function(e,t,n){"use strict";n.d(t,{E:function(){return r}});var r=function(e){return e?"menu__link--active":"navbar__link--active"}},1217:function(e,t,n){"use strict";n.d(t,{Z:function(){return l}});var r=n(7294),a=n(5742),o=n(3725),i=n(4996);function l(e){var t=e.title,n=e.description,l=e.keywords,s=e.image,u=e.children,c=(0,o.pe)(t),d=(0,i.C)().withBaseUrl,f=s?d(s,{absolute:!0}):void 0;return r.createElement(a.Z,null,t&&r.createElement("title",null,c),t&&r.createElement("meta",{property:"og:title",content:c}),n&&r.createElement("meta",{name:"description",content:n}),n&&r.createElement("meta",{property:"og:description",content:n}),l&&r.createElement("meta",{name:"keywords",content:Array.isArray(l)?l.join(","):l}),f&&r.createElement("meta",{property:"og:image",content:f}),f&&r.createElement("meta",{name:"twitter:image",content:f}),u)}},9750:function(e,t,n){"use strict";n.d(t,{Z:function(){return d}});var r=n(7462),a=n(3366),o=n(7294),i=n(6010),l=n(2389),s=n(3725),u={themedImage:"themedImage_W2Cr","themedImage--light":"themedImage--light_TfLj","themedImage--dark":"themedImage--dark_oUvU"},c=["sources","className","alt"];function d(e){var t=(0,l.Z)(),n=(0,s.If)().isDarkTheme,d=e.sources,f=e.className,p=e.alt,m=void 0===p?"":p,g=(0,a.Z)(e,c),h=t?n?["dark"]:["light"]:["light","dark"];return o.createElement(o.Fragment,null,h.map((function(e){return o.createElement("img",(0,r.Z)({key:e,src:d[e],alt:m,className:(0,i.Z)(u.themedImage,u["themedImage--"+e],f)},g))})))}},467:function(e,t,n){"use strict";n.r(t),n.d(t,{default:function(){return a}});var r=n(9782);function a(e){var t=r.default.themeConfig.prism.additionalLanguages;globalThis.Prism=e,t.forEach((function(e){n(6726)("./prism-"+e)})),delete globalThis.Prism}},2448:function(e,t,n){"use strict";var r=a(n(7410));function a(e){return e&&e.__esModule?e:{default:e}}(0,a(n(467)).default)(r.default)},3725:function(e,t,n){"use strict";n.d(t,{pl:function(){return et},zF:function(){return Re},SG:function(){return Ot},HX:function(){return ce},PO:function(){return Ue},D_:function(){return k},L5:function(){return K},bT:function(){return B},qu:function(){return M},Cv:function(){return Ge},Cn:function(){return $e},OC:function(){return ht},z5:function(){return Mt},kM:function(){return We},os:function(){return de},Wl:function(){return U},_F:function(){return Z},Fx:function(){return kt},Mg:function(){return R},hC:function(){return Ft},PZ:function(){return ot},bc:function(){return le},Vo:function(){return se},nZ:function(){return ue},MA:function(){return at},jj:function(){return Ve},l5:function(){return A},nT:function(){return tt},uR:function(){return _e},If:function(){return Rt},fP:function(){return w},J:function(){return X},Vq:function(){return z},E6:function(){return j},b9:function(){return mt},cK:function(){return jt},Rb:function(){return it},Ns:function(){return Et},t$:function(){return Bt},be:function(){return nt},SL:function(){return ye},Ni:function(){return Zt},g8:function(){return qe},c2:function(){return be},D9:function(){return ve},pJ:function(){return Ut},RF:function(){return yt},s1:function(){return $},Si:function(){return ct},LU:function(){return a},pe:function(){return fe},iP:function(){return Vt}});var r=n(2263);function a(){return(0,r.Z)().siteConfig.themeConfig}var o=n(7294);function i(e){return i="function"==typeof Symbol&&"symbol"==typeof Symbol.iterator?function(e){return typeof e}:function(e){return e&&"function"==typeof Symbol&&e.constructor===Symbol&&e!==Symbol.prototype?"symbol":typeof e},i(e)}var l=n(9611);function s(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function");e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,writable:!0,configurable:!0}}),Object.defineProperty(e,"prototype",{writable:!1}),t&&(0,l.Z)(e,t)}function u(){u=function(e,t){return new n(e,void 0,t)};var e=RegExp.prototype,t=new WeakMap;function n(e,r,a){var o=new RegExp(e,r);return t.set(o,a||t.get(e)),(0,l.Z)(o,n.prototype)}function r(e,n){var r=t.get(n);return Object.keys(r).reduce((function(t,n){return t[n]=e[r[n]],t}),Object.create(null))}return s(n,RegExp),n.prototype.exec=function(t){var n=e.exec.call(this,t);return n&&(n.groups=r(n,this)),n},n.prototype[Symbol.replace]=function(n,a){if("string"==typeof a){var o=t.get(this);return e[Symbol.replace].call(this,n,a.replace(/\$<([^>]+)>/g,(function(e,t){return"$"+o[t]})))}if("function"==typeof a){var l=this;return e[Symbol.replace].call(this,n,(function(){var e=arguments;return"object"!=i(e[e.length-1])&&(e=[].slice.call(e)).push(r(e,l)),a.apply(this,e)}))}return e[Symbol.replace].call(this,n,a)},u.apply(this,arguments)}var c=n(4578);function d(e){return d=Object.setPrototypeOf?Object.getPrototypeOf:function(e){return e.__proto__||Object.getPrototypeOf(e)},d(e)}function f(){if("undefined"==typeof Reflect||!Reflect.construct)return!1;if(Reflect.construct.sham)return!1;if("function"==typeof Proxy)return!0;try{return Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],(function(){}))),!0}catch(e){return!1}}function p(e,t,n){return p=f()?Reflect.construct:function(e,t,n){var r=[null];r.push.apply(r,t);var a=new(Function.bind.apply(e,r));return n&&(0,l.Z)(a,n.prototype),a},p.apply(null,arguments)}function m(e){var t="function"==typeof Map?new Map:void 0;return m=function(e){if(null===e||(n=e,-1===Function.toString.call(n).indexOf("[native code]")))return e;var n;if("function"!=typeof e)throw new TypeError("Super expression must either be null or a function");if(void 0!==t){if(t.has(e))return t.get(e);t.set(e,r)}function r(){return p(e,arguments,d(this).constructor)}return r.prototype=Object.create(e.prototype,{constructor:{value:r,enumerable:!1,writable:!0,configurable:!0}}),(0,l.Z)(r,e)},m(e)}var g="undefined"!=typeof window?o.useLayoutEffect:o.useEffect;function h(e){var t=(0,o.useRef)(e);return g((function(){t.current=e}),[e]),(0,o.useCallback)((function(){return t.current.apply(t,arguments)}),[])}var b=function(e){function t(t,n){var r,a,o,i;return(i=e.call(this)||this).name="ReactContextError",i.message="Hook "+(null==(r=i.stack)||null==(a=r.split("\n")[1])||null==(o=a.match(u(/at (\w+)/,{name:1})))?void 0:o.groups.name)+" is called outside the <"+t+">. "+(n||""),i}return(0,c.Z)(t,e),t}(m(Error)),v=Symbol("EmptyContext"),y=o.createContext(v);function k(e){var t=e.children,n=(0,o.useState)(null),r=n[0],a=n[1],i=(0,o.useMemo)((function(){return{expandedItem:r,setExpandedItem:a}}),[r]);return o.createElement(y.Provider,{value:i},t)}function w(){var e=(0,o.useContext)(y);if(e===v)throw new b("DocSidebarItemsExpandedStateProvider");return e}var E="localStorage";function S(e){if(void 0===e&&(e=E),"undefined"==typeof window)throw new Error("Browser storage is not available on Node.js/Docusaurus SSR process.");if("none"===e)return null;try{return window[e]}catch(n){return t=n,_||(console.warn("Docusaurus browser storage is not available.\nPossible reasons: running Docusaurus in an iframe, in an incognito browser session, or using too strict browser privacy settings.",t),_=!0),null}var t}var _=!1;var x={get:function(){return null},set:function(){},del:function(){}};var C=function(e,t){if("undefined"==typeof window)return function(e){function t(){throw new Error('Illegal storage API usage for storage key "'+e+'".\nDocusaurus storage APIs are not supposed to be called on the server-rendering process.\nPlease only call storage APIs in effects and event handlers.')}return{get:t,set:t,del:t}}(e);var n=S(null==t?void 0:t.persistence);return null===n?x:{get:function(){try{return n.getItem(e)}catch(t){return console.error("Docusaurus storage error, can't get key="+e,t),null}},set:function(t){try{n.setItem(e,t)}catch(r){console.error("Docusaurus storage error, can't set "+e+"="+t,r)}},del:function(){try{n.removeItem(e)}catch(t){console.error("Docusaurus storage error, can't delete key="+e,t)}}}};var T=n(6775);function A(){var e=(0,r.Z)(),t=e.siteConfig,n=t.baseUrl,a=t.url,o=e.i18n,i=o.defaultLocale,l=o.currentLocale,s=(0,T.TH)().pathname,u=l===i?n:n.replace("/"+l+"/","/"),c=s.replace(n,"");return{createUrl:function(e){var t=e.locale;return""+(e.fullyQualified?a:"")+function(e){return e===i?""+u:""+u+e+"/"}(t)+c}}}var P=n(5551);function L(e,t){(null==t||t>e.length)&&(t=e.length);for(var n=0,r=new Array(t);n=e.length?{done:!0}:{done:!1,value:e[r++]}}}throw new TypeError("Invalid attempt to iterate non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method.")}var R=function(e,t){var n=function(e){var t;return null==(t=!e||null!=e&&e.endsWith("/")?e:e+"/")?void 0:t.toLowerCase()};return n(e)===n(t)},N=!!P._r,I=Symbol("EmptyContext"),D=(0,o.createContext)(I);function M(e){var t=e.children,n=e.version;return o.createElement(D.Provider,{value:n},t)}function j(){var e=(0,o.useContext)(D);if(e===I)throw new b("DocsVersionProvider");return e}var F=(0,o.createContext)(I);function B(e){var t=e.children,n=e.sidebar;return o.createElement(F.Provider,{value:n},t)}function z(){var e=(0,o.useContext)(F);if(e===I)throw new b("DocsSidebarProvider");return e}function U(e){if(e.href)return e.href;for(var t,n=O(e.items);!(t=n()).done;){var r=t.value;if("link"===r.type)return r.href;if("category"===r.type){var a=U(r);if(a)return a}else if("html"!==r.type)throw new Error("Unexpected category item type for "+JSON.stringify(r))}}function Z(e,t){var n=function(e){return void 0!==e&&R(e,t)};return"link"===e.type?n(e.href):"category"===e.type&&(n(e.href)||function(e,t){return e.some((function(e){return Z(e,t)}))}(e.items,t))}function $(){var e,t=z(),n=(0,T.TH)().pathname;return!1!==(null==(e=(0,P.gA)())?void 0:e.pluginData.breadcrumbs)&&t?function(e){var t=e.sidebar,n=e.pathname,r=[];return function e(t){for(var a,o=O(t);!(a=o()).done;){var i=a.value;if("category"===i.type&&(R(i.href,n)||e(i.items)))return r.push(i),!0;if("link"===i.type&&R(i.href,n))return r.push(i),!0}return!1}(t),r.reverse()}({sidebar:t,pathname:n}):null}var H=function(e){return"docs-preferred-version-"+e},q={save:function(e,t,n){C(H(e),{persistence:t}).set(n)},read:function(e,t){return C(H(e),{persistence:t}).get()},clear:function(e,t){C(H(e),{persistence:t}).del()}};function G(e){var t=e.pluginIds,n=e.versionPersistence,r=e.allDocsData;var a={};return t.forEach((function(e){a[e]=function(e){var t=q.read(e,n);return r[e].versions.some((function(e){return e.name===t}))?{preferredVersionName:t}:(q.clear(e,n),{preferredVersionName:null})}(e)})),a}function V(){var e=(0,P._r)(),t=a().docs.versionPersistence,n=(0,o.useMemo)((function(){return Object.keys(e)}),[e]),r=(0,o.useState)((function(){return function(e){var t={};return e.forEach((function(e){t[e]={preferredVersionName:null}})),t}(n)})),i=r[0],l=r[1];return(0,o.useEffect)((function(){l(G({allDocsData:e,versionPersistence:t,pluginIds:n}))}),[e,t,n]),[i,(0,o.useMemo)((function(){return{savePreferredVersion:function(e,n){q.save(e,t,n),l((function(t){var r;return Object.assign({},t,((r={})[e]={preferredVersionName:n},r))}))}}}),[t])]}var W=(0,o.createContext)(null);function K(e){var t=e.children;return N?o.createElement(Y,null,t):t}function Y(e){var t=e.children,n=V();return o.createElement(W.Provider,{value:n},t)}var Q=n(9935);function X(e){void 0===e&&(e=Q.m);var t=(0,P.zh)(e),n=function(){var e=(0,o.useContext)(W);if(!e)throw new b("DocsPreferredVersionContextProvider");return e}(),r=n[0],a=n[1],i=r[e].preferredVersionName;return{preferredVersion:i?t.versions.find((function(e){return e.name===i})):null,savePreferredVersionName:(0,o.useCallback)((function(t){a.savePreferredVersion(e,t)}),[a,e])}}var J=n(7594),ee=n.n(J),te=u(/title=(["'])(.*?)\1/,{quote:1,title:2}),ne=u(/\{([\d,-]+)\}/,{range:1}),re=["js","jsBlock","jsx","python","html"],ae={js:{start:"\\/\\/",end:""},jsBlock:{start:"\\/\\*",end:"\\*\\/"},jsx:{start:"\\{\\s*\\/\\*",end:"\\*\\/\\s*\\}"},python:{start:"#",end:""},html:{start:"\x3c!--",end:"--\x3e"}},oe=["highlight-next-line","highlight-start","highlight-end"],ie=function(e){void 0===e&&(e=re);var t=e.map((function(e){var t=ae[e],n=t.start,r=t.end;return"(?:"+n+"\\s*("+oe.join("|")+")\\s*"+r+")"})).join("|");return new RegExp("^\\s*(?:"+t+")\\s*$")};function le(e){var t,n;return null!=(t=null==e||null==(n=e.match(te))?void 0:n.groups.title)?t:""}function se(e){var t=e.split(" ").find((function(e){return e.startsWith("language-")}));return null==t?void 0:t.replace(/language-/,"")}function ue(e,t,n){var r=e.replace(/\n$/,"");if(t&&ne.test(t)){var a=t.match(ne).groups.range;return{highlightLines:ee()(a).filter((function(e){return e>0})).map((function(e){return e-1})),code:r}}if(void 0===n)return{highlightLines:[],code:r};for(var o,i=function(e){switch(e){case"js":case"javascript":case"ts":case"typescript":return ie(["js","jsBlock"]);case"jsx":case"tsx":return ie(["js","jsBlock","jsx"]);case"html":return ie(["js","jsBlock","html"]);case"python":case"py":return ie(["python"]);default:return ie()}}(n),l=r.split("\n"),s="",u=0;un.pluralForms.length&&console.error("For locale="+n.locale+", a maximum of "+n.pluralForms.length+" plural forms are expected ("+n.pluralForms+"), but the message contains "+r.length+" plural forms: "+e+" ");var a=n.select(t),o=n.pluralForms.indexOf(a);return r[Math.min(o,r.length-1)]}(n,t,e)}}}function ve(e){var t=(0,o.useRef)();return g((function(){t.current=e})),t.current}function ye(e){var t=(0,T.TH)(),n=ve(t),r=h(e);(0,o.useEffect)((function(){n&&t!==n&&r({location:t,previousLocation:n})}),[r,t,n])}var ke=n(3366),we=n(412),Ee=["collapsed"],Se=["lazy"];function _e(e){var t=e.initialState,n=(0,o.useState)(null!=t&&t),r=n[0],a=n[1],i=(0,o.useCallback)((function(){a((function(e){return!e}))}),[]);return{collapsed:r,setCollapsed:a,toggleCollapsed:i}}var xe={display:"none",overflow:"hidden",height:"0px"},Ce={display:"block",overflow:"visible",height:"auto"};function Te(e,t){var n=t?xe:Ce;e.style.display=n.display,e.style.overflow=n.overflow,e.style.height=n.height}function Ae(e){var t=e.collapsibleRef,n=e.collapsed,r=e.animation,a=(0,o.useRef)(!1);(0,o.useEffect)((function(){var e,o=t.current;function i(){var e,t,n=o.scrollHeight,a=null!=(e=null==r?void 0:r.duration)?e:function(e){var t=e/36;return Math.round(10*(4+15*Math.pow(t,.25)+t/5))}(n);return{transition:"height "+a+"ms "+(null!=(t=null==r?void 0:r.easing)?t:"ease-in-out"),height:n+"px"}}function l(){var e=i();o.style.transition=e.transition,o.style.height=e.height}if(!a.current)return Te(o,n),void(a.current=!0);return o.style.willChange="height",e=requestAnimationFrame((function(){n?(l(),requestAnimationFrame((function(){o.style.height=xe.height,o.style.overflow=xe.overflow}))):(o.style.display="block",requestAnimationFrame((function(){l()})))})),function(){return cancelAnimationFrame(e)}}),[t,n,r])}function Pe(e){if(!we.default.canUseDOM)return e?xe:Ce}function Le(e){var t=e.as,n=void 0===t?"div":t,r=e.collapsed,a=e.children,i=e.animation,l=e.onCollapseTransitionEnd,s=e.className,u=e.disableSSRStyle,c=(0,o.useRef)(null);return Ae({collapsibleRef:c,collapsed:r,animation:i}),o.createElement(n,{ref:c,style:u?void 0:Pe(r),onTransitionEnd:function(e){"height"===e.propertyName&&(Te(c.current,r),null==l||l(r))},className:s},a)}function Oe(e){var t=e.collapsed,n=(0,ke.Z)(e,Ee),r=(0,o.useState)(!t),a=r[0],i=r[1];(0,o.useLayoutEffect)((function(){t||i(!0)}),[t]);var l=(0,o.useState)(t),s=l[0],u=l[1];return(0,o.useLayoutEffect)((function(){a&&u(t)}),[a,t]),a?o.createElement(Le,Object.assign({},n,{collapsed:s})):null}function Re(e){var t=e.lazy,n=(0,ke.Z)(e,Se),r=t?Oe:Le;return o.createElement(r,Object.assign({},n))}var Ne=n(2389),Ie=n(6010),De="details_lb9f",Me="isBrowser_bmU9",je="collapsibleContent_i85q",Fe=["summary","children"];function Be(e){return!!e&&("SUMMARY"===e.tagName||Be(e.parentElement))}function ze(e,t){return!!e&&(e===t||ze(e.parentElement,t))}function Ue(e){var t,n=e.summary,r=e.children,a=(0,ke.Z)(e,Fe),i=(0,Ne.Z)(),l=(0,o.useRef)(null),s=_e({initialState:!a.open}),u=s.collapsed,c=s.setCollapsed,d=(0,o.useState)(a.open),f=d[0],p=d[1];return o.createElement("details",Object.assign({},a,{ref:l,open:f,"data-collapsed":u,className:(0,Ie.Z)(De,(t={},t[Me]=i,t),a.className),onMouseDown:function(e){Be(e.target)&&e.detail>1&&e.preventDefault()},onClick:function(e){e.stopPropagation();var t=e.target;Be(t)&&ze(t,l.current)&&(e.preventDefault(),u?(c(!1),p(!0)):c(!0))}}),n,o.createElement(Re,{lazy:!1,collapsed:u,disableSSRStyle:!0,onCollapseTransitionEnd:function(e){c(e),p(!e)}},o.createElement("div",{className:je},r)))}var Ze=(0,o.createContext)(null);function $e(e){var t=e.children;return o.createElement(Ze.Provider,{value:(0,o.useState)(null)},t)}function He(){var e=(0,o.useContext)(Ze);if(null===e)throw new b("MobileSecondaryMenuProvider");return e}function qe(){var e=He()[0];if(e){var t=e.component;return function(n){return o.createElement(t,Object.assign({},e.props,n))}}return function(){}}function Ge(e){var t,n=e.component,r=e.props,a=He()[1],i=(t=r,(0,o.useMemo)((function(){return t}),[].concat(Object.keys(t),Object.values(t))));return(0,o.useEffect)((function(){a({component:n,props:i})}),[a,n,i]),(0,o.useEffect)((function(){return function(){return a(null)}}),[a]),null}function Ve(e){return Array.from(new Set(e))}var We={page:{blogListPage:"blog-list-page",blogPostPage:"blog-post-page",blogTagsListPage:"blog-tags-list-page",blogTagPostListPage:"blog-tags-post-list-page",docsDocPage:"docs-doc-page",docsTagsListPage:"docs-tags-list-page",docsTagDocListPage:"docs-tags-doc-list-page",mdxPage:"mdx-page"},wrapper:{main:"main-wrapper",blogPages:"blog-wrapper",docsPages:"docs-wrapper",mdxPages:"mdx-wrapper"},common:{editThisPage:"theme-edit-this-page",lastUpdated:"theme-last-updated",backToTopButton:"theme-back-to-top-button",codeBlock:"theme-code-block"},layout:{},docs:{docVersionBanner:"theme-doc-version-banner",docVersionBadge:"theme-doc-version-badge",docBreadcrumbs:"theme-doc-breadcrumbs",docMarkdown:"theme-doc-markdown",docTocMobile:"theme-doc-toc-mobile",docTocDesktop:"theme-doc-toc-desktop",docFooter:"theme-doc-footer",docFooterTagsRow:"theme-doc-footer-tags-row",docFooterEditMetaRow:"theme-doc-footer-edit-meta-row",docSidebarContainer:"theme-doc-sidebar-container",docSidebarMenu:"theme-doc-sidebar-menu",docSidebarItemCategory:"theme-doc-sidebar-item-category",docSidebarItemLink:"theme-doc-sidebar-item-link",docSidebarItemCategoryLevel:function(e){return"theme-doc-sidebar-item-category-level-"+e},docSidebarItemLinkLevel:function(e){return"theme-doc-sidebar-item-link-level-"+e}},blog:{}},Ke=C("docusaurus.announcement.dismiss"),Ye=C("docusaurus.announcement.id"),Qe=function(){return"true"===Ke.get()},Xe=function(e){return Ke.set(String(e))},Je=(0,o.createContext)(null);function et(e){var t=e.children,n=function(){var e=a().announcementBar,t=(0,Ne.Z)(),n=(0,o.useState)((function(){return!!t&&Qe()})),r=n[0],i=n[1];(0,o.useEffect)((function(){i(Qe())}),[]);var l=(0,o.useCallback)((function(){Xe(!0),i(!0)}),[]);return(0,o.useEffect)((function(){if(e){var t=e.id,n=Ye.get();"annoucement-bar"===n&&(n="announcement-bar");var r=t!==n;Ye.set(t),r&&Xe(!1),!r&&Qe()||i(!1)}}),[e]),(0,o.useMemo)((function(){return{isActive:!!e&&!r,close:l}}),[e,r,l])}();return o.createElement(Je.Provider,{value:n},t)}function tt(){var e=(0,o.useContext)(Je);if(!e)throw new b("AnnouncementBarProvider");return e}function nt(){var e=(0,r.Z)().siteConfig.baseUrl;return(0,T.TH)().pathname.replace(e,"/")}var rt=n(5999),at=function(){return(0,rt.I)({id:"theme.tags.tagsPageTitle",message:"Tags",description:"The title of the tag list page"})};function ot(e){var t={};return Object.values(e).forEach((function(e){var n,r=function(e){return e[0].toUpperCase()}(e.name);t[r]=null!=(n=t[r])?n:[],t[r].push(e)})),Object.entries(t).sort((function(e,t){var n=e[0],r=t[0];return n.localeCompare(r)})).map((function(e){return{letter:e[0],tags:e[1].sort((function(e,t){return e.name.localeCompare(t.name)}))}}))}function it(e){!function(e){var t=(0,T.k6)().block,n=(0,o.useRef)(e);(0,o.useEffect)((function(){n.current=e}),[e]),(0,o.useEffect)((function(){return t((function(e,t){return n.current(e,t)}))}),[t,n])}((function(t,n){if("POP"===n)return e(t,n)}))}function lt(e){var t=e.getBoundingClientRect();return t.top===t.bottom?lt(e.parentNode):t}function st(e,t){var n,r=t.anchorTopOffset,a=e.find((function(e){return lt(e).top>=r}));return a?function(e){return e.top>0&&e.bottom=0?t[n].children.push(a):r.push(a)})),r}function pt(e){var t=e.toc,n=e.minHeadingLevel,r=e.maxHeadingLevel;return t.flatMap((function(e){var t=pt({toc:e.children,minHeadingLevel:n,maxHeadingLevel:r});return function(e){return e.level>=n&&e.level<=r}(e)?[Object.assign({},e,{children:t})]:t}))}function mt(e){var t=e.toc,n=e.minHeadingLevel,r=e.maxHeadingLevel;return(0,o.useMemo)((function(){return pt({toc:ft(t),minHeadingLevel:n,maxHeadingLevel:r})}),[t,n,r])}var gt=(0,o.createContext)(void 0);function ht(e){var t,n=e.children;return o.createElement(gt.Provider,{value:(t=(0,o.useRef)(!0),(0,o.useMemo)((function(){return{scrollEventsEnabledRef:t,enableScrollEvents:function(){t.current=!0},disableScrollEvents:function(){t.current=!1}}}),[]))},n)}function bt(){var e=(0,o.useContext)(gt);if(null==e)throw new b("ScrollControllerProvider");return e}var vt=function(){return we.default.canUseDOM?{scrollX:window.pageXOffset,scrollY:window.pageYOffset}:null};function yt(e,t){void 0===t&&(t=[]);var n=bt().scrollEventsEnabledRef,r=(0,o.useRef)(vt()),a=h(e);(0,o.useEffect)((function(){var e=function(){if(n.current){var e=vt();a&&a(e,r.current),r.current=e}},t={passive:!0};return e(),window.addEventListener("scroll",e,t),function(){return window.removeEventListener("scroll",e,t)}}),[a,n].concat(t))}function kt(e,t){return void 0!==e&&void 0!==t&&new RegExp(e,"gi").test(t)}var wt=n(723);function Et(){var e=(0,r.Z)().siteConfig.baseUrl;return(0,o.useMemo)((function(){return function(e){var t=e.baseUrl;function n(e){return e.path===t&&!0===e.exact}function r(e){return e.path===t&&!e.exact}return function e(t){if(0!==t.length)return t.find(n)||e(t.filter(r).flatMap((function(e){var t;return null!=(t=e.routes)?t:[]})))}(e.routes)}({routes:wt.Z,baseUrl:e})}),[e])}var St="theme",_t=C(St),xt="light",Ct="dark",Tt=function(e){return e===Ct?Ct:xt},At=function(e){_t.set(Tt(e))};function Pt(){var e=a().colorMode,t=e.defaultMode,n=e.disableSwitch,r=e.respectPrefersColorScheme,i=(0,o.useState)(function(e){return we.default.canUseDOM?Tt(document.documentElement.getAttribute("data-theme")):Tt(e)}(t)),l=i[0],s=i[1],u=(0,o.useCallback)((function(){s(xt),At(xt)}),[]),c=(0,o.useCallback)((function(){s(Ct),At(Ct)}),[]);(0,o.useEffect)((function(){document.documentElement.setAttribute("data-theme",Tt(l))}),[l]),(0,o.useEffect)((function(){if(!n){var e=function(e){if(e.key===St)try{var t=_t.get();null!==t&&s(Tt(t))}catch(n){console.error(n)}};return window.addEventListener("storage",e),function(){window.removeEventListener("storage",e)}}}),[n,s]);var d=o.useRef(!1);return(0,o.useEffect)((function(){if(!n||r){var e=window.matchMedia("(prefers-color-scheme: dark)"),t=function(e){var t=e.matches;window.matchMedia("print").matches||d.current?d.current=window.matchMedia("print").matches:s(t?Ct:xt)};return e.addListener(t),function(){e.removeListener(t)}}}),[n,r]),{isDarkTheme:l===Ct,setLightTheme:u,setDarkTheme:c}}var Lt=o.createContext(void 0);function Ot(e){var t=e.children,n=Pt(),r=n.isDarkTheme,a=n.setLightTheme,i=n.setDarkTheme,l=(0,o.useMemo)((function(){return{isDarkTheme:r,setLightTheme:a,setDarkTheme:i}}),[r,a,i]);return o.createElement(Lt.Provider,{value:l},t)}function Rt(){var e=(0,o.useContext)(Lt);if(null==e)throw new b("ColorModeProvider","Please see https://docusaurus.io/docs/api/themes/configuration#use-color-mode.");return e}var Nt="docusaurus.tab.",It=(0,o.createContext)(void 0);function Dt(){var e=(0,o.useState)({}),t=e[0],n=e[1],r=(0,o.useCallback)((function(e,t){C("docusaurus.tab."+e).set(t)}),[]);return(0,o.useEffect)((function(){try{var e={};(function(e){void 0===e&&(e=E);var t=S(e);if(!t)return[];for(var n=[],r=0;r=l?r(!1):o+u996?$t:Ht:qt}function Vt(){var e=(0,o.useState)((function(){return Gt()})),t=e[0],n=e[1];return(0,o.useEffect)((function(){function e(){n(Gt())}return window.addEventListener("resize",e),function(){window.removeEventListener("resize",e),clearTimeout(undefined)}}),[]),t}},8802:function(e,t){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e,t){var n=t.trailingSlash,r=t.baseUrl;if(e.startsWith("#"))return e;if(void 0===n)return e;var a,o=e.split(/[#?]/)[0],i="/"===o||o===r?o:(a=o,n?function(e){return e.endsWith("/")?e:e+"/"}(a):function(e){return e.endsWith("/")?e.slice(0,-1):e}(a));return e.replace(o,i)}},8780:function(e,t,n){"use strict";var r=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.applyTrailingSlash=t.blogPostContainerID=void 0,t.blogPostContainerID="post-content";var a=n(8802);Object.defineProperty(t,"applyTrailingSlash",{enumerable:!0,get:function(){return r(a).default}})},6010:function(e,t,n){"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t=0;f--){var p=i[f];"."===p?o(i,f):".."===p?(o(i,f),d++):d&&(o(i,f),d--)}if(!u)for(;d--;d)i.unshift("..");!u||""===i[0]||i[0]&&a(i[0])||i.unshift("");var m=i.join("/");return n&&"/"!==m.substr(-1)&&(m+="/"),m};function l(e){return e.valueOf?e.valueOf():Object.prototype.valueOf.call(e)}var s=function e(t,n){if(t===n)return!0;if(null==t||null==n)return!1;if(Array.isArray(t))return Array.isArray(n)&&t.length===n.length&&t.every((function(t,r){return e(t,n[r])}));if("object"==typeof t||"object"==typeof n){var r=l(t),a=l(n);return r!==t||a!==n?e(r,a):Object.keys(Object.assign({},t,n)).every((function(r){return e(t[r],n[r])}))}return!1},u=n(2177);function c(e){return"/"===e.charAt(0)?e:"/"+e}function d(e){return"/"===e.charAt(0)?e.substr(1):e}function f(e,t){return function(e,t){return 0===e.toLowerCase().indexOf(t.toLowerCase())&&-1!=="/?#".indexOf(e.charAt(t.length))}(e,t)?e.substr(t.length):e}function p(e){return"/"===e.charAt(e.length-1)?e.slice(0,-1):e}function m(e){var t=e.pathname,n=e.search,r=e.hash,a=t||"/";return n&&"?"!==n&&(a+="?"===n.charAt(0)?n:"?"+n),r&&"#"!==r&&(a+="#"===r.charAt(0)?r:"#"+r),a}function g(e,t,n,a){var o;"string"==typeof e?(o=function(e){var t=e||"/",n="",r="",a=t.indexOf("#");-1!==a&&(r=t.substr(a),t=t.substr(0,a));var o=t.indexOf("?");return-1!==o&&(n=t.substr(o),t=t.substr(0,o)),{pathname:t,search:"?"===n?"":n,hash:"#"===r?"":r}}(e),o.state=t):(void 0===(o=(0,r.Z)({},e)).pathname&&(o.pathname=""),o.search?"?"!==o.search.charAt(0)&&(o.search="?"+o.search):o.search="",o.hash?"#"!==o.hash.charAt(0)&&(o.hash="#"+o.hash):o.hash="",void 0!==t&&void 0===o.state&&(o.state=t));try{o.pathname=decodeURI(o.pathname)}catch(l){throw l instanceof URIError?new URIError('Pathname "'+o.pathname+'" could not be decoded. This is likely caused by an invalid percent-encoding.'):l}return n&&(o.key=n),a?o.pathname?"/"!==o.pathname.charAt(0)&&(o.pathname=i(o.pathname,a.pathname)):o.pathname=a.pathname:o.pathname||(o.pathname="/"),o}function h(e,t){return e.pathname===t.pathname&&e.search===t.search&&e.hash===t.hash&&e.key===t.key&&s(e.state,t.state)}function b(){var e=null;var t=[];return{setPrompt:function(t){return e=t,function(){e===t&&(e=null)}},confirmTransitionTo:function(t,n,r,a){if(null!=e){var o="function"==typeof e?e(t,n):e;"string"==typeof o?"function"==typeof r?r(o,a):a(!0):a(!1!==o)}else a(!0)},appendListener:function(e){var n=!0;function r(){n&&e.apply(void 0,arguments)}return t.push(r),function(){n=!1,t=t.filter((function(e){return e!==r}))}},notifyListeners:function(){for(var e=arguments.length,n=new Array(e),r=0;rt?n.splice(t,n.length-t,a):n.push(a),d({action:r,location:a,index:t,entries:n})}}))},replace:function(e,t){var r="REPLACE",a=g(e,t,f(),k.location);c.confirmTransitionTo(a,r,n,(function(e){e&&(k.entries[k.index]=a,d({action:r,location:a}))}))},go:y,goBack:function(){y(-1)},goForward:function(){y(1)},canGo:function(e){var t=k.index+e;return t>=0&&t
'};function a(e,t,n){return en?n:e}function o(e){return 100*(-1+e)}function i(e,t,n){var a;return(a="translate3d"===r.positionUsing?{transform:"translate3d("+o(e)+"%,0,0)"}:"translate"===r.positionUsing?{transform:"translate("+o(e)+"%,0)"}:{"margin-left":o(e)+"%"}).transition="all "+t+"ms "+n,a}n.configure=function(e){var t,n;for(t in e)void 0!==(n=e[t])&&e.hasOwnProperty(t)&&(r[t]=n);return this},n.status=null,n.set=function(e){var t=n.isStarted();e=a(e,r.minimum,1),n.status=1===e?null:e;var o=n.render(!t),u=o.querySelector(r.barSelector),c=r.speed,d=r.easing;return o.offsetWidth,l((function(t){""===r.positionUsing&&(r.positionUsing=n.getPositioningCSS()),s(u,i(e,c,d)),1===e?(s(o,{transition:"none",opacity:1}),o.offsetWidth,setTimeout((function(){s(o,{transition:"all "+c+"ms linear",opacity:0}),setTimeout((function(){n.remove(),t()}),c)}),c)):setTimeout(t,c)})),this},n.isStarted=function(){return"number"==typeof n.status},n.start=function(){n.status||n.set(0);var e=function(){setTimeout((function(){n.status&&(n.trickle(),e())}),r.trickleSpeed)};return r.trickle&&e(),this},n.done=function(e){return e||n.status?n.inc(.3+.5*Math.random()).set(1):this},n.inc=function(e){var t=n.status;return t?("number"!=typeof e&&(e=(1-t)*a(Math.random()*t,.1,.95)),t=a(t+e,0,.994),n.set(t)):n.start()},n.trickle=function(){return n.inc(Math.random()*r.trickleRate)},e=0,t=0,n.promise=function(r){return r&&"resolved"!==r.state()?(0===t&&n.start(),e++,t++,r.always((function(){0==--t?(e=0,n.done()):n.set((e-t)/e)})),this):this},n.render=function(e){if(n.isRendered())return document.getElementById("nprogress");c(document.documentElement,"nprogress-busy");var t=document.createElement("div");t.id="nprogress",t.innerHTML=r.template;var a,i=t.querySelector(r.barSelector),l=e?"-100":o(n.status||0),u=document.querySelector(r.parent);return s(i,{transition:"all 0 linear",transform:"translate3d("+l+"%,0,0)"}),r.showSpinner||(a=t.querySelector(r.spinnerSelector))&&p(a),u!=document.body&&c(u,"nprogress-custom-parent"),u.appendChild(t),t},n.remove=function(){d(document.documentElement,"nprogress-busy"),d(document.querySelector(r.parent),"nprogress-custom-parent");var e=document.getElementById("nprogress");e&&p(e)},n.isRendered=function(){return!!document.getElementById("nprogress")},n.getPositioningCSS=function(){var e=document.body.style,t="WebkitTransform"in e?"Webkit":"MozTransform"in e?"Moz":"msTransform"in e?"ms":"OTransform"in e?"O":"";return t+"Perspective"in e?"translate3d":t+"Transform"in e?"translate":"margin"};var l=function(){var e=[];function t(){var n=e.shift();n&&n(t)}return function(n){e.push(n),1==e.length&&t()}}(),s=function(){var e=["Webkit","O","Moz","ms"],t={};function n(e){return e.replace(/^-ms-/,"ms-").replace(/-([\da-z])/gi,(function(e,t){return t.toUpperCase()}))}function r(t){var n=document.body.style;if(t in n)return t;for(var r,a=e.length,o=t.charAt(0).toUpperCase()+t.slice(1);a--;)if((r=e[a]+o)in n)return r;return t}function a(e){return e=n(e),t[e]||(t[e]=r(e))}function o(e,t,n){t=a(t),e.style[t]=n}return function(e,t){var n,r,a=arguments;if(2==a.length)for(n in t)void 0!==(r=t[n])&&t.hasOwnProperty(n)&&o(e,n,r);else o(e,a[1],a[2])}}();function u(e,t){return("string"==typeof e?e:f(e)).indexOf(" "+t+" ")>=0}function c(e,t){var n=f(e),r=n+t;u(n,t)||(e.className=r.substring(1))}function d(e,t){var n,r=f(e);u(e,t)&&(n=r.replace(" "+t+" "," "),e.className=n.substring(1,n.length-1))}function f(e){return(" "+(e.className||"")+" ").replace(/\s+/gi," ")}function p(e){e&&e.parentNode&&e.parentNode.removeChild(e)}return n},void 0===(a="function"==typeof r?r.call(t,n,t,e):r)||(e.exports=a)},7418:function(e){"use strict";var t=Object.getOwnPropertySymbols,n=Object.prototype.hasOwnProperty,r=Object.prototype.propertyIsEnumerable;function a(e){if(null==e)throw new TypeError("Object.assign cannot be called with null or undefined");return Object(e)}e.exports=function(){try{if(!Object.assign)return!1;var e=new String("abc");if(e[5]="de","5"===Object.getOwnPropertyNames(e)[0])return!1;for(var t={},n=0;n<10;n++)t["_"+String.fromCharCode(n)]=n;if("0123456789"!==Object.getOwnPropertyNames(t).map((function(e){return t[e]})).join(""))return!1;var r={};return"abcdefghijklmnopqrst".split("").forEach((function(e){r[e]=e})),"abcdefghijklmnopqrst"===Object.keys(Object.assign({},r)).join("")}catch(a){return!1}}()?Object.assign:function(e,o){for(var i,l,s=a(e),u=1;ue.trim())))if(/^-?\d+$/.test(r))n.push(parseInt(r,10));else if(t=r.match(/^(-?\d+)(-|\.\.\.?|\u2025|\u2026|\u22EF)(-?\d+)$/)){let[e,r,a,o]=t;if(r&&o){r=parseInt(r),o=parseInt(o);const e=r=d.reach);S+=E.value.length,E=E.next){var _=E.value;if(t.length>e.length)return;if(!(_ instanceof a)){var x,C=1;if(v){if(!(x=o(w,S,e,b))||x.index>=e.length)break;var T=x.index,A=x.index+x[0].length,P=S;for(P+=E.value.length;T>=P;)P+=(E=E.next).value.length;if(S=P-=E.value.length,E.value instanceof a)continue;for(var L=E;L!==t.tail&&(Pd.reach&&(d.reach=I);var D=E.prev;if(R&&(D=s(t,D,R),S+=R.length),u(t,D,C),E=s(t,D,new a(f,h?r.tokenize(O,h):O,y,O)),N&&s(t,E,N),C>1){var M={cause:f+","+m,reach:I};i(e,t,n,E.prev,S,M),d&&M.reach>d.reach&&(d.reach=M.reach)}}}}}}function l(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function s(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function u(e,t,n){for(var r=t.next,a=0;a"+o.content+""},r}(),a=r;r.default=r,a.languages.markup={comment:{pattern://,greedy:!0},prolog:{pattern:/<\?[\s\S]+?\?>/,greedy:!0},doctype:{pattern:/"'[\]]|"[^"]*"|'[^']*')+(?:\[(?:[^<"'\]]|"[^"]*"|'[^']*'|<(?!!--)|)*\]\s*)?>/i,greedy:!0,inside:{"internal-subset":{pattern:/(^[^\[]*\[)[\s\S]+(?=\]>$)/,lookbehind:!0,greedy:!0,inside:null},string:{pattern:/"[^"]*"|'[^']*'/,greedy:!0},punctuation:/^$|[[\]]/,"doctype-tag":/^DOCTYPE/i,name:/[^\s<>'"]+/}},cdata:{pattern://i,greedy:!0},tag:{pattern:/<\/?(?!\d)[^\s>\/=$<%]+(?:\s(?:\s*[^\s>\/=]+(?:\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))|(?=[\s/>])))+)?\s*\/?>/,greedy:!0,inside:{tag:{pattern:/^<\/?[^\s>\/]+/,inside:{punctuation:/^<\/?/,namespace:/^[^\s>\/:]+:/}},"special-attr":[],"attr-value":{pattern:/=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+)/,inside:{punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}},punctuation:/\/?>/,"attr-name":{pattern:/[^\s>\/]+/,inside:{namespace:/^[^\s>\/:]+:/}}}},entity:[{pattern:/&[\da-z]{1,8};/i,alias:"named-entity"},/&#x?[\da-f]{1,8};/i]},a.languages.markup.tag.inside["attr-value"].inside.entity=a.languages.markup.entity,a.languages.markup.doctype.inside["internal-subset"].inside=a.languages.markup,a.hooks.add("wrap",(function(e){"entity"===e.type&&(e.attributes.title=e.content.replace(/&/,"&"))})),Object.defineProperty(a.languages.markup.tag,"addInlined",{value:function(e,t){var n={};n["language-"+t]={pattern:/(^$)/i,lookbehind:!0,inside:a.languages[t]},n.cdata=/^$/i;var r={"included-cdata":{pattern://i,inside:n}};r["language-"+t]={pattern:/[\s\S]+/,inside:a.languages[t]};var o={};o[e]={pattern:RegExp(/(<__[^>]*>)(?:))*\]\]>|(?!)/.source.replace(/__/g,(function(){return e})),"i"),lookbehind:!0,greedy:!0,inside:r},a.languages.insertBefore("markup","cdata",o)}}),Object.defineProperty(a.languages.markup.tag,"addAttribute",{value:function(e,t){a.languages.markup.tag.inside["special-attr"].push({pattern:RegExp(/(^|["'\s])/.source+"(?:"+e+")"+/\s*=\s*(?:"[^"]*"|'[^']*'|[^\s'">=]+(?=[\s>]))/.source,"i"),lookbehind:!0,inside:{"attr-name":/^[^\s=]+/,"attr-value":{pattern:/=[\s\S]+/,inside:{value:{pattern:/(^=\s*(["']|(?!["'])))\S[\s\S]*(?=\2$)/,lookbehind:!0,alias:[t,"language-"+t],inside:a.languages[t]},punctuation:[{pattern:/^=/,alias:"attr-equals"},/"|'/]}}}})}}),a.languages.html=a.languages.markup,a.languages.mathml=a.languages.markup,a.languages.svg=a.languages.markup,a.languages.xml=a.languages.extend("markup",{}),a.languages.ssml=a.languages.xml,a.languages.atom=a.languages.xml,a.languages.rss=a.languages.xml,function(e){var t="\\b(?:BASH|BASHOPTS|BASH_ALIASES|BASH_ARGC|BASH_ARGV|BASH_CMDS|BASH_COMPLETION_COMPAT_DIR|BASH_LINENO|BASH_REMATCH|BASH_SOURCE|BASH_VERSINFO|BASH_VERSION|COLORTERM|COLUMNS|COMP_WORDBREAKS|DBUS_SESSION_BUS_ADDRESS|DEFAULTS_PATH|DESKTOP_SESSION|DIRSTACK|DISPLAY|EUID|GDMSESSION|GDM_LANG|GNOME_KEYRING_CONTROL|GNOME_KEYRING_PID|GPG_AGENT_INFO|GROUPS|HISTCONTROL|HISTFILE|HISTFILESIZE|HISTSIZE|HOME|HOSTNAME|HOSTTYPE|IFS|INSTANCE|JOB|LANG|LANGUAGE|LC_ADDRESS|LC_ALL|LC_IDENTIFICATION|LC_MEASUREMENT|LC_MONETARY|LC_NAME|LC_NUMERIC|LC_PAPER|LC_TELEPHONE|LC_TIME|LESSCLOSE|LESSOPEN|LINES|LOGNAME|LS_COLORS|MACHTYPE|MAILCHECK|MANDATORY_PATH|NO_AT_BRIDGE|OLDPWD|OPTERR|OPTIND|ORBIT_SOCKETDIR|OSTYPE|PAPERSIZE|PATH|PIPESTATUS|PPID|PS1|PS2|PS3|PS4|PWD|RANDOM|REPLY|SECONDS|SELINUX_INIT|SESSION|SESSIONTYPE|SESSION_MANAGER|SHELL|SHELLOPTS|SHLVL|SSH_AUTH_SOCK|TERM|UID|UPSTART_EVENTS|UPSTART_INSTANCE|UPSTART_JOB|UPSTART_SESSION|USER|WINDOWID|XAUTHORITY|XDG_CONFIG_DIRS|XDG_CURRENT_DESKTOP|XDG_DATA_DIRS|XDG_GREETER_DATA_DIR|XDG_MENU_PREFIX|XDG_RUNTIME_DIR|XDG_SEAT|XDG_SEAT_PATH|XDG_SESSION_DESKTOP|XDG_SESSION_ID|XDG_SESSION_PATH|XDG_SESSION_TYPE|XDG_VTNR|XMODIFIERS)\\b",n={pattern:/(^(["']?)\w+\2)[ \t]+\S.*/,lookbehind:!0,alias:"punctuation",inside:null},r={bash:n,environment:{pattern:RegExp("\\$"+t),alias:"constant"},variable:[{pattern:/\$?\(\([\s\S]+?\)\)/,greedy:!0,inside:{variable:[{pattern:/(^\$\(\([\s\S]+)\)\)/,lookbehind:!0},/^\$\(\(/],number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee]-?\d+)?/,operator:/--|\+\+|\*\*=?|<<=?|>>=?|&&|\|\||[=!+\-*/%<>^&|]=?|[?~:]/,punctuation:/\(\(?|\)\)?|,|;/}},{pattern:/\$\((?:\([^)]+\)|[^()])+\)|`[^`]+`/,greedy:!0,inside:{variable:/^\$\(|^`|\)$|`$/}},{pattern:/\$\{[^}]+\}/,greedy:!0,inside:{operator:/:[-=?+]?|[!\/]|##?|%%?|\^\^?|,,?/,punctuation:/[\[\]]/,environment:{pattern:RegExp("(\\{)"+t),lookbehind:!0,alias:"constant"}}},/\$(?:\w+|[#?*!@$])/],entity:/\\(?:[abceEfnrtv\\"]|O?[0-7]{1,3}|U[0-9a-fA-F]{8}|u[0-9a-fA-F]{4}|x[0-9a-fA-F]{1,2})/};e.languages.bash={shebang:{pattern:/^#!\s*\/.*/,alias:"important"},comment:{pattern:/(^|[^"{\\$])#.*/,lookbehind:!0},"function-name":[{pattern:/(\bfunction\s+)[\w-]+(?=(?:\s*\(?:\s*\))?\s*\{)/,lookbehind:!0,alias:"function"},{pattern:/\b[\w-]+(?=\s*\(\s*\)\s*\{)/,alias:"function"}],"for-or-select":{pattern:/(\b(?:for|select)\s+)\w+(?=\s+in\s)/,alias:"variable",lookbehind:!0},"assign-left":{pattern:/(^|[\s;|&]|[<>]\()\w+(?=\+?=)/,inside:{environment:{pattern:RegExp("(^|[\\s;|&]|[<>]\\()"+t),lookbehind:!0,alias:"constant"}},alias:"variable",lookbehind:!0},string:[{pattern:/((?:^|[^<])<<-?\s*)(\w+)\s[\s\S]*?(?:\r?\n|\r)\2/,lookbehind:!0,greedy:!0,inside:r},{pattern:/((?:^|[^<])<<-?\s*)(["'])(\w+)\2\s[\s\S]*?(?:\r?\n|\r)\3/,lookbehind:!0,greedy:!0,inside:{bash:n}},{pattern:/(^|[^\\](?:\\\\)*)"(?:\\[\s\S]|\$\([^)]+\)|\$(?!\()|`[^`]+`|[^"\\`$])*"/,lookbehind:!0,greedy:!0,inside:r},{pattern:/(^|[^$\\])'[^']*'/,lookbehind:!0,greedy:!0},{pattern:/\$'(?:[^'\\]|\\[\s\S])*'/,greedy:!0,inside:{entity:r.entity}}],environment:{pattern:RegExp("\\$?"+t),alias:"constant"},variable:r.variable,function:{pattern:/(^|[\s;|&]|[<>]\()(?:add|apropos|apt|apt-cache|apt-get|aptitude|aspell|automysqlbackup|awk|basename|bash|bc|bconsole|bg|bzip2|cal|cat|cfdisk|chgrp|chkconfig|chmod|chown|chroot|cksum|clear|cmp|column|comm|composer|cp|cron|crontab|csplit|curl|cut|date|dc|dd|ddrescue|debootstrap|df|diff|diff3|dig|dir|dircolors|dirname|dirs|dmesg|docker|docker-compose|du|egrep|eject|env|ethtool|expand|expect|expr|fdformat|fdisk|fg|fgrep|file|find|fmt|fold|format|free|fsck|ftp|fuser|gawk|git|gparted|grep|groupadd|groupdel|groupmod|groups|grub-mkconfig|gzip|halt|head|hg|history|host|hostname|htop|iconv|id|ifconfig|ifdown|ifup|import|install|ip|jobs|join|kill|killall|less|link|ln|locate|logname|logrotate|look|lpc|lpr|lprint|lprintd|lprintq|lprm|ls|lsof|lynx|make|man|mc|mdadm|mkconfig|mkdir|mke2fs|mkfifo|mkfs|mkisofs|mknod|mkswap|mmv|more|most|mount|mtools|mtr|mutt|mv|nano|nc|netstat|nice|nl|node|nohup|notify-send|npm|nslookup|op|open|parted|passwd|paste|pathchk|ping|pkill|pnpm|podman|podman-compose|popd|pr|printcap|printenv|ps|pushd|pv|quota|quotacheck|quotactl|ram|rar|rcp|reboot|remsync|rename|renice|rev|rm|rmdir|rpm|rsync|scp|screen|sdiff|sed|sendmail|seq|service|sftp|sh|shellcheck|shuf|shutdown|sleep|slocate|sort|split|ssh|stat|strace|su|sudo|sum|suspend|swapon|sync|tac|tail|tar|tee|time|timeout|top|touch|tr|traceroute|tsort|tty|umount|uname|unexpand|uniq|units|unrar|unshar|unzip|update-grub|uptime|useradd|userdel|usermod|users|uudecode|uuencode|v|vcpkg|vdir|vi|vim|virsh|vmstat|wait|watch|wc|wget|whereis|which|who|whoami|write|xargs|xdg-open|yarn|yes|zenity|zip|zsh|zypper)(?=$|[)\s;|&])/,lookbehind:!0},keyword:{pattern:/(^|[\s;|&]|[<>]\()(?:case|do|done|elif|else|esac|fi|for|function|if|in|select|then|until|while)(?=$|[)\s;|&])/,lookbehind:!0},builtin:{pattern:/(^|[\s;|&]|[<>]\()(?:\.|:|alias|bind|break|builtin|caller|cd|command|continue|declare|echo|enable|eval|exec|exit|export|getopts|hash|help|let|local|logout|mapfile|printf|pwd|read|readarray|readonly|return|set|shift|shopt|source|test|times|trap|type|typeset|ulimit|umask|unalias|unset)(?=$|[)\s;|&])/,lookbehind:!0,alias:"class-name"},boolean:{pattern:/(^|[\s;|&]|[<>]\()(?:false|true)(?=$|[)\s;|&])/,lookbehind:!0},"file-descriptor":{pattern:/\B&\d\b/,alias:"important"},operator:{pattern:/\d?<>|>\||\+=|=[=~]?|!=?|<<[<-]?|[&\d]?>>|\d[<>]&?|[<>][&=]?|&[>&]?|\|[&|]?/,inside:{"file-descriptor":{pattern:/^\d/,alias:"important"}}},punctuation:/\$?\(\(?|\)\)?|\.\.|[{}[\];\\]/,number:{pattern:/(^|\s)(?:[1-9]\d*|0)(?:[.,]\d+)?\b/,lookbehind:!0}},n.inside=e.languages.bash;for(var a=["comment","function-name","for-or-select","assign-left","string","environment","function","keyword","builtin","boolean","file-descriptor","operator","punctuation","number"],o=r.variable[1].inside,i=0;i]=?|[!=]=?=?|--?|\+\+?|&&?|\|\|?|[?*/~^%]/,punctuation:/[{}[\];(),.:]/},a.languages.c=a.languages.extend("clike",{comment:{pattern:/\/\/(?:[^\r\n\\]|\\(?:\r\n?|\n|(?![\r\n])))*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},"class-name":{pattern:/(\b(?:enum|struct)\s+(?:__attribute__\s*\(\([\s\S]*?\)\)\s*)?)\w+|\b[a-z]\w*_t\b/,lookbehind:!0},keyword:/\b(?:_Alignas|_Alignof|_Atomic|_Bool|_Complex|_Generic|_Imaginary|_Noreturn|_Static_assert|_Thread_local|__attribute__|asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|inline|int|long|register|return|short|signed|sizeof|static|struct|switch|typedef|typeof|union|unsigned|void|volatile|while)\b/,function:/\b[a-z_]\w*(?=\s*\()/i,number:/(?:\b0x(?:[\da-f]+(?:\.[\da-f]*)?|\.[\da-f]+)(?:p[+-]?\d+)?|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:e[+-]?\d+)?)[ful]{0,4}/i,operator:/>>=?|<<=?|->|([-+&|:])\1|[?:~]|[-+*/%&|^!=<>]=?/}),a.languages.insertBefore("c","string",{char:{pattern:/'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n]){0,32}'/,greedy:!0}}),a.languages.insertBefore("c","string",{macro:{pattern:/(^[\t ]*)#\s*[a-z](?:[^\r\n\\/]|\/(?!\*)|\/\*(?:[^*]|\*(?!\/))*\*\/|\\(?:\r\n|[\s\S]))*/im,lookbehind:!0,greedy:!0,alias:"property",inside:{string:[{pattern:/^(#\s*include\s*)<[^>]+>/,lookbehind:!0},a.languages.c.string],char:a.languages.c.char,comment:a.languages.c.comment,"macro-name":[{pattern:/(^#\s*define\s+)\w+\b(?!\()/i,lookbehind:!0},{pattern:/(^#\s*define\s+)\w+\b(?=\()/i,lookbehind:!0,alias:"function"}],directive:{pattern:/^(#\s*)[a-z]+/,lookbehind:!0,alias:"keyword"},"directive-hash":/^#/,punctuation:/##|\\(?=[\r\n])/,expression:{pattern:/\S[\s\S]*/,inside:a.languages.c}}}}),a.languages.insertBefore("c","function",{constant:/\b(?:EOF|NULL|SEEK_CUR|SEEK_END|SEEK_SET|__DATE__|__FILE__|__LINE__|__TIMESTAMP__|__TIME__|__func__|stderr|stdin|stdout)\b/}),delete a.languages.c.boolean,function(e){var t=/\b(?:alignas|alignof|asm|auto|bool|break|case|catch|char|char16_t|char32_t|char8_t|class|co_await|co_return|co_yield|compl|concept|const|const_cast|consteval|constexpr|constinit|continue|decltype|default|delete|do|double|dynamic_cast|else|enum|explicit|export|extern|final|float|for|friend|goto|if|import|inline|int|int16_t|int32_t|int64_t|int8_t|long|module|mutable|namespace|new|noexcept|nullptr|operator|override|private|protected|public|register|reinterpret_cast|requires|return|short|signed|sizeof|static|static_assert|static_cast|struct|switch|template|this|thread_local|throw|try|typedef|typeid|typename|uint16_t|uint32_t|uint64_t|uint8_t|union|unsigned|using|virtual|void|volatile|wchar_t|while)\b/,n=/\b(?!)\w+(?:\s*\.\s*\w+)*\b/.source.replace(//g,(function(){return t.source}));e.languages.cpp=e.languages.extend("c",{"class-name":[{pattern:RegExp(/(\b(?:class|concept|enum|struct|typename)\s+)(?!)\w+/.source.replace(//g,(function(){return t.source}))),lookbehind:!0},/\b[A-Z]\w*(?=\s*::\s*\w+\s*\()/,/\b[A-Z_]\w*(?=\s*::\s*~\w+\s*\()/i,/\b\w+(?=\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>\s*::\s*\w+\s*\()/],keyword:t,number:{pattern:/(?:\b0b[01']+|\b0x(?:[\da-f']+(?:\.[\da-f']*)?|\.[\da-f']+)(?:p[+-]?[\d']+)?|(?:\b[\d']+(?:\.[\d']*)?|\B\.[\d']+)(?:e[+-]?[\d']+)?)[ful]{0,4}/i,greedy:!0},operator:/>>=?|<<=?|->|--|\+\+|&&|\|\||[?:~]|<=>|[-+*/%&|^!=<>]=?|\b(?:and|and_eq|bitand|bitor|not|not_eq|or|or_eq|xor|xor_eq)\b/,boolean:/\b(?:false|true)\b/}),e.languages.insertBefore("cpp","string",{module:{pattern:RegExp(/(\b(?:import|module)\s+)/.source+"(?:"+/"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|<[^<>\r\n]*>/.source+"|"+/(?:\s*:\s*)?|:\s*/.source.replace(//g,(function(){return n}))+")"),lookbehind:!0,greedy:!0,inside:{string:/^[<"][\s\S]+/,operator:/:/,punctuation:/\./}},"raw-string":{pattern:/R"([^()\\ ]{0,16})\([\s\S]*?\)\1"/,alias:"string",greedy:!0}}),e.languages.insertBefore("cpp","keyword",{"generic-function":{pattern:/\b(?!operator\b)[a-z_]\w*\s*<(?:[^<>]|<[^<>]*>)*>(?=\s*\()/i,inside:{function:/^\w+/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:e.languages.cpp}}}}),e.languages.insertBefore("cpp","operator",{"double-colon":{pattern:/::/,alias:"punctuation"}}),e.languages.insertBefore("cpp","class-name",{"base-clause":{pattern:/(\b(?:class|struct)\s+\w+\s*:\s*)[^;{}"'\s]+(?:\s+[^;{}"'\s]+)*(?=\s*[;{])/,lookbehind:!0,greedy:!0,inside:e.languages.extend("cpp",{})}}),e.languages.insertBefore("inside","double-colon",{"class-name":/\b[a-z_]\w*\b(?!\s*::)/i},e.languages.cpp["base-clause"])}(a),function(e){var t=/(?:"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"|'(?:\\(?:\r\n|[\s\S])|[^'\\\r\n])*')/;e.languages.css={comment:/\/\*[\s\S]*?\*\//,atrule:{pattern:/@[\w-](?:[^;{\s]|\s+(?![\s{]))*(?:;|(?=\s*\{))/,inside:{rule:/^@[\w-]+/,"selector-function-argument":{pattern:/(\bselector\s*\(\s*(?![\s)]))(?:[^()\s]|\s+(?![\s)])|\((?:[^()]|\([^()]*\))*\))+(?=\s*\))/,lookbehind:!0,alias:"selector"},keyword:{pattern:/(^|[^\w-])(?:and|not|only|or)(?![\w-])/,lookbehind:!0}}},url:{pattern:RegExp("\\burl\\((?:"+t.source+"|"+/(?:[^\\\r\n()"']|\\[\s\S])*/.source+")\\)","i"),greedy:!0,inside:{function:/^url/i,punctuation:/^\(|\)$/,string:{pattern:RegExp("^"+t.source+"$"),alias:"url"}}},selector:{pattern:RegExp("(^|[{}\\s])[^{}\\s](?:[^{};\"'\\s]|\\s+(?![\\s{])|"+t.source+")*(?=\\s*\\{)"),lookbehind:!0},string:{pattern:t,greedy:!0},property:{pattern:/(^|[^-\w\xA0-\uFFFF])(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*(?=\s*:)/i,lookbehind:!0},important:/!important\b/i,function:{pattern:/(^|[^-a-z0-9])[-a-z0-9]+(?=\()/i,lookbehind:!0},punctuation:/[(){};:,]/},e.languages.css.atrule.inside.rest=e.languages.css;var n=e.languages.markup;n&&(n.tag.addInlined("style","css"),n.tag.addAttribute("style","css"))}(a),function(e){var t,n=/("|')(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/;e.languages.css.selector={pattern:e.languages.css.selector.pattern,lookbehind:!0,inside:t={"pseudo-element":/:(?:after|before|first-letter|first-line|selection)|::[-\w]+/,"pseudo-class":/:[-\w]+/,class:/\.[-\w]+/,id:/#[-\w]+/,attribute:{pattern:RegExp("\\[(?:[^[\\]\"']|"+n.source+")*\\]"),greedy:!0,inside:{punctuation:/^\[|\]$/,"case-sensitivity":{pattern:/(\s)[si]$/i,lookbehind:!0,alias:"keyword"},namespace:{pattern:/^(\s*)(?:(?!\s)[-*\w\xA0-\uFFFF])*\|(?!=)/,lookbehind:!0,inside:{punctuation:/\|$/}},"attr-name":{pattern:/^(\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+/,lookbehind:!0},"attr-value":[n,{pattern:/(=\s*)(?:(?!\s)[-\w\xA0-\uFFFF])+(?=\s*$)/,lookbehind:!0}],operator:/[|~*^$]?=/}},"n-th":[{pattern:/(\(\s*)[+-]?\d*[\dn](?:\s*[+-]\s*\d+)?(?=\s*\))/,lookbehind:!0,inside:{number:/[\dn]+/,operator:/[+-]/}},{pattern:/(\(\s*)(?:even|odd)(?=\s*\))/i,lookbehind:!0}],combinator:/>|\+|~|\|\|/,punctuation:/[(),]/}},e.languages.css.atrule.inside["selector-function-argument"].inside=t,e.languages.insertBefore("css","property",{variable:{pattern:/(^|[^-\w\xA0-\uFFFF])--(?!\s)[-_a-z\xA0-\uFFFF](?:(?!\s)[-\w\xA0-\uFFFF])*/i,lookbehind:!0}});var r={pattern:/(\b\d+)(?:%|[a-z]+(?![\w-]))/,lookbehind:!0},a={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0};e.languages.insertBefore("css","function",{operator:{pattern:/(\s)[+\-*\/](?=\s)/,lookbehind:!0},hexcode:{pattern:/\B#[\da-f]{3,8}\b/i,alias:"color"},color:[{pattern:/(^|[^\w-])(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)(?![\w-])/i,lookbehind:!0},{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:r,number:a,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:r,number:a})}(a),a.languages.javascript=a.languages.extend("clike",{"class-name":[a.languages.clike["class-name"],{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$A-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\.(?:constructor|prototype))/,lookbehind:!0}],keyword:[{pattern:/((?:^|\})\s*)catch\b/,lookbehind:!0},{pattern:/(^|[^.]|\.\.\.\s*)\b(?:as|assert(?=\s*\{)|async(?=\s*(?:function\b|\(|[$\w\xA0-\uFFFF]|$))|await|break|case|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally(?=\s*(?:\{|$))|for|from(?=\s*(?:['"]|$))|function|(?:get|set)(?=\s*(?:[#\[$\w\xA0-\uFFFF]|$))|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)\b/,lookbehind:!0}],function:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*(?:\.\s*(?:apply|bind|call)\s*)?\()/,number:{pattern:RegExp(/(^|[^\w$])/.source+"(?:"+/NaN|Infinity/.source+"|"+/0[bB][01]+(?:_[01]+)*n?/.source+"|"+/0[oO][0-7]+(?:_[0-7]+)*n?/.source+"|"+/0[xX][\dA-Fa-f]+(?:_[\dA-Fa-f]+)*n?/.source+"|"+/\d+(?:_\d+)*n/.source+"|"+/(?:\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\.\d+(?:_\d+)*)(?:[Ee][+-]?\d+(?:_\d+)*)?/.source+")"+/(?![\w$])/.source),lookbehind:!0},operator:/--|\+\+|\*\*=?|=>|&&=?|\|\|=?|[!=]==|<<=?|>>>?=?|[-+*/%&|^!=<>]=?|\.{3}|\?\?=?|\?\.?|[~:]/}),a.languages.javascript["class-name"][0].pattern=/(\b(?:class|extends|implements|instanceof|interface|new)\s+)[\w.\\]+/,a.languages.insertBefore("javascript","keyword",{regex:{pattern:/((?:^|[^$\w\xA0-\uFFFF."'\])\s]|\b(?:return|yield))\s*)\/(?:\[(?:[^\]\\\r\n]|\\.)*\]|\\.|[^/\\\[\r\n])+\/[dgimyus]{0,7}(?=(?:\s|\/\*(?:[^*]|\*(?!\/))*\*\/)*(?:$|[\r\n,.;:})\]]|\/\/))/,lookbehind:!0,greedy:!0,inside:{"regex-source":{pattern:/^(\/)[\s\S]+(?=\/[a-z]*$)/,lookbehind:!0,alias:"language-regex",inside:a.languages.regex},"regex-delimiter":/^\/|\/$/,"regex-flags":/^[a-z]+$/}},"function-variable":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*[=:]\s*(?:async\s*)?(?:\bfunction\b|(?:\((?:[^()]|\([^()]*\))*\)|(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)\s*=>))/,alias:"function"},parameter:[{pattern:/(function(?:\s+(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*)?\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\))/,lookbehind:!0,inside:a.languages.javascript},{pattern:/(^|[^$\w\xA0-\uFFFF])(?!\s)[_$a-z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*=>)/i,lookbehind:!0,inside:a.languages.javascript},{pattern:/(\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*=>)/,lookbehind:!0,inside:a.languages.javascript},{pattern:/((?:\b|\s|^)(?!(?:as|async|await|break|case|catch|class|const|continue|debugger|default|delete|do|else|enum|export|extends|finally|for|from|function|get|if|implements|import|in|instanceof|interface|let|new|null|of|package|private|protected|public|return|set|static|super|switch|this|throw|try|typeof|undefined|var|void|while|with|yield)(?![$\w\xA0-\uFFFF]))(?:(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*)\(\s*|\]\s*\(\s*)(?!\s)(?:[^()\s]|\s+(?![\s)])|\([^()]*\))+(?=\s*\)\s*\{)/,lookbehind:!0,inside:a.languages.javascript}],constant:/\b[A-Z](?:[A-Z_]|\dx?)*\b/}),a.languages.insertBefore("javascript","string",{hashbang:{pattern:/^#!.*/,greedy:!0,alias:"comment"},"template-string":{pattern:/`(?:\\[\s\S]|\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}|(?!\$\{)[^\\`])*`/,greedy:!0,inside:{"template-punctuation":{pattern:/^`|`$/,alias:"string"},interpolation:{pattern:/((?:^|[^\\])(?:\\{2})*)\$\{(?:[^{}]|\{(?:[^{}]|\{[^}]*\})*\})+\}/,lookbehind:!0,inside:{"interpolation-punctuation":{pattern:/^\$\{|\}$/,alias:"punctuation"},rest:a.languages.javascript}},string:/[\s\S]+/}},"string-property":{pattern:/((?:^|[,{])[ \t]*)(["'])(?:\\(?:\r\n|[\s\S])|(?!\2)[^\\\r\n])*\2(?=\s*:)/m,lookbehind:!0,greedy:!0,alias:"property"}}),a.languages.insertBefore("javascript","operator",{"literal-property":{pattern:/((?:^|[,{])[ \t]*)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?=\s*:)/m,lookbehind:!0,alias:"property"}}),a.languages.markup&&(a.languages.markup.tag.addInlined("script","javascript"),a.languages.markup.tag.addAttribute(/on(?:abort|blur|change|click|composition(?:end|start|update)|dblclick|error|focus(?:in|out)?|key(?:down|up)|load|mouse(?:down|enter|leave|move|out|over|up)|reset|resize|scroll|select|slotchange|submit|unload|wheel)/.source,"javascript")),a.languages.js=a.languages.javascript,function(e){var t=e.util.clone(e.languages.javascript),n=/(?:\s|\/\/.*(?!.)|\/\*(?:[^*]|\*(?!\/))\*\/)/.source,r=/(?:\{(?:\{(?:\{[^{}]*\}|[^{}])*\}|[^{}])*\})/.source,a=/(?:\{*\.{3}(?:[^{}]|)*\})/.source;function o(e,t){return e=e.replace(//g,(function(){return n})).replace(//g,(function(){return r})).replace(//g,(function(){return a})),RegExp(e,t)}a=o(a).source,e.languages.jsx=e.languages.extend("markup",t),e.languages.jsx.tag.pattern=o(/<\/?(?:[\w.:-]+(?:+(?:[\w.:$-]+(?:=(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s{'"/>=]+|))?|))**\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(//.source),inside:e.languages.jsx}},e.languages.jsx.tag),e.languages.insertBefore("inside","special-attr",{script:{pattern:o(/=/.source),alias:"language-javascript",inside:{"script-punctuation":{pattern:/^=(?=\{)/,alias:"punctuation"},rest:e.languages.jsx}}},e.languages.jsx.tag);var i=function(e){return e?"string"==typeof e?e:"string"==typeof e.content?e.content:e.content.map(i).join(""):""},l=function(t){for(var n=[],r=0;r0&&n[n.length-1].tagName===i(a.content[0].content[1])&&n.pop():"/>"===a.content[a.content.length-1].content||n.push({tagName:i(a.content[0].content[1]),openedBraces:0}):n.length>0&&"punctuation"===a.type&&"{"===a.content?n[n.length-1].openedBraces++:n.length>0&&n[n.length-1].openedBraces>0&&"punctuation"===a.type&&"}"===a.content?n[n.length-1].openedBraces--:o=!0),(o||"string"==typeof a)&&n.length>0&&0===n[n.length-1].openedBraces){var s=i(a);r0&&("string"==typeof t[r-1]||"plain-text"===t[r-1].type)&&(s=i(t[r-1])+s,t.splice(r-1,1),r--),t[r]=new e.Token("plain-text",s,null,s)}a.content&&"string"!=typeof a.content&&l(a.content)}};e.hooks.add("after-tokenize",(function(e){"jsx"!==e.language&&"tsx"!==e.language||l(e.tokens)}))}(a),function(e){function t(e,t){return RegExp(e.replace(//g,(function(){return/(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/.source})),t)}e.languages.insertBefore("javascript","function-variable",{"method-variable":{pattern:RegExp("(\\.\\s*)"+e.languages.javascript["function-variable"].pattern.source),lookbehind:!0,alias:["function-variable","method","function","property-access"]}}),e.languages.insertBefore("javascript","function",{method:{pattern:RegExp("(\\.\\s*)"+e.languages.javascript.function.source),lookbehind:!0,alias:["function","property-access"]}}),e.languages.insertBefore("javascript","constant",{"known-class-name":[{pattern:/\b(?:(?:Float(?:32|64)|(?:Int|Uint)(?:8|16|32)|Uint8Clamped)?Array|ArrayBuffer|BigInt|Boolean|DataView|Date|Error|Function|Intl|JSON|(?:Weak)?(?:Map|Set)|Math|Number|Object|Promise|Proxy|Reflect|RegExp|String|Symbol|WebAssembly)\b/,alias:"class-name"},{pattern:/\b(?:[A-Z]\w*)Error\b/,alias:"class-name"}]}),e.languages.insertBefore("javascript","keyword",{imports:{pattern:t(/(\bimport\b\s*)(?:(?:\s*,\s*(?:\*\s*as\s+|\{[^{}]*\}))?|\*\s*as\s+|\{[^{}]*\})(?=\s*\bfrom\b)/.source),lookbehind:!0,inside:e.languages.javascript},exports:{pattern:t(/(\bexport\b\s*)(?:\*(?:\s*as\s+)?(?=\s*\bfrom\b)|\{[^{}]*\})/.source),lookbehind:!0,inside:e.languages.javascript}}),e.languages.javascript.keyword.unshift({pattern:/\b(?:as|default|export|from|import)\b/,alias:"module"},{pattern:/\b(?:await|break|catch|continue|do|else|finally|for|if|return|switch|throw|try|while|yield)\b/,alias:"control-flow"},{pattern:/\bnull\b/,alias:["null","nil"]},{pattern:/\bundefined\b/,alias:"nil"}),e.languages.insertBefore("javascript","operator",{spread:{pattern:/\.{3}/,alias:"operator"},arrow:{pattern:/=>/,alias:"operator"}}),e.languages.insertBefore("javascript","punctuation",{"property-access":{pattern:t(/(\.\s*)#?/.source),lookbehind:!0},"maybe-class-name":{pattern:/(^|[^$\w\xA0-\uFFFF])[A-Z][$\w\xA0-\uFFFF]+/,lookbehind:!0},dom:{pattern:/\b(?:document|(?:local|session)Storage|location|navigator|performance|window)\b/,alias:"variable"},console:{pattern:/\bconsole(?=\s*\.)/,alias:"class-name"}});for(var n=["function","function-variable","method","method-variable","property-access"],r=0;r=f.length)return;var r=t[n];if("string"==typeof r||"string"==typeof r.content){var a=f[i],o="string"==typeof r?r:r.content,l=o.indexOf(a);if(-1!==l){++i;var s=o.substring(0,l),d=u(c[a]),p=o.substring(l+a.length),m=[];if(s&&m.push(s),m.push(d),p){var g=[p];e(g),m.push.apply(m,g)}"string"==typeof r?(t.splice.apply(t,[n,1].concat(m)),n+=m.length-1):r.content=m}}else{var h=r.content;Array.isArray(h)?e(h):e([h])}}}(d),new e.Token(r,d,"language-"+r,t)}e.languages.javascript["template-string"]=[i("css",/\b(?:styled(?:\([^)]*\))?(?:\s*\.\s*\w+(?:\([^)]*\))*)*|css(?:\s*\.\s*(?:global|resolve))?|createGlobalStyle|keyframes)/.source),i("html",/\bhtml|\.\s*(?:inner|outer)HTML\s*\+?=/.source),i("svg",/\bsvg/.source),i("markdown",/\b(?:markdown|md)/.source),i("graphql",/\b(?:gql|graphql(?:\s*\.\s*experimental)?)/.source),i("sql",/\bsql/.source),t].filter(Boolean);var d={javascript:!0,js:!0,typescript:!0,ts:!0,jsx:!0,tsx:!0};function f(e){return"string"==typeof e?e:Array.isArray(e)?e.map(f).join(""):f(e.content)}e.hooks.add("after-tokenize",(function(t){t.language in d&&function t(n){for(var r=0,a=n.length;r",unchanged:" ",diff:"!"};Object.keys(t).forEach((function(n){var r=t[n],a=[];/^\w+$/.test(n)||a.push(/\w+/.exec(n)[0]),"diff"===n&&a.push("bold"),e.languages.diff[n]={pattern:RegExp("^(?:["+r+"].*(?:\r\n?|\n|(?![\\s\\S])))+","m"),alias:a,inside:{line:{pattern:/(.)(?=[\s\S]).*(?:\r\n?|\n)?/,lookbehind:!0},prefix:{pattern:/[\s\S]/,alias:/\w+/.exec(n)[0]}}}})),Object.defineProperty(e.languages.diff,"PREFIXES",{value:t})}(a),a.languages.git={comment:/^#.*/m,deleted:/^[-\u2013].*/m,inserted:/^\+.*/m,string:/("|')(?:\\.|(?!\1)[^\\\r\n])*\1/,command:{pattern:/^.*\$ git .*$/m,inside:{parameter:/\s--?\w+/}},coord:/^@@.*@@$/m,"commit-sha1":/^commit \w{40}$/m},a.languages.go=a.languages.extend("clike",{string:{pattern:/(^|[^\\])"(?:\\.|[^"\\\r\n])*"|`[^`]*`/,lookbehind:!0,greedy:!0},keyword:/\b(?:break|case|chan|const|continue|default|defer|else|fallthrough|for|func|go(?:to)?|if|import|interface|map|package|range|return|select|struct|switch|type|var)\b/,boolean:/\b(?:_|false|iota|nil|true)\b/,number:[/\b0(?:b[01_]+|o[0-7_]+)i?\b/i,/\b0x(?:[a-f\d_]+(?:\.[a-f\d_]*)?|\.[a-f\d_]+)(?:p[+-]?\d+(?:_\d+)*)?i?(?!\w)/i,/(?:\b\d[\d_]*(?:\.[\d_]*)?|\B\.\d[\d_]*)(?:e[+-]?[\d_]+)?i?(?!\w)/i],operator:/[*\/%^!=]=?|\+[=+]?|-[=-]?|\|[=|]?|&(?:=|&|\^=?)?|>(?:>=?|=)?|<(?:<=?|=|-)?|:=|\.\.\./,builtin:/\b(?:append|bool|byte|cap|close|complex|complex(?:64|128)|copy|delete|error|float(?:32|64)|u?int(?:8|16|32|64)?|imag|len|make|new|panic|print(?:ln)?|real|recover|rune|string|uintptr)\b/}),a.languages.insertBefore("go","string",{char:{pattern:/'(?:\\.|[^'\\\r\n]){0,10}'/,greedy:!0}}),delete a.languages.go["class-name"],a.languages.graphql={comment:/#.*/,description:{pattern:/(?:"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*")(?=\s*[a-z_])/i,greedy:!0,alias:"string",inside:{"language-markdown":{pattern:/(^"(?:"")?)(?!\1)[\s\S]+(?=\1$)/,lookbehind:!0,inside:a.languages.markdown}}},string:{pattern:/"""(?:[^"]|(?!""")")*"""|"(?:\\.|[^\\"\r\n])*"/,greedy:!0},number:/(?:\B-|\b)\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,boolean:/\b(?:false|true)\b/,variable:/\$[a-z_]\w*/i,directive:{pattern:/@[a-z_]\w*/i,alias:"function"},"attr-name":{pattern:/\b[a-z_]\w*(?=\s*(?:\((?:[^()"]|"(?:\\.|[^\\"\r\n])*")*\))?:)/i,greedy:!0},"atom-input":{pattern:/\b[A-Z]\w*Input\b/,alias:"class-name"},scalar:/\b(?:Boolean|Float|ID|Int|String)\b/,constant:/\b[A-Z][A-Z_\d]*\b/,"class-name":{pattern:/(\b(?:enum|implements|interface|on|scalar|type|union)\s+|&\s*|:\s*|\[)[A-Z_]\w*/,lookbehind:!0},fragment:{pattern:/(\bfragment\s+|\.{3}\s*(?!on\b))[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-mutation":{pattern:/(\bmutation\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},"definition-query":{pattern:/(\bquery\s+)[a-zA-Z_]\w*/,lookbehind:!0,alias:"function"},keyword:/\b(?:directive|enum|extend|fragment|implements|input|interface|mutation|on|query|repeatable|scalar|schema|subscription|type|union)\b/,operator:/[!=|&]|\.{3}/,"property-query":/\w+(?=\s*\()/,object:/\w+(?=\s*\{)/,punctuation:/[!(){}\[\]:=,]/,property:/\w+/},a.hooks.add("after-tokenize",(function(e){if("graphql"===e.language)for(var t=e.tokens.filter((function(e){return"string"!=typeof e&&"comment"!==e.type&&"scalar"!==e.type})),n=0;n0)){var l=f(/^\{$/,/^\}$/);if(-1===l)continue;for(var s=n;s=0&&p(u,"variable-input")}}}}function c(e){return t[n+e]}function d(e,t){t=t||0;for(var n=0;n=o.length);s++){var u=l[s];if("string"==typeof u||u.content&&"string"==typeof u.content){var c=o[a],d=n.tokenStack[c],f="string"==typeof u?u:u.content,p=t(r,c),m=f.indexOf(p);if(m>-1){++a;var g=f.substring(0,m),h=new e.Token(r,e.tokenize(d,n.grammar),"language-"+r,d),b=f.substring(m+p.length),v=[];g&&v.push.apply(v,i([g])),v.push(h),b&&v.push.apply(v,i([b])),"string"==typeof u?l.splice.apply(l,[s,1].concat(v)):u.content=v}}else u.content&&i(u.content)}return l}(n.tokens)}}}})}(a),function(e){e.languages.handlebars={comment:/\{\{![\s\S]*?\}\}/,delimiter:{pattern:/^\{\{\{?|\}\}\}?$/,alias:"punctuation"},string:/(["'])(?:\\.|(?!\1)[^\\\r\n])*\1/,number:/\b0x[\dA-Fa-f]+\b|(?:\b\d+(?:\.\d*)?|\B\.\d+)(?:[Ee][+-]?\d+)?/,boolean:/\b(?:false|true)\b/,block:{pattern:/^(\s*(?:~\s*)?)[#\/]\S+?(?=\s*(?:~\s*)?$|\s)/,lookbehind:!0,alias:"keyword"},brackets:{pattern:/\[[^\]]+\]/,inside:{punctuation:/\[|\]/,variable:/[\s\S]+/}},punctuation:/[!"#%&':()*+,.\/;<=>@\[\\\]^`{|}~]/,variable:/[^!"#%&'()*+,\/;<=>@\[\\\]^`{|}~\s]+/},e.hooks.add("before-tokenize",(function(t){e.languages["markup-templating"].buildPlaceholders(t,"handlebars",/\{\{\{[\s\S]+?\}\}\}|\{\{[\s\S]+?\}\}/g)})),e.hooks.add("after-tokenize",(function(t){e.languages["markup-templating"].tokenizePlaceholders(t,"handlebars")})),e.languages.hbs=e.languages.handlebars}(a),a.languages.json={property:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?=\s*:)/,lookbehind:!0,greedy:!0},string:{pattern:/(^|[^\\])"(?:\\.|[^\\"\r\n])*"(?!\s*:)/,lookbehind:!0,greedy:!0},comment:{pattern:/\/\/.*|\/\*[\s\S]*?(?:\*\/|$)/,greedy:!0},number:/-?\b\d+(?:\.\d+)?(?:e[+-]?\d+)?\b/i,punctuation:/[{}[\],]/,operator:/:/,boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"}},a.languages.webmanifest=a.languages.json,a.languages.less=a.languages.extend("css",{comment:[/\/\*[\s\S]*?\*\//,{pattern:/(^|[^\\])\/\/.*/,lookbehind:!0}],atrule:{pattern:/@[\w-](?:\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{punctuation:/[:()]/}},selector:{pattern:/(?:@\{[\w-]+\}|[^{};\s@])(?:@\{[\w-]+\}|\((?:[^(){}]|\([^(){}]*\))*\)|[^(){};@\s]|\s+(?!\s))*?(?=\s*\{)/,inside:{variable:/@+[\w-]+/}},property:/(?:@\{[\w-]+\}|[\w-])+(?:\+_?)?(?=\s*:)/,operator:/[+\-*\/]/}),a.languages.insertBefore("less","property",{variable:[{pattern:/@[\w-]+\s*:/,inside:{punctuation:/:/}},/@@?[\w-]+/],"mixin-usage":{pattern:/([{;]\s*)[.#](?!\d)[\w-].*?(?=[(;])/,lookbehind:!0,alias:"function"}}),a.languages.makefile={comment:{pattern:/(^|[^\\])#(?:\\(?:\r\n|[\s\S])|[^\\\r\n])*/,lookbehind:!0},string:{pattern:/(["'])(?:\\(?:\r\n|[\s\S])|(?!\1)[^\\\r\n])*\1/,greedy:!0},"builtin-target":{pattern:/\.[A-Z][^:#=\s]+(?=\s*:(?!=))/,alias:"builtin"},target:{pattern:/^(?:[^:=\s]|[ \t]+(?![\s:]))+(?=\s*:(?!=))/m,alias:"symbol",inside:{variable:/\$+(?:(?!\$)[^(){}:#=\s]+|(?=[({]))/}},variable:/\$+(?:(?!\$)[^(){}:#=\s]+|\([@*%<^+?][DF]\)|(?=[({]))/,keyword:/-include\b|\b(?:define|else|endef|endif|export|ifn?def|ifn?eq|include|override|private|sinclude|undefine|unexport|vpath)\b/,function:{pattern:/(\()(?:abspath|addsuffix|and|basename|call|dir|error|eval|file|filter(?:-out)?|findstring|firstword|flavor|foreach|guile|if|info|join|lastword|load|notdir|or|origin|patsubst|realpath|shell|sort|strip|subst|suffix|value|warning|wildcard|word(?:list|s)?)(?=[ \t])/,lookbehind:!0},operator:/(?:::|[?:+!])?=|[|@]/,punctuation:/[:;(){}]/},function(e){var t=/(?:\\.|[^\\\n\r]|(?:\n|\r\n?)(?![\r\n]))/.source;function n(e){return e=e.replace(//g,(function(){return t})),RegExp(/((?:^|[^\\])(?:\\{2})*)/.source+"(?:"+e+")")}var r=/(?:\\.|``(?:[^`\r\n]|`(?!`))+``|`[^`\r\n]+`|[^\\|\r\n`])+/.source,a=/\|?__(?:\|__)+\|?(?:(?:\n|\r\n?)|(?![\s\S]))/.source.replace(/__/g,(function(){return r})),o=/\|?[ \t]*:?-{3,}:?[ \t]*(?:\|[ \t]*:?-{3,}:?[ \t]*)+\|?(?:\n|\r\n?)/.source;e.languages.markdown=e.languages.extend("markup",{}),e.languages.insertBefore("markdown","prolog",{"front-matter-block":{pattern:/(^(?:\s*[\r\n])?)---(?!.)[\s\S]*?[\r\n]---(?!.)/,lookbehind:!0,greedy:!0,inside:{punctuation:/^---|---$/,"front-matter":{pattern:/\S+(?:\s+\S+)*/,alias:["yaml","language-yaml"],inside:e.languages.yaml}}},blockquote:{pattern:/^>(?:[\t ]*>)*/m,alias:"punctuation"},table:{pattern:RegExp("^"+a+o+"(?:"+a+")*","m"),inside:{"table-data-rows":{pattern:RegExp("^("+a+o+")(?:"+a+")*$"),lookbehind:!0,inside:{"table-data":{pattern:RegExp(r),inside:e.languages.markdown},punctuation:/\|/}},"table-line":{pattern:RegExp("^("+a+")"+o+"$"),lookbehind:!0,inside:{punctuation:/\||:?-{3,}:?/}},"table-header-row":{pattern:RegExp("^"+a+"$"),inside:{"table-header":{pattern:RegExp(r),alias:"important",inside:e.languages.markdown},punctuation:/\|/}}}},code:[{pattern:/((?:^|\n)[ \t]*\n|(?:^|\r\n?)[ \t]*\r\n?)(?: {4}|\t).+(?:(?:\n|\r\n?)(?: {4}|\t).+)*/,lookbehind:!0,alias:"keyword"},{pattern:/^```[\s\S]*?^```$/m,greedy:!0,inside:{"code-block":{pattern:/^(```.*(?:\n|\r\n?))[\s\S]+?(?=(?:\n|\r\n?)^```$)/m,lookbehind:!0},"code-language":{pattern:/^(```).+/,lookbehind:!0},punctuation:/```/}}],title:[{pattern:/\S.*(?:\n|\r\n?)(?:==+|--+)(?=[ \t]*$)/m,alias:"important",inside:{punctuation:/==+$|--+$/}},{pattern:/(^\s*)#.+/m,lookbehind:!0,alias:"important",inside:{punctuation:/^#+|#+$/}}],hr:{pattern:/(^\s*)([*-])(?:[\t ]*\2){2,}(?=\s*$)/m,lookbehind:!0,alias:"punctuation"},list:{pattern:/(^\s*)(?:[*+-]|\d+\.)(?=[\t ].)/m,lookbehind:!0,alias:"punctuation"},"url-reference":{pattern:/!?\[[^\]]+\]:[\t ]+(?:\S+|<(?:\\.|[^>\\])+>)(?:[\t ]+(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\)))?/,inside:{variable:{pattern:/^(!?\[)[^\]]+/,lookbehind:!0},string:/(?:"(?:\\.|[^"\\])*"|'(?:\\.|[^'\\])*'|\((?:\\.|[^)\\])*\))$/,punctuation:/^[\[\]!:]|[<>]/},alias:"url"},bold:{pattern:n(/\b__(?:(?!_)|_(?:(?!_))+_)+__\b|\*\*(?:(?!\*)|\*(?:(?!\*))+\*)+\*\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^..)[\s\S]+(?=..$)/,lookbehind:!0,inside:{}},punctuation:/\*\*|__/}},italic:{pattern:n(/\b_(?:(?!_)|__(?:(?!_))+__)+_\b|\*(?:(?!\*)|\*\*(?:(?!\*))+\*\*)+\*/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^.)[\s\S]+(?=.$)/,lookbehind:!0,inside:{}},punctuation:/[*_]/}},strike:{pattern:n(/(~~?)(?:(?!~))+\2/.source),lookbehind:!0,greedy:!0,inside:{content:{pattern:/(^~~?)[\s\S]+(?=\1$)/,lookbehind:!0,inside:{}},punctuation:/~~?/}},"code-snippet":{pattern:/(^|[^\\`])(?:``[^`\r\n]+(?:`[^`\r\n]+)*``(?!`)|`[^`\r\n]+`(?!`))/,lookbehind:!0,greedy:!0,alias:["code","keyword"]},url:{pattern:n(/!?\[(?:(?!\]))+\](?:\([^\s)]+(?:[\t ]+"(?:\\.|[^"\\])*")?\)|[ \t]?\[(?:(?!\]))+\])/.source),lookbehind:!0,greedy:!0,inside:{operator:/^!/,content:{pattern:/(^\[)[^\]]+(?=\])/,lookbehind:!0,inside:{}},variable:{pattern:/(^\][ \t]?\[)[^\]]+(?=\]$)/,lookbehind:!0},url:{pattern:/(^\]\()[^\s)]+/,lookbehind:!0},string:{pattern:/(^[ \t]+)"(?:\\.|[^"\\])*"(?=\)$)/,lookbehind:!0}}}}),["url","bold","italic","strike"].forEach((function(t){["url","bold","italic","strike","code-snippet"].forEach((function(n){t!==n&&(e.languages.markdown[t].inside.content.inside[n]=e.languages.markdown[n])}))})),e.hooks.add("after-tokenize",(function(e){"markdown"!==e.language&&"md"!==e.language||function e(t){if(t&&"string"!=typeof t)for(var n=0,r=t.length;n",quot:'"'},s=String.fromCodePoint||String.fromCharCode;e.languages.md=e.languages.markdown}(a),a.languages.objectivec=a.languages.extend("c",{string:{pattern:/@?"(?:\\(?:\r\n|[\s\S])|[^"\\\r\n])*"/,greedy:!0},keyword:/\b(?:asm|auto|break|case|char|const|continue|default|do|double|else|enum|extern|float|for|goto|if|in|inline|int|long|register|return|self|short|signed|sizeof|static|struct|super|switch|typedef|typeof|union|unsigned|void|volatile|while)\b|(?:@interface|@end|@implementation|@protocol|@class|@public|@protected|@private|@property|@try|@catch|@finally|@throw|@synthesize|@dynamic|@selector)\b/,operator:/-[->]?|\+\+?|!=?|<>?=?|==?|&&?|\|\|?|[~^%?*\/@]/}),delete a.languages.objectivec["class-name"],a.languages.objc=a.languages.objectivec,a.languages.ocaml={comment:{pattern:/\(\*[\s\S]*?\*\)/,greedy:!0},char:{pattern:/'(?:[^\\\r\n']|\\(?:.|[ox]?[0-9a-f]{1,3}))'/i,greedy:!0},string:[{pattern:/"(?:\\(?:[\s\S]|\r\n)|[^\\\r\n"])*"/,greedy:!0},{pattern:/\{([a-z_]*)\|[\s\S]*?\|\1\}/,greedy:!0}],number:[/\b(?:0b[01][01_]*|0o[0-7][0-7_]*)\b/i,/\b0x[a-f0-9][a-f0-9_]*(?:\.[a-f0-9_]*)?(?:p[+-]?\d[\d_]*)?(?!\w)/i,/\b\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?\d[\d_]*)?(?!\w)/i],directive:{pattern:/\B#\w+/,alias:"property"},label:{pattern:/\B~\w+/,alias:"property"},"type-variable":{pattern:/\B'\w+/,alias:"function"},variant:{pattern:/`\w+/,alias:"symbol"},keyword:/\b(?:as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|match|method|module|mutable|new|nonrec|object|of|open|private|rec|sig|struct|then|to|try|type|val|value|virtual|when|where|while|with)\b/,boolean:/\b(?:false|true)\b/,"operator-like-punctuation":{pattern:/\[[<>|]|[>|]\]|\{<|>\}/,alias:"punctuation"},operator:/\.[.~]|:[=>]|[=<>@^|&+\-*\/$%!?~][!$%&*+\-.\/:<=>?@^|~]*|\b(?:and|asr|land|lor|lsl|lsr|lxor|mod|or)\b/,punctuation:/;;|::|[(){}\[\].,:;#]|\b_\b/},a.languages.python={comment:{pattern:/(^|[^\\])#.*/,lookbehind:!0,greedy:!0},"string-interpolation":{pattern:/(?:f|fr|rf)(?:("""|''')[\s\S]*?\1|("|')(?:\\.|(?!\2)[^\\\r\n])*\2)/i,greedy:!0,inside:{interpolation:{pattern:/((?:^|[^{])(?:\{\{)*)\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}]|\{(?!\{)(?:[^{}])+\})+\})+\}/,lookbehind:!0,inside:{"format-spec":{pattern:/(:)[^:(){}]+(?=\}$)/,lookbehind:!0},"conversion-option":{pattern:/![sra](?=[:}]$)/,alias:"punctuation"},rest:null}},string:/[\s\S]+/}},"triple-quoted-string":{pattern:/(?:[rub]|br|rb)?("""|''')[\s\S]*?\1/i,greedy:!0,alias:"string"},string:{pattern:/(?:[rub]|br|rb)?("|')(?:\\.|(?!\1)[^\\\r\n])*\1/i,greedy:!0},function:{pattern:/((?:^|\s)def[ \t]+)[a-zA-Z_]\w*(?=\s*\()/g,lookbehind:!0},"class-name":{pattern:/(\bclass\s+)\w+/i,lookbehind:!0},decorator:{pattern:/(^[\t ]*)@\w+(?:\.\w+)*/m,lookbehind:!0,alias:["annotation","punctuation"],inside:{punctuation:/\./}},keyword:/\b(?:_(?=\s*:)|and|as|assert|async|await|break|case|class|continue|def|del|elif|else|except|exec|finally|for|from|global|if|import|in|is|lambda|match|nonlocal|not|or|pass|print|raise|return|try|while|with|yield)\b/,builtin:/\b(?:__import__|abs|all|any|apply|ascii|basestring|bin|bool|buffer|bytearray|bytes|callable|chr|classmethod|cmp|coerce|compile|complex|delattr|dict|dir|divmod|enumerate|eval|execfile|file|filter|float|format|frozenset|getattr|globals|hasattr|hash|help|hex|id|input|int|intern|isinstance|issubclass|iter|len|list|locals|long|map|max|memoryview|min|next|object|oct|open|ord|pow|property|range|raw_input|reduce|reload|repr|reversed|round|set|setattr|slice|sorted|staticmethod|str|sum|super|tuple|type|unichr|unicode|vars|xrange|zip)\b/,boolean:/\b(?:False|None|True)\b/,number:/\b0(?:b(?:_?[01])+|o(?:_?[0-7])+|x(?:_?[a-f0-9])+)\b|(?:\b\d+(?:_\d+)*(?:\.(?:\d+(?:_\d+)*)?)?|\B\.\d+(?:_\d+)*)(?:e[+-]?\d+(?:_\d+)*)?j?(?!\w)/i,operator:/[-+%=]=?|!=|:=|\*\*?=?|\/\/?=?|<[<=>]?|>[=>]?|[&|^~]/,punctuation:/[{}[\];(),.:]/},a.languages.python["string-interpolation"].inside.interpolation.inside.rest=a.languages.python,a.languages.py=a.languages.python,a.languages.reason=a.languages.extend("clike",{string:{pattern:/"(?:\\(?:\r\n|[\s\S])|[^\\\r\n"])*"/,greedy:!0},"class-name":/\b[A-Z]\w*/,keyword:/\b(?:and|as|assert|begin|class|constraint|do|done|downto|else|end|exception|external|for|fun|function|functor|if|in|include|inherit|initializer|lazy|let|method|module|mutable|new|nonrec|object|of|open|or|private|rec|sig|struct|switch|then|to|try|type|val|virtual|when|while|with)\b/,operator:/\.{3}|:[:=]|\|>|->|=(?:==?|>)?|<=?|>=?|[|^?'#!~`]|[+\-*\/]\.?|\b(?:asr|land|lor|lsl|lsr|lxor|mod)\b/}),a.languages.insertBefore("reason","class-name",{char:{pattern:/'(?:\\x[\da-f]{2}|\\o[0-3][0-7][0-7]|\\\d{3}|\\.|[^'\\\r\n])'/,greedy:!0},constructor:/\b[A-Z]\w*\b(?!\s*\.)/,label:{pattern:/\b[a-z]\w*(?=::)/,alias:"symbol"}}),delete a.languages.reason.function,function(e){e.languages.sass=e.languages.extend("css",{comment:{pattern:/^([ \t]*)\/[\/*].*(?:(?:\r?\n|\r)\1[ \t].+)*/m,lookbehind:!0,greedy:!0}}),e.languages.insertBefore("sass","atrule",{"atrule-line":{pattern:/^(?:[ \t]*)[@+=].+/m,greedy:!0,inside:{atrule:/(?:@[\w-]+|[+=])/}}}),delete e.languages.sass.atrule;var t=/\$[-\w]+|#\{\$[-\w]+\}/,n=[/[+*\/%]|[=!]=|<=?|>=?|\b(?:and|not|or)\b/,{pattern:/(\s)-(?=\s)/,lookbehind:!0}];e.languages.insertBefore("sass","property",{"variable-line":{pattern:/^[ \t]*\$.+/m,greedy:!0,inside:{punctuation:/:/,variable:t,operator:n}},"property-line":{pattern:/^[ \t]*(?:[^:\s]+ *:.*|:[^:\s].*)/m,greedy:!0,inside:{property:[/[^:\s]+(?=\s*:)/,{pattern:/(:)[^:\s]+/,lookbehind:!0}],punctuation:/:/,variable:t,operator:n,important:e.languages.sass.important}}}),delete e.languages.sass.property,delete e.languages.sass.important,e.languages.insertBefore("sass","punctuation",{selector:{pattern:/^([ \t]*)\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*(?:,(?:\r?\n|\r)\1[ \t]+\S(?:,[^,\r\n]+|[^,\r\n]*)(?:,[^,\r\n]+)*)*/m,lookbehind:!0,greedy:!0}})}(a),a.languages.scss=a.languages.extend("css",{comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},atrule:{pattern:/@[\w-](?:\([^()]+\)|[^()\s]|\s+(?!\s))*?(?=\s+[{;])/,inside:{rule:/@[\w-]+/}},url:/(?:[-a-z]+-)?url(?=\()/i,selector:{pattern:/(?=\S)[^@;{}()]?(?:[^@;{}()\s]|\s+(?!\s)|#\{\$[-\w]+\})+(?=\s*\{(?:\}|\s|[^}][^:{}]*[:{][^}]))/,inside:{parent:{pattern:/&/,alias:"important"},placeholder:/%[-\w]+/,variable:/\$[-\w]+|#\{\$[-\w]+\}/}},property:{pattern:/(?:[-\w]|\$[-\w]|#\{\$[-\w]+\})+(?=\s*:)/,inside:{variable:/\$[-\w]+|#\{\$[-\w]+\}/}}}),a.languages.insertBefore("scss","atrule",{keyword:[/@(?:content|debug|each|else(?: if)?|extend|for|forward|function|if|import|include|mixin|return|use|warn|while)\b/i,{pattern:/( )(?:from|through)(?= )/,lookbehind:!0}]}),a.languages.insertBefore("scss","important",{variable:/\$[-\w]+|#\{\$[-\w]+\}/}),a.languages.insertBefore("scss","function",{"module-modifier":{pattern:/\b(?:as|hide|show|with)\b/i,alias:"keyword"},placeholder:{pattern:/%[-\w]+/,alias:"selector"},statement:{pattern:/\B!(?:default|optional)\b/i,alias:"keyword"},boolean:/\b(?:false|true)\b/,null:{pattern:/\bnull\b/,alias:"keyword"},operator:{pattern:/(\s)(?:[-+*\/%]|[=!]=|<=?|>=?|and|not|or)(?=\s)/,lookbehind:!0}}),a.languages.scss.atrule.inside.rest=a.languages.scss,a.languages.sql={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|(?:--|\/\/|#).*)/,lookbehind:!0},variable:[{pattern:/@(["'`])(?:\\[\s\S]|(?!\1)[^\\])+\1/,greedy:!0},/@[\w.$]+/],string:{pattern:/(^|[^@\\])("|')(?:\\[\s\S]|(?!\2)[^\\]|\2\2)*\2/,greedy:!0,lookbehind:!0},identifier:{pattern:/(^|[^@\\])`(?:\\[\s\S]|[^`\\]|``)*`/,greedy:!0,lookbehind:!0,inside:{punctuation:/^`|`$/}},function:/\b(?:AVG|COUNT|FIRST|FORMAT|LAST|LCASE|LEN|MAX|MID|MIN|MOD|NOW|ROUND|SUM|UCASE)(?=\s*\()/i,keyword:/\b(?:ACTION|ADD|AFTER|ALGORITHM|ALL|ALTER|ANALYZE|ANY|APPLY|AS|ASC|AUTHORIZATION|AUTO_INCREMENT|BACKUP|BDB|BEGIN|BERKELEYDB|BIGINT|BINARY|BIT|BLOB|BOOL|BOOLEAN|BREAK|BROWSE|BTREE|BULK|BY|CALL|CASCADED?|CASE|CHAIN|CHAR(?:ACTER|SET)?|CHECK(?:POINT)?|CLOSE|CLUSTERED|COALESCE|COLLATE|COLUMNS?|COMMENT|COMMIT(?:TED)?|COMPUTE|CONNECT|CONSISTENT|CONSTRAINT|CONTAINS(?:TABLE)?|CONTINUE|CONVERT|CREATE|CROSS|CURRENT(?:_DATE|_TIME|_TIMESTAMP|_USER)?|CURSOR|CYCLE|DATA(?:BASES?)?|DATE(?:TIME)?|DAY|DBCC|DEALLOCATE|DEC|DECIMAL|DECLARE|DEFAULT|DEFINER|DELAYED|DELETE|DELIMITERS?|DENY|DESC|DESCRIBE|DETERMINISTIC|DISABLE|DISCARD|DISK|DISTINCT|DISTINCTROW|DISTRIBUTED|DO|DOUBLE|DROP|DUMMY|DUMP(?:FILE)?|DUPLICATE|ELSE(?:IF)?|ENABLE|ENCLOSED|END|ENGINE|ENUM|ERRLVL|ERRORS|ESCAPED?|EXCEPT|EXEC(?:UTE)?|EXISTS|EXIT|EXPLAIN|EXTENDED|FETCH|FIELDS|FILE|FILLFACTOR|FIRST|FIXED|FLOAT|FOLLOWING|FOR(?: EACH ROW)?|FORCE|FOREIGN|FREETEXT(?:TABLE)?|FROM|FULL|FUNCTION|GEOMETRY(?:COLLECTION)?|GLOBAL|GOTO|GRANT|GROUP|HANDLER|HASH|HAVING|HOLDLOCK|HOUR|IDENTITY(?:COL|_INSERT)?|IF|IGNORE|IMPORT|INDEX|INFILE|INNER|INNODB|INOUT|INSERT|INT|INTEGER|INTERSECT|INTERVAL|INTO|INVOKER|ISOLATION|ITERATE|JOIN|KEYS?|KILL|LANGUAGE|LAST|LEAVE|LEFT|LEVEL|LIMIT|LINENO|LINES|LINESTRING|LOAD|LOCAL|LOCK|LONG(?:BLOB|TEXT)|LOOP|MATCH(?:ED)?|MEDIUM(?:BLOB|INT|TEXT)|MERGE|MIDDLEINT|MINUTE|MODE|MODIFIES|MODIFY|MONTH|MULTI(?:LINESTRING|POINT|POLYGON)|NATIONAL|NATURAL|NCHAR|NEXT|NO|NONCLUSTERED|NULLIF|NUMERIC|OFF?|OFFSETS?|ON|OPEN(?:DATASOURCE|QUERY|ROWSET)?|OPTIMIZE|OPTION(?:ALLY)?|ORDER|OUT(?:ER|FILE)?|OVER|PARTIAL|PARTITION|PERCENT|PIVOT|PLAN|POINT|POLYGON|PRECEDING|PRECISION|PREPARE|PREV|PRIMARY|PRINT|PRIVILEGES|PROC(?:EDURE)?|PUBLIC|PURGE|QUICK|RAISERROR|READS?|REAL|RECONFIGURE|REFERENCES|RELEASE|RENAME|REPEAT(?:ABLE)?|REPLACE|REPLICATION|REQUIRE|RESIGNAL|RESTORE|RESTRICT|RETURN(?:ING|S)?|REVOKE|RIGHT|ROLLBACK|ROUTINE|ROW(?:COUNT|GUIDCOL|S)?|RTREE|RULE|SAVE(?:POINT)?|SCHEMA|SECOND|SELECT|SERIAL(?:IZABLE)?|SESSION(?:_USER)?|SET(?:USER)?|SHARE|SHOW|SHUTDOWN|SIMPLE|SMALLINT|SNAPSHOT|SOME|SONAME|SQL|START(?:ING)?|STATISTICS|STATUS|STRIPED|SYSTEM_USER|TABLES?|TABLESPACE|TEMP(?:ORARY|TABLE)?|TERMINATED|TEXT(?:SIZE)?|THEN|TIME(?:STAMP)?|TINY(?:BLOB|INT|TEXT)|TOP?|TRAN(?:SACTIONS?)?|TRIGGER|TRUNCATE|TSEQUAL|TYPES?|UNBOUNDED|UNCOMMITTED|UNDEFINED|UNION|UNIQUE|UNLOCK|UNPIVOT|UNSIGNED|UPDATE(?:TEXT)?|USAGE|USE|USER|USING|VALUES?|VAR(?:BINARY|CHAR|CHARACTER|YING)|VIEW|WAITFOR|WARNINGS|WHEN|WHERE|WHILE|WITH(?: ROLLUP|IN)?|WORK|WRITE(?:TEXT)?|YEAR)\b/i,boolean:/\b(?:FALSE|NULL|TRUE)\b/i,number:/\b0x[\da-f]+\b|\b\d+(?:\.\d*)?|\B\.\d+\b/i,operator:/[-+*\/=%^~]|&&?|\|\|?|!=?|<(?:=>?|<|>)?|>[>=]?|\b(?:AND|BETWEEN|DIV|ILIKE|IN|IS|LIKE|NOT|OR|REGEXP|RLIKE|SOUNDS LIKE|XOR)\b/i,punctuation:/[;[\]()`,.]/},function(e){var t={pattern:/(\b\d+)(?:%|[a-z]+)/,lookbehind:!0},n={pattern:/(^|[^\w.-])-?(?:\d+(?:\.\d+)?|\.\d+)/,lookbehind:!0},r={comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0},url:{pattern:/\burl\((["']?).*?\1\)/i,greedy:!0},string:{pattern:/("|')(?:(?!\1)[^\\\r\n]|\\(?:\r\n|[\s\S]))*\1/,greedy:!0},interpolation:null,func:null,important:/\B!(?:important|optional)\b/i,keyword:{pattern:/(^|\s+)(?:(?:else|for|if|return|unless)(?=\s|$)|@[\w-]+)/,lookbehind:!0},hexcode:/#[\da-f]{3,6}/i,color:[/\b(?:AliceBlue|AntiqueWhite|Aqua|Aquamarine|Azure|Beige|Bisque|Black|BlanchedAlmond|Blue|BlueViolet|Brown|BurlyWood|CadetBlue|Chartreuse|Chocolate|Coral|CornflowerBlue|Cornsilk|Crimson|Cyan|DarkBlue|DarkCyan|DarkGoldenRod|DarkGr[ae]y|DarkGreen|DarkKhaki|DarkMagenta|DarkOliveGreen|DarkOrange|DarkOrchid|DarkRed|DarkSalmon|DarkSeaGreen|DarkSlateBlue|DarkSlateGr[ae]y|DarkTurquoise|DarkViolet|DeepPink|DeepSkyBlue|DimGr[ae]y|DodgerBlue|FireBrick|FloralWhite|ForestGreen|Fuchsia|Gainsboro|GhostWhite|Gold|GoldenRod|Gr[ae]y|Green|GreenYellow|HoneyDew|HotPink|IndianRed|Indigo|Ivory|Khaki|Lavender|LavenderBlush|LawnGreen|LemonChiffon|LightBlue|LightCoral|LightCyan|LightGoldenRodYellow|LightGr[ae]y|LightGreen|LightPink|LightSalmon|LightSeaGreen|LightSkyBlue|LightSlateGr[ae]y|LightSteelBlue|LightYellow|Lime|LimeGreen|Linen|Magenta|Maroon|MediumAquaMarine|MediumBlue|MediumOrchid|MediumPurple|MediumSeaGreen|MediumSlateBlue|MediumSpringGreen|MediumTurquoise|MediumVioletRed|MidnightBlue|MintCream|MistyRose|Moccasin|NavajoWhite|Navy|OldLace|Olive|OliveDrab|Orange|OrangeRed|Orchid|PaleGoldenRod|PaleGreen|PaleTurquoise|PaleVioletRed|PapayaWhip|PeachPuff|Peru|Pink|Plum|PowderBlue|Purple|Red|RosyBrown|RoyalBlue|SaddleBrown|Salmon|SandyBrown|SeaGreen|SeaShell|Sienna|Silver|SkyBlue|SlateBlue|SlateGr[ae]y|Snow|SpringGreen|SteelBlue|Tan|Teal|Thistle|Tomato|Transparent|Turquoise|Violet|Wheat|White|WhiteSmoke|Yellow|YellowGreen)\b/i,{pattern:/\b(?:hsl|rgb)\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*\)\B|\b(?:hsl|rgb)a\(\s*\d{1,3}\s*,\s*\d{1,3}%?\s*,\s*\d{1,3}%?\s*,\s*(?:0|0?\.\d+|1)\s*\)\B/i,inside:{unit:t,number:n,function:/[\w-]+(?=\()/,punctuation:/[(),]/}}],entity:/\\[\da-f]{1,8}/i,unit:t,boolean:/\b(?:false|true)\b/,operator:[/~|[+!\/%<>?=]=?|[-:]=|\*[*=]?|\.{2,3}|&&|\|\||\B-\B|\b(?:and|in|is(?: a| defined| not|nt)?|not|or)\b/],number:n,punctuation:/[{}()\[\];:,]/};r.interpolation={pattern:/\{[^\r\n}:]+\}/,alias:"variable",inside:{delimiter:{pattern:/^\{|\}$/,alias:"punctuation"},rest:r}},r.func={pattern:/[\w-]+\([^)]*\).*/,inside:{function:/^[^(]+/,rest:r}},e.languages.stylus={"atrule-declaration":{pattern:/(^[ \t]*)@.+/m,lookbehind:!0,inside:{atrule:/^@[\w-]+/,rest:r}},"variable-declaration":{pattern:/(^[ \t]*)[\w$-]+\s*.?=[ \t]*(?:\{[^{}]*\}|\S.*|$)/m,lookbehind:!0,inside:{variable:/^\S+/,rest:r}},statement:{pattern:/(^[ \t]*)(?:else|for|if|return|unless)[ \t].+/m,lookbehind:!0,inside:{keyword:/^\S+/,rest:r}},"property-declaration":{pattern:/((?:^|\{)([ \t]*))(?:[\w-]|\{[^}\r\n]+\})+(?:\s*:\s*|[ \t]+)(?!\s)[^{\r\n]*(?:;|[^{\r\n,]$(?!(?:\r?\n|\r)(?:\{|\2[ \t])))/m,lookbehind:!0,inside:{property:{pattern:/^[^\s:]+/,inside:{interpolation:r.interpolation}},rest:r}},selector:{pattern:/(^[ \t]*)(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)(?:(?:\r?\n|\r)(?:\1(?:(?=\S)(?:[^{}\r\n:()]|::?[\w-]+(?:\([^)\r\n]*\)|(?![\w-]))|\{[^}\r\n]+\})+)))*(?:,$|\{|(?=(?:\r?\n|\r)(?:\{|\1[ \t])))/m,lookbehind:!0,inside:{interpolation:r.interpolation,comment:r.comment,punctuation:/[{},]/}},func:r.func,string:r.string,comment:{pattern:/(^|[^\\])(?:\/\*[\s\S]*?\*\/|\/\/.*)/,lookbehind:!0,greedy:!0},interpolation:r.interpolation,punctuation:/[{}()\[\];:.]/}}(a),function(e){e.languages.typescript=e.languages.extend("javascript",{"class-name":{pattern:/(\b(?:class|extends|implements|instanceof|interface|new|type)\s+)(?!keyof\b)(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*(?:\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>)?/,lookbehind:!0,greedy:!0,inside:null},builtin:/\b(?:Array|Function|Promise|any|boolean|console|never|number|string|symbol|unknown)\b/}),e.languages.typescript.keyword.push(/\b(?:abstract|declare|is|keyof|readonly|require)\b/,/\b(?:asserts|infer|interface|module|namespace|type)\b(?=\s*(?:[{_$a-zA-Z\xA0-\uFFFF]|$))/,/\btype\b(?=\s*(?:[\{*]|$))/),delete e.languages.typescript.parameter,delete e.languages.typescript["literal-property"];var t=e.languages.extend("typescript",{});delete t["class-name"],e.languages.typescript["class-name"].inside=t,e.languages.insertBefore("typescript","function",{decorator:{pattern:/@[$\w\xA0-\uFFFF]+/,inside:{at:{pattern:/^@/,alias:"operator"},function:/^[\s\S]+/}},"generic-function":{pattern:/#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*\s*<(?:[^<>]|<(?:[^<>]|<[^<>]*>)*>)*>(?=\s*\()/,greedy:!0,inside:{function:/^#?(?!\s)[_$a-zA-Z\xA0-\uFFFF](?:(?!\s)[$\w\xA0-\uFFFF])*/,generic:{pattern:/<[\s\S]+/,alias:"class-name",inside:t}}}}),e.languages.ts=e.languages.typescript}(a),function(e){var t=e.util.clone(e.languages.typescript);e.languages.tsx=e.languages.extend("jsx",t),delete e.languages.tsx.parameter,delete e.languages.tsx["literal-property"];var n=e.languages.tsx.tag;n.pattern=RegExp(/(^|[^\w$]|(?=<\/))/.source+"(?:"+n.pattern.source+")",n.pattern.flags),n.lookbehind=!0}(a),a.languages.wasm={comment:[/\(;[\s\S]*?;\)/,{pattern:/;;.*/,greedy:!0}],string:{pattern:/"(?:\\[\s\S]|[^"\\])*"/,greedy:!0},keyword:[{pattern:/\b(?:align|offset)=/,inside:{operator:/=/}},{pattern:/\b(?:(?:f32|f64|i32|i64)(?:\.(?:abs|add|and|ceil|clz|const|convert_[su]\/i(?:32|64)|copysign|ctz|demote\/f64|div(?:_[su])?|eqz?|extend_[su]\/i32|floor|ge(?:_[su])?|gt(?:_[su])?|le(?:_[su])?|load(?:(?:8|16|32)_[su])?|lt(?:_[su])?|max|min|mul|neg?|nearest|or|popcnt|promote\/f32|reinterpret\/[fi](?:32|64)|rem_[su]|rot[lr]|shl|shr_[su]|sqrt|store(?:8|16|32)?|sub|trunc(?:_[su]\/f(?:32|64))?|wrap\/i64|xor))?|memory\.(?:grow|size))\b/,inside:{punctuation:/\./}},/\b(?:anyfunc|block|br(?:_if|_table)?|call(?:_indirect)?|data|drop|elem|else|end|export|func|get_(?:global|local)|global|if|import|local|loop|memory|module|mut|nop|offset|param|result|return|select|set_(?:global|local)|start|table|tee_local|then|type|unreachable)\b/],variable:/\$[\w!#$%&'*+\-./:<=>?@\\^`|~]+/,number:/[+-]?\b(?:\d(?:_?\d)*(?:\.\d(?:_?\d)*)?(?:[eE][+-]?\d(?:_?\d)*)?|0x[\da-fA-F](?:_?[\da-fA-F])*(?:\.[\da-fA-F](?:_?[\da-fA-D])*)?(?:[pP][+-]?\d(?:_?\d)*)?)\b|\binf\b|\bnan(?::0x[\da-fA-F](?:_?[\da-fA-D])*)?\b/,punctuation:/[()]/},function(e){var t=/[*&][^\s[\]{},]+/,n=/!(?:<[\w\-%#;/?:@&=+$,.!~*'()[\]]+>|(?:[a-zA-Z\d-]*!)?[\w\-%#;/?:@&=+$.~*'()]+)?/,r="(?:"+n.source+"(?:[ \t]+"+t.source+")?|"+t.source+"(?:[ \t]+"+n.source+")?)",a=/(?:[^\s\x00-\x08\x0e-\x1f!"#%&'*,\-:>?@[\]`{|}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]|[?:-])(?:[ \t]*(?:(?![#:])|:))*/.source.replace(//g,(function(){return/[^\s\x00-\x08\x0e-\x1f,[\]{}\x7f-\x84\x86-\x9f\ud800-\udfff\ufffe\uffff]/.source})),o=/"(?:[^"\\\r\n]|\\.)*"|'(?:[^'\\\r\n]|\\.)*'/.source;function i(e,t){t=(t||"").replace(/m/g,"")+"m";var n=/([:\-,[{]\s*(?:\s<>[ \t]+)?)(?:<>)(?=[ \t]*(?:$|,|\]|\}|(?:[\r\n]\s*)?#))/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return e}));return RegExp(n,t)}e.languages.yaml={scalar:{pattern:RegExp(/([\-:]\s*(?:\s<>[ \t]+)?[|>])[ \t]*(?:((?:\r?\n|\r)[ \t]+)\S[^\r\n]*(?:\2[^\r\n]+)*)/.source.replace(/<>/g,(function(){return r}))),lookbehind:!0,alias:"string"},comment:/#.*/,key:{pattern:RegExp(/((?:^|[:\-,[{\r\n?])[ \t]*(?:<>[ \t]+)?)<>(?=\s*:\s)/.source.replace(/<>/g,(function(){return r})).replace(/<>/g,(function(){return"(?:"+a+"|"+o+")"}))),lookbehind:!0,greedy:!0,alias:"atrule"},directive:{pattern:/(^[ \t]*)%.+/m,lookbehind:!0,alias:"important"},datetime:{pattern:i(/\d{4}-\d\d?-\d\d?(?:[tT]|[ \t]+)\d\d?:\d{2}:\d{2}(?:\.\d*)?(?:[ \t]*(?:Z|[-+]\d\d?(?::\d{2})?))?|\d{4}-\d{2}-\d{2}|\d\d?:\d{2}(?::\d{2}(?:\.\d*)?)?/.source),lookbehind:!0,alias:"number"},boolean:{pattern:i(/false|true/.source,"i"),lookbehind:!0,alias:"important"},null:{pattern:i(/null|~/.source,"i"),lookbehind:!0,alias:"important"},string:{pattern:i(o),lookbehind:!0,greedy:!0},number:{pattern:i(/[+-]?(?:0x[\da-f]+|0o[0-7]+|(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?|\.inf|\.nan)/.source,"i"),lookbehind:!0},tag:n,important:t,punctuation:/---|[:[\]{}\-,|>?]|\.\.\./},e.languages.yml=e.languages.yaml}(a),t.default=a},9901:function(e){e.exports&&(e.exports={core:{meta:{path:"components/prism-core.js",option:"mandatory"},core:"Core"},themes:{meta:{path:"themes/{id}.css",link:"index.html?theme={id}",exclusive:!0},prism:{title:"Default",option:"default"},"prism-dark":"Dark","prism-funky":"Funky","prism-okaidia":{title:"Okaidia",owner:"ocodia"},"prism-twilight":{title:"Twilight",owner:"remybach"},"prism-coy":{title:"Coy",owner:"tshedor"},"prism-solarizedlight":{title:"Solarized Light",owner:"hectormatos2011 "},"prism-tomorrow":{title:"Tomorrow Night",owner:"Rosey"}},languages:{meta:{path:"components/prism-{id}",noCSS:!0,examplesPath:"examples/prism-{id}",addCheckAll:!0},markup:{title:"Markup",alias:["html","xml","svg","mathml","ssml","atom","rss"],aliasTitles:{html:"HTML",xml:"XML",svg:"SVG",mathml:"MathML",ssml:"SSML",atom:"Atom",rss:"RSS"},option:"default"},css:{title:"CSS",option:"default",modify:"markup"},clike:{title:"C-like",option:"default"},javascript:{title:"JavaScript",require:"clike",modify:"markup",optional:"regex",alias:"js",option:"default"},abap:{title:"ABAP",owner:"dellagustin"},abnf:{title:"ABNF",owner:"RunDevelopment"},actionscript:{title:"ActionScript",require:"javascript",modify:"markup",owner:"Golmote"},ada:{title:"Ada",owner:"Lucretia"},agda:{title:"Agda",owner:"xy-ren"},al:{title:"AL",owner:"RunDevelopment"},antlr4:{title:"ANTLR4",alias:"g4",owner:"RunDevelopment"},apacheconf:{title:"Apache Configuration",owner:"GuiTeK"},apex:{title:"Apex",require:["clike","sql"],owner:"RunDevelopment"},apl:{title:"APL",owner:"ngn"},applescript:{title:"AppleScript",owner:"Golmote"},aql:{title:"AQL",owner:"RunDevelopment"},arduino:{title:"Arduino",require:"cpp",alias:"ino",owner:"dkern"},arff:{title:"ARFF",owner:"Golmote"},asciidoc:{alias:"adoc",title:"AsciiDoc",owner:"Golmote"},aspnet:{title:"ASP.NET (C#)",require:["markup","csharp"],owner:"nauzilus"},asm6502:{title:"6502 Assembly",owner:"kzurawel"},asmatmel:{title:"Atmel AVR Assembly",owner:"cerkit"},autohotkey:{title:"AutoHotkey",owner:"aviaryan"},autoit:{title:"AutoIt",owner:"Golmote"},avisynth:{title:"AviSynth",alias:"avs",owner:"Zinfidel"},"avro-idl":{title:"Avro IDL",alias:"avdl",owner:"RunDevelopment"},bash:{title:"Bash",alias:"shell",aliasTitles:{shell:"Shell"},owner:"zeitgeist87"},basic:{title:"BASIC",owner:"Golmote"},batch:{title:"Batch",owner:"Golmote"},bbcode:{title:"BBcode",alias:"shortcode",aliasTitles:{shortcode:"Shortcode"},owner:"RunDevelopment"},bicep:{title:"Bicep",owner:"johnnyreilly"},birb:{title:"Birb",require:"clike",owner:"Calamity210"},bison:{title:"Bison",require:"c",owner:"Golmote"},bnf:{title:"BNF",alias:"rbnf",aliasTitles:{rbnf:"RBNF"},owner:"RunDevelopment"},brainfuck:{title:"Brainfuck",owner:"Golmote"},brightscript:{title:"BrightScript",owner:"RunDevelopment"},bro:{title:"Bro",owner:"wayward710"},bsl:{title:"BSL (1C:Enterprise)",alias:"oscript",aliasTitles:{oscript:"OneScript"},owner:"Diversus23"},c:{title:"C",require:"clike",owner:"zeitgeist87"},csharp:{title:"C#",require:"clike",alias:["cs","dotnet"],owner:"mvalipour"},cpp:{title:"C++",require:"c",owner:"zeitgeist87"},cfscript:{title:"CFScript",require:"clike",alias:"cfc",owner:"mjclemente"},chaiscript:{title:"ChaiScript",require:["clike","cpp"],owner:"RunDevelopment"},cil:{title:"CIL",owner:"sbrl"},clojure:{title:"Clojure",owner:"troglotit"},cmake:{title:"CMake",owner:"mjrogozinski"},cobol:{title:"COBOL",owner:"RunDevelopment"},coffeescript:{title:"CoffeeScript",require:"javascript",alias:"coffee",owner:"R-osey"},concurnas:{title:"Concurnas",alias:"conc",owner:"jasontatton"},csp:{title:"Content-Security-Policy",owner:"ScottHelme"},coq:{title:"Coq",owner:"RunDevelopment"},crystal:{title:"Crystal",require:"ruby",owner:"MakeNowJust"},"css-extras":{title:"CSS Extras",require:"css",modify:"css",owner:"milesj"},csv:{title:"CSV",owner:"RunDevelopment"},cypher:{title:"Cypher",owner:"RunDevelopment"},d:{title:"D",require:"clike",owner:"Golmote"},dart:{title:"Dart",require:"clike",owner:"Golmote"},dataweave:{title:"DataWeave",owner:"machaval"},dax:{title:"DAX",owner:"peterbud"},dhall:{title:"Dhall",owner:"RunDevelopment"},diff:{title:"Diff",owner:"uranusjr"},django:{title:"Django/Jinja2",require:"markup-templating",alias:"jinja2",owner:"romanvm"},"dns-zone-file":{title:"DNS zone file",owner:"RunDevelopment",alias:"dns-zone"},docker:{title:"Docker",alias:"dockerfile",owner:"JustinBeckwith"},dot:{title:"DOT (Graphviz)",alias:"gv",optional:"markup",owner:"RunDevelopment"},ebnf:{title:"EBNF",owner:"RunDevelopment"},editorconfig:{title:"EditorConfig",owner:"osipxd"},eiffel:{title:"Eiffel",owner:"Conaclos"},ejs:{title:"EJS",require:["javascript","markup-templating"],owner:"RunDevelopment",alias:"eta",aliasTitles:{eta:"Eta"}},elixir:{title:"Elixir",owner:"Golmote"},elm:{title:"Elm",owner:"zwilias"},etlua:{title:"Embedded Lua templating",require:["lua","markup-templating"],owner:"RunDevelopment"},erb:{title:"ERB",require:["ruby","markup-templating"],owner:"Golmote"},erlang:{title:"Erlang",owner:"Golmote"},"excel-formula":{title:"Excel Formula",alias:["xlsx","xls"],owner:"RunDevelopment"},fsharp:{title:"F#",require:"clike",owner:"simonreynolds7"},factor:{title:"Factor",owner:"catb0t"},false:{title:"False",owner:"edukisto"},"firestore-security-rules":{title:"Firestore security rules",require:"clike",owner:"RunDevelopment"},flow:{title:"Flow",require:"javascript",owner:"Golmote"},fortran:{title:"Fortran",owner:"Golmote"},ftl:{title:"FreeMarker Template Language",require:"markup-templating",owner:"RunDevelopment"},gml:{title:"GameMaker Language",alias:"gamemakerlanguage",require:"clike",owner:"LiarOnce"},gap:{title:"GAP (CAS)",owner:"RunDevelopment"},gcode:{title:"G-code",owner:"RunDevelopment"},gdscript:{title:"GDScript",owner:"RunDevelopment"},gedcom:{title:"GEDCOM",owner:"Golmote"},gherkin:{title:"Gherkin",owner:"hason"},git:{title:"Git",owner:"lgiraudel"},glsl:{title:"GLSL",require:"c",owner:"Golmote"},gn:{title:"GN",alias:"gni",owner:"RunDevelopment"},go:{title:"Go",require:"clike",owner:"arnehormann"},"go-module":{title:"Go module",alias:"go-mod",owner:"RunDevelopment"},graphql:{title:"GraphQL",optional:"markdown",owner:"Golmote"},groovy:{title:"Groovy",require:"clike",owner:"robfletcher"},haml:{title:"Haml",require:"ruby",optional:["css","css-extras","coffeescript","erb","javascript","less","markdown","scss","textile"],owner:"Golmote"},handlebars:{title:"Handlebars",require:"markup-templating",alias:"hbs",owner:"Golmote"},haskell:{title:"Haskell",alias:"hs",owner:"bholst"},haxe:{title:"Haxe",require:"clike",optional:"regex",owner:"Golmote"},hcl:{title:"HCL",owner:"outsideris"},hlsl:{title:"HLSL",require:"c",owner:"RunDevelopment"},hoon:{title:"Hoon",owner:"matildepark"},http:{title:"HTTP",optional:["csp","css","hpkp","hsts","javascript","json","markup","uri"],owner:"danielgtaylor"},hpkp:{title:"HTTP Public-Key-Pins",owner:"ScottHelme"},hsts:{title:"HTTP Strict-Transport-Security",owner:"ScottHelme"},ichigojam:{title:"IchigoJam",owner:"BlueCocoa"},icon:{title:"Icon",owner:"Golmote"},"icu-message-format":{title:"ICU Message Format",owner:"RunDevelopment"},idris:{title:"Idris",alias:"idr",owner:"KeenS",require:"haskell"},ignore:{title:".ignore",owner:"osipxd",alias:["gitignore","hgignore","npmignore"],aliasTitles:{gitignore:".gitignore",hgignore:".hgignore",npmignore:".npmignore"}},inform7:{title:"Inform 7",owner:"Golmote"},ini:{title:"Ini",owner:"aviaryan"},io:{title:"Io",owner:"AlesTsurko"},j:{title:"J",owner:"Golmote"},java:{title:"Java",require:"clike",owner:"sherblot"},javadoc:{title:"JavaDoc",require:["markup","java","javadoclike"],modify:"java",optional:"scala",owner:"RunDevelopment"},javadoclike:{title:"JavaDoc-like",modify:["java","javascript","php"],owner:"RunDevelopment"},javastacktrace:{title:"Java stack trace",owner:"RunDevelopment"},jexl:{title:"Jexl",owner:"czosel"},jolie:{title:"Jolie",require:"clike",owner:"thesave"},jq:{title:"JQ",owner:"RunDevelopment"},jsdoc:{title:"JSDoc",require:["javascript","javadoclike","typescript"],modify:"javascript",optional:["actionscript","coffeescript"],owner:"RunDevelopment"},"js-extras":{title:"JS Extras",require:"javascript",modify:"javascript",optional:["actionscript","coffeescript","flow","n4js","typescript"],owner:"RunDevelopment"},json:{title:"JSON",alias:"webmanifest",aliasTitles:{webmanifest:"Web App Manifest"},owner:"CupOfTea696"},json5:{title:"JSON5",require:"json",owner:"RunDevelopment"},jsonp:{title:"JSONP",require:"json",owner:"RunDevelopment"},jsstacktrace:{title:"JS stack trace",owner:"sbrl"},"js-templates":{title:"JS Templates",require:"javascript",modify:"javascript",optional:["css","css-extras","graphql","markdown","markup","sql"],owner:"RunDevelopment"},julia:{title:"Julia",owner:"cdagnino"},keepalived:{title:"Keepalived Configure",owner:"dev-itsheng"},keyman:{title:"Keyman",owner:"mcdurdin"},kotlin:{title:"Kotlin",alias:["kt","kts"],aliasTitles:{kts:"Kotlin Script"},require:"clike",owner:"Golmote"},kumir:{title:"KuMir (\u041a\u0443\u041c\u0438\u0440)",alias:"kum",owner:"edukisto"},kusto:{title:"Kusto",owner:"RunDevelopment"},latex:{title:"LaTeX",alias:["tex","context"],aliasTitles:{tex:"TeX",context:"ConTeXt"},owner:"japborst"},latte:{title:"Latte",require:["clike","markup-templating","php"],owner:"nette"},less:{title:"Less",require:"css",optional:"css-extras",owner:"Golmote"},lilypond:{title:"LilyPond",require:"scheme",alias:"ly",owner:"RunDevelopment"},liquid:{title:"Liquid",require:"markup-templating",owner:"cinhtau"},lisp:{title:"Lisp",alias:["emacs","elisp","emacs-lisp"],owner:"JuanCaicedo"},livescript:{title:"LiveScript",owner:"Golmote"},llvm:{title:"LLVM IR",owner:"porglezomp"},log:{title:"Log file",optional:"javastacktrace",owner:"RunDevelopment"},lolcode:{title:"LOLCODE",owner:"Golmote"},lua:{title:"Lua",owner:"Golmote"},magma:{title:"Magma (CAS)",owner:"RunDevelopment"},makefile:{title:"Makefile",owner:"Golmote"},markdown:{title:"Markdown",require:"markup",optional:"yaml",alias:"md",owner:"Golmote"},"markup-templating":{title:"Markup templating",require:"markup",owner:"Golmote"},matlab:{title:"MATLAB",owner:"Golmote"},maxscript:{title:"MAXScript",owner:"RunDevelopment"},mel:{title:"MEL",owner:"Golmote"},mermaid:{title:"Mermaid",owner:"RunDevelopment"},mizar:{title:"Mizar",owner:"Golmote"},mongodb:{title:"MongoDB",owner:"airs0urce",require:"javascript"},monkey:{title:"Monkey",owner:"Golmote"},moonscript:{title:"MoonScript",alias:"moon",owner:"RunDevelopment"},n1ql:{title:"N1QL",owner:"TMWilds"},n4js:{title:"N4JS",require:"javascript",optional:"jsdoc",alias:"n4jsd",owner:"bsmith-n4"},"nand2tetris-hdl":{title:"Nand To Tetris HDL",owner:"stephanmax"},naniscript:{title:"Naninovel Script",owner:"Elringus",alias:"nani"},nasm:{title:"NASM",owner:"rbmj"},neon:{title:"NEON",owner:"nette"},nevod:{title:"Nevod",owner:"nezaboodka"},nginx:{title:"nginx",owner:"volado"},nim:{title:"Nim",owner:"Golmote"},nix:{title:"Nix",owner:"Golmote"},nsis:{title:"NSIS",owner:"idleberg"},objectivec:{title:"Objective-C",require:"c",alias:"objc",owner:"uranusjr"},ocaml:{title:"OCaml",owner:"Golmote"},opencl:{title:"OpenCL",require:"c",modify:["c","cpp"],owner:"Milania1"},openqasm:{title:"OpenQasm",alias:"qasm",owner:"RunDevelopment"},oz:{title:"Oz",owner:"Golmote"},parigp:{title:"PARI/GP",owner:"Golmote"},parser:{title:"Parser",require:"markup",owner:"Golmote"},pascal:{title:"Pascal",alias:"objectpascal",aliasTitles:{objectpascal:"Object Pascal"},owner:"Golmote"},pascaligo:{title:"Pascaligo",owner:"DefinitelyNotAGoat"},psl:{title:"PATROL Scripting Language",owner:"bertysentry"},pcaxis:{title:"PC-Axis",alias:"px",owner:"RunDevelopment"},peoplecode:{title:"PeopleCode",alias:"pcode",owner:"RunDevelopment"},perl:{title:"Perl",owner:"Golmote"},php:{title:"PHP",require:"markup-templating",owner:"milesj"},phpdoc:{title:"PHPDoc",require:["php","javadoclike"],modify:"php",owner:"RunDevelopment"},"php-extras":{title:"PHP Extras",require:"php",modify:"php",owner:"milesj"},plsql:{title:"PL/SQL",require:"sql",owner:"Golmote"},powerquery:{title:"PowerQuery",alias:["pq","mscript"],owner:"peterbud"},powershell:{title:"PowerShell",owner:"nauzilus"},processing:{title:"Processing",require:"clike",owner:"Golmote"},prolog:{title:"Prolog",owner:"Golmote"},promql:{title:"PromQL",owner:"arendjr"},properties:{title:".properties",owner:"Golmote"},protobuf:{title:"Protocol Buffers",require:"clike",owner:"just-boris"},pug:{title:"Pug",require:["markup","javascript"],optional:["coffeescript","ejs","handlebars","less","livescript","markdown","scss","stylus","twig"],owner:"Golmote"},puppet:{title:"Puppet",owner:"Golmote"},pure:{title:"Pure",optional:["c","cpp","fortran"],owner:"Golmote"},purebasic:{title:"PureBasic",require:"clike",alias:"pbfasm",owner:"HeX0R101"},purescript:{title:"PureScript",require:"haskell",alias:"purs",owner:"sriharshachilakapati"},python:{title:"Python",alias:"py",owner:"multipetros"},qsharp:{title:"Q#",require:"clike",alias:"qs",owner:"fedonman"},q:{title:"Q (kdb+ database)",owner:"Golmote"},qml:{title:"QML",require:"javascript",owner:"RunDevelopment"},qore:{title:"Qore",require:"clike",owner:"temnroegg"},r:{title:"R",owner:"Golmote"},racket:{title:"Racket",require:"scheme",alias:"rkt",owner:"RunDevelopment"},cshtml:{title:"Razor C#",alias:"razor",require:["markup","csharp"],optional:["css","css-extras","javascript","js-extras"],owner:"RunDevelopment"},jsx:{title:"React JSX",require:["markup","javascript"],optional:["jsdoc","js-extras","js-templates"],owner:"vkbansal"},tsx:{title:"React TSX",require:["jsx","typescript"]},reason:{title:"Reason",require:"clike",owner:"Golmote"},regex:{title:"Regex",owner:"RunDevelopment"},rego:{title:"Rego",owner:"JordanSh"},renpy:{title:"Ren'py",alias:"rpy",owner:"HyuchiaDiego"},rest:{title:"reST (reStructuredText)",owner:"Golmote"},rip:{title:"Rip",owner:"ravinggenius"},roboconf:{title:"Roboconf",owner:"Golmote"},robotframework:{title:"Robot Framework",alias:"robot",owner:"RunDevelopment"},ruby:{title:"Ruby",require:"clike",alias:"rb",owner:"samflores"},rust:{title:"Rust",owner:"Golmote"},sas:{title:"SAS",optional:["groovy","lua","sql"],owner:"Golmote"},sass:{title:"Sass (Sass)",require:"css",optional:"css-extras",owner:"Golmote"},scss:{title:"Sass (Scss)",require:"css",optional:"css-extras",owner:"MoOx"},scala:{title:"Scala",require:"java",owner:"jozic"},scheme:{title:"Scheme",owner:"bacchus123"},"shell-session":{title:"Shell session",require:"bash",alias:["sh-session","shellsession"],owner:"RunDevelopment"},smali:{title:"Smali",owner:"RunDevelopment"},smalltalk:{title:"Smalltalk",owner:"Golmote"},smarty:{title:"Smarty",require:"markup-templating",optional:"php",owner:"Golmote"},sml:{title:"SML",alias:"smlnj",aliasTitles:{smlnj:"SML/NJ"},owner:"RunDevelopment"},solidity:{title:"Solidity (Ethereum)",alias:"sol",require:"clike",owner:"glachaud"},"solution-file":{title:"Solution file",alias:"sln",owner:"RunDevelopment"},soy:{title:"Soy (Closure Template)",require:"markup-templating",owner:"Golmote"},sparql:{title:"SPARQL",require:"turtle",owner:"Triply-Dev",alias:"rq"},"splunk-spl":{title:"Splunk SPL",owner:"RunDevelopment"},sqf:{title:"SQF: Status Quo Function (Arma 3)",require:"clike",owner:"RunDevelopment"},sql:{title:"SQL",owner:"multipetros"},squirrel:{title:"Squirrel",require:"clike",owner:"RunDevelopment"},stan:{title:"Stan",owner:"RunDevelopment"},iecst:{title:"Structured Text (IEC 61131-3)",owner:"serhioromano"},stylus:{title:"Stylus",owner:"vkbansal"},swift:{title:"Swift",owner:"chrischares"},systemd:{title:"Systemd configuration file",owner:"RunDevelopment"},"t4-templating":{title:"T4 templating",owner:"RunDevelopment"},"t4-cs":{title:"T4 Text Templates (C#)",require:["t4-templating","csharp"],alias:"t4",owner:"RunDevelopment"},"t4-vb":{title:"T4 Text Templates (VB)",require:["t4-templating","vbnet"],owner:"RunDevelopment"},tap:{title:"TAP",owner:"isaacs",require:"yaml"},tcl:{title:"Tcl",owner:"PeterChaplin"},tt2:{title:"Template Toolkit 2",require:["clike","markup-templating"],owner:"gflohr"},textile:{title:"Textile",require:"markup",optional:"css",owner:"Golmote"},toml:{title:"TOML",owner:"RunDevelopment"},tremor:{title:"Tremor",alias:["trickle","troy"],owner:"darach",aliasTitles:{trickle:"trickle",troy:"troy"}},turtle:{title:"Turtle",alias:"trig",aliasTitles:{trig:"TriG"},owner:"jakubklimek"},twig:{title:"Twig",require:"markup-templating",owner:"brandonkelly"},typescript:{title:"TypeScript",require:"javascript",optional:"js-templates",alias:"ts",owner:"vkbansal"},typoscript:{title:"TypoScript",alias:"tsconfig",aliasTitles:{tsconfig:"TSConfig"},owner:"dkern"},unrealscript:{title:"UnrealScript",alias:["uscript","uc"],owner:"RunDevelopment"},uorazor:{title:"UO Razor Script",owner:"jaseowns"},uri:{title:"URI",alias:"url",aliasTitles:{url:"URL"},owner:"RunDevelopment"},v:{title:"V",require:"clike",owner:"taggon"},vala:{title:"Vala",require:"clike",optional:"regex",owner:"TemplarVolk"},vbnet:{title:"VB.Net",require:"basic",owner:"Bigsby"},velocity:{title:"Velocity",require:"markup",owner:"Golmote"},verilog:{title:"Verilog",owner:"a-rey"},vhdl:{title:"VHDL",owner:"a-rey"},vim:{title:"vim",owner:"westonganger"},"visual-basic":{title:"Visual Basic",alias:["vb","vba"],aliasTitles:{vba:"VBA"},owner:"Golmote"},warpscript:{title:"WarpScript",owner:"RunDevelopment"},wasm:{title:"WebAssembly",owner:"Golmote"},"web-idl":{title:"Web IDL",alias:"webidl",owner:"RunDevelopment"},wiki:{title:"Wiki markup",require:"markup",owner:"Golmote"},wolfram:{title:"Wolfram language",alias:["mathematica","nb","wl"],aliasTitles:{mathematica:"Mathematica",nb:"Mathematica Notebook"},owner:"msollami"},wren:{title:"Wren",owner:"clsource"},xeora:{title:"Xeora",require:"markup",alias:"xeoracube",aliasTitles:{xeoracube:"XeoraCube"},owner:"freakmaxi"},"xml-doc":{title:"XML doc (.net)",require:"markup",modify:["csharp","fsharp","vbnet"],owner:"RunDevelopment"},xojo:{title:"Xojo (REALbasic)",owner:"Golmote"},xquery:{title:"XQuery",require:"markup",owner:"Golmote"},yaml:{title:"YAML",alias:"yml",owner:"hason"},yang:{title:"YANG",owner:"RunDevelopment"},zig:{title:"Zig",owner:"RunDevelopment"}},plugins:{meta:{path:"plugins/{id}/prism-{id}",link:"plugins/{id}/"},"line-highlight":{title:"Line Highlight",description:"Highlights specific lines and/or line ranges."},"line-numbers":{title:"Line Numbers",description:"Line number at the beginning of code lines.",owner:"kuba-kubula"},"show-invisibles":{title:"Show Invisibles",description:"Show hidden characters such as tabs and line breaks.",optional:["autolinker","data-uri-highlight"]},autolinker:{title:"Autolinker",description:"Converts URLs and emails in code to clickable links. Parses Markdown links in comments."},wpd:{title:"WebPlatform Docs",description:'Makes tokens link to WebPlatform.org documentation. The links open in a new tab.'},"custom-class":{title:"Custom Class",description:"This plugin allows you to prefix Prism's default classes (.comment can become .namespace--comment) or replace them with your defined ones (like .editor__comment). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll and highlightAllUnder methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:function(e,t,n){const r=n(9901),a=n(9642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(6500).resolve(t)],delete Prism.languages[e],n(6500)(t),o.add(e)}))}i.silent=!1,e.exports=i},6726:function(e,t,n){var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6726},6500:function(e,t,n){var r={"./":2885};function a(e){var t=o(e);return n(t)}function o(e){if(!n.o(r,e)){var t=new Error("Cannot find module '"+e+"'");throw t.code="MODULE_NOT_FOUND",t}return r[e]}a.keys=function(){return Object.keys(r)},a.resolve=o,e.exports=a,a.id=6500},9642:function(e){"use strict";var t=function(){var e=function(){};function t(e,t){Array.isArray(e)?e.forEach(t):null!=e&&t(e,0)}function n(e){for(var t={},n=0,r=e.length;n "));var l={},s=e[r];if(s){function u(t){if(!(t in e))throw new Error(r+" depends on an unknown component "+t);if(!(t in l))for(var i in a(t,o),l[t]=!0,n[t])l[i]=!0}t(s.require,u),t(s.optional,u),t(s.modify,u)}n[r]=l,o.pop()}}return function(e){var t=n[e];return t||(a(e,r),t=n[e]),t}}function a(e){for(var t in e)return!0;return!1}return function(o,i,l){var s=function(e){var t={};for(var n in e){var r=e[n];for(var a in r)if("meta"!=a){var o=r[a];t[a]="string"==typeof o?{title:o}:o}}return t}(o),u=function(e){var n;return function(r){if(r in e)return r;if(!n)for(var a in n={},e){var o=e[a];t(o&&o.alias,(function(t){if(t in n)throw new Error(t+" cannot be alias for both "+a+" and "+n[t]);if(t in e)throw new Error(t+" cannot be alias of "+a+" because it is a component.");n[t]=a}))}return n[r]||r}}(s);i=i.map(u),l=(l||[]).map(u);var c=n(i),d=n(l);i.forEach((function e(n){var r=s[n];t(r&&r.require,(function(t){t in d||(c[t]=!0,e(t))}))}));for(var f,p=r(s),m=c;a(m);){for(var g in f={},m){var h=s[g];t(h&&h.modify,(function(e){e in d&&(f[e]=!0)}))}for(var b in d)if(!(b in c))for(var v in p(b))if(v in c){f[b]=!0;break}for(var y in m=f)c[y]=!0}var k={getIds:function(){var e=[];return k.load((function(t){e.push(t)})),e},load:function(t,n){return function(t,n,r,a){var o=a?a.series:void 0,i=a?a.parallel:e,l={},s={};function u(e){if(e in l)return l[e];s[e]=!0;var a,c=[];for(var d in t(e))d in n&&c.push(d);if(0===c.length)a=r(e);else{var f=i(c.map((function(e){var t=u(e);return delete s[e],t})));o?a=o(f,(function(){return r(e)})):r(e)}return l[e]=a}for(var c in n)u(c);var d=[];for(var f in s)d.push(l[f]);return i(d)}(p,c,t,n)}};return k}}();e.exports=t},2703:function(e,t,n){"use strict";var r=n(414);function a(){}function o(){}o.resetWarningCache=a,e.exports=function(){function e(e,t,n,a,o,i){if(i!==r){var l=new Error("Calling PropTypes validators directly is not supported by the `prop-types` package. Use PropTypes.checkPropTypes() to call them. Read more at http://fb.me/use-check-prop-types");throw l.name="Invariant Violation",l}}function t(){return e}e.isRequired=e;var n={array:e,bigint:e,bool:e,func:e,number:e,object:e,string:e,symbol:e,any:e,arrayOf:t,element:e,elementType:e,instanceOf:t,node:e,objectOf:t,oneOf:t,oneOfType:t,shape:t,exact:t,checkPropTypes:o,resetWarningCache:a};return n.PropTypes=n,n}},5697:function(e,t,n){e.exports=n(2703)()},414:function(e){"use strict";e.exports="SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED"},4448:function(e,t,n){"use strict";var r=n(7294),a=n(7418),o=n(3840);function i(e){for(var t="https://reactjs.org/docs/error-decoder.html?invariant="+e,n=1;n